autosnippet 3.0.1 → 3.0.2

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 (290) hide show
  1. package/README.md +230 -324
  2. package/bin/api-server.js +1 -1
  3. package/bin/cli.js +204 -244
  4. package/bin/mcp-server.js +5 -3
  5. package/config/knowledge-base.config.js +132 -132
  6. package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
  7. package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
  8. package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
  9. package/dashboard/dist/index.html +3 -3
  10. package/lib/bootstrap.js +8 -8
  11. package/lib/cli/AiScanService.js +86 -40
  12. package/lib/cli/KnowledgeSyncService.js +113 -74
  13. package/lib/cli/SetupService.js +439 -277
  14. package/lib/cli/UpgradeService.js +63 -100
  15. package/lib/core/AstAnalyzer.js +276 -597
  16. package/lib/core/ast/ProjectGraph.js +101 -40
  17. package/lib/core/ast/ensure-grammars.js +232 -0
  18. package/lib/core/ast/index.js +115 -0
  19. package/lib/core/ast/lang-dart.js +661 -0
  20. package/lib/core/ast/lang-go.js +530 -0
  21. package/lib/core/ast/lang-java.js +435 -0
  22. package/lib/core/ast/lang-javascript.js +272 -0
  23. package/lib/core/ast/lang-kotlin.js +423 -0
  24. package/lib/core/ast/lang-objc.js +388 -0
  25. package/lib/core/ast/lang-python.js +371 -0
  26. package/lib/core/ast/lang-swift.js +337 -0
  27. package/lib/core/ast/lang-typescript.js +503 -0
  28. package/lib/core/capability/CapabilityProbe.js +18 -9
  29. package/lib/core/constitution/Constitution.js +2 -3
  30. package/lib/core/constitution/ConstitutionValidator.js +65 -24
  31. package/lib/core/discovery/DartDiscoverer.js +534 -0
  32. package/lib/core/discovery/DiscovererRegistry.js +83 -0
  33. package/lib/core/discovery/GenericDiscoverer.js +225 -0
  34. package/lib/core/discovery/GoDiscoverer.js +541 -0
  35. package/lib/core/discovery/JvmDiscoverer.js +506 -0
  36. package/lib/core/discovery/NodeDiscoverer.js +466 -0
  37. package/lib/core/discovery/ProjectDiscoverer.js +93 -0
  38. package/lib/core/discovery/PythonDiscoverer.js +338 -0
  39. package/lib/core/discovery/SpmDiscoverer.js +5 -0
  40. package/lib/core/discovery/index.js +53 -0
  41. package/lib/core/enhancement/EnhancementPack.js +71 -0
  42. package/lib/core/enhancement/EnhancementRegistry.js +47 -0
  43. package/lib/core/enhancement/android-enhancement.js +102 -0
  44. package/lib/core/enhancement/django-enhancement.js +70 -0
  45. package/lib/core/enhancement/fastapi-enhancement.js +63 -0
  46. package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
  47. package/lib/core/enhancement/go-web-enhancement.js +201 -0
  48. package/lib/core/enhancement/index.js +65 -0
  49. package/lib/core/enhancement/node-server-enhancement.js +88 -0
  50. package/lib/core/enhancement/react-enhancement.js +86 -0
  51. package/lib/core/enhancement/spring-enhancement.js +112 -0
  52. package/lib/core/enhancement/vue-enhancement.js +96 -0
  53. package/lib/core/gateway/Gateway.js +8 -9
  54. package/lib/core/gateway/GatewayActionRegistry.js +1 -1
  55. package/lib/core/permission/PermissionManager.js +12 -8
  56. package/lib/domain/index.js +13 -9
  57. package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
  58. package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
  59. package/lib/domain/knowledge/Lifecycle.js +22 -22
  60. package/lib/domain/knowledge/index.js +9 -12
  61. package/lib/domain/knowledge/values/Constraints.js +31 -21
  62. package/lib/domain/knowledge/values/Content.js +21 -13
  63. package/lib/domain/knowledge/values/Quality.js +31 -18
  64. package/lib/domain/knowledge/values/Reasoning.js +20 -12
  65. package/lib/domain/knowledge/values/Relations.js +37 -25
  66. package/lib/domain/knowledge/values/Stats.js +18 -12
  67. package/lib/domain/knowledge/values/index.js +4 -3
  68. package/lib/domain/snippet/Snippet.js +35 -10
  69. package/lib/external/ai/AiFactory.js +48 -16
  70. package/lib/external/ai/AiProvider.js +184 -90
  71. package/lib/external/ai/providers/ClaudeProvider.js +25 -12
  72. package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
  73. package/lib/external/ai/providers/MockProvider.js +9 -3
  74. package/lib/external/ai/providers/OpenAiProvider.js +51 -29
  75. package/lib/external/mcp/McpServer.js +66 -36
  76. package/lib/external/mcp/errorHandler.js +23 -11
  77. package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
  78. package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
  79. package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
  80. package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
  81. package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
  82. package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
  83. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
  84. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
  85. package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
  86. package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
  87. package/lib/external/mcp/handlers/bootstrap.js +691 -168
  88. package/lib/external/mcp/handlers/browse.js +66 -22
  89. package/lib/external/mcp/handlers/candidate.js +118 -35
  90. package/lib/external/mcp/handlers/consolidated.js +49 -17
  91. package/lib/external/mcp/handlers/guard.js +104 -39
  92. package/lib/external/mcp/handlers/knowledge.js +60 -36
  93. package/lib/external/mcp/handlers/search.js +43 -14
  94. package/lib/external/mcp/handlers/skill.js +120 -45
  95. package/lib/external/mcp/handlers/structure.js +240 -86
  96. package/lib/external/mcp/handlers/system.js +42 -12
  97. package/lib/external/mcp/handlers/wiki.js +58 -33
  98. package/lib/external/mcp/tools.js +306 -123
  99. package/lib/http/HttpServer.js +72 -47
  100. package/lib/http/middleware/RateLimiter.js +5 -3
  101. package/lib/http/middleware/errorHandler.js +6 -1
  102. package/lib/http/middleware/requestLogger.js +14 -3
  103. package/lib/http/middleware/roleResolver.js +30 -23
  104. package/lib/http/routes/ai.js +387 -265
  105. package/lib/http/routes/auth.js +81 -61
  106. package/lib/http/routes/candidates.js +430 -320
  107. package/lib/http/routes/commands.js +289 -189
  108. package/lib/http/routes/extract.js +158 -125
  109. package/lib/http/routes/guardRules.js +309 -217
  110. package/lib/http/routes/knowledge.js +213 -154
  111. package/lib/http/routes/modules.js +578 -0
  112. package/lib/http/routes/monitoring.js +6 -6
  113. package/lib/http/routes/recipes.js +104 -93
  114. package/lib/http/routes/search.js +361 -305
  115. package/lib/http/routes/skills.js +145 -98
  116. package/lib/http/routes/snippets.js +42 -30
  117. package/lib/http/routes/spm.js +3 -405
  118. package/lib/http/routes/violations.js +113 -93
  119. package/lib/http/routes/wiki.js +211 -170
  120. package/lib/http/utils/routeHelpers.js +3 -1
  121. package/lib/http/utils/sse-sessions.js +16 -6
  122. package/lib/http/utils/sse.js +15 -5
  123. package/lib/infrastructure/audit/AuditLogger.js +5 -2
  124. package/lib/infrastructure/audit/AuditStore.js +10 -7
  125. package/lib/infrastructure/cache/CacheService.js +3 -1
  126. package/lib/infrastructure/cache/GraphCache.js +8 -4
  127. package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
  128. package/lib/infrastructure/config/ConfigLoader.js +9 -5
  129. package/lib/infrastructure/config/Defaults.js +30 -10
  130. package/lib/infrastructure/config/Paths.js +28 -8
  131. package/lib/infrastructure/config/TriggerSymbol.js +22 -10
  132. package/lib/infrastructure/database/DatabaseConnection.js +15 -10
  133. package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
  134. package/lib/infrastructure/external/ClipboardManager.js +6 -2
  135. package/lib/infrastructure/external/NativeUi.js +50 -43
  136. package/lib/infrastructure/external/OpenBrowser.js +14 -17
  137. package/lib/infrastructure/external/XcodeAutomation.js +14 -258
  138. package/lib/infrastructure/logging/Logger.js +46 -30
  139. package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
  140. package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
  141. package/lib/infrastructure/paths/HeaderResolver.js +25 -9
  142. package/lib/infrastructure/paths/PathFinder.js +34 -12
  143. package/lib/infrastructure/plugin/PluginManager.js +26 -8
  144. package/lib/infrastructure/realtime/RealtimeService.js +2 -2
  145. package/lib/infrastructure/vector/Chunker.js +22 -7
  146. package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
  147. package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
  148. package/lib/infrastructure/vector/VectorStore.js +28 -10
  149. package/lib/injection/ServiceContainer.js +247 -93
  150. package/lib/platform/ios/index.js +63 -0
  151. package/lib/platform/ios/routes/spm.js +437 -0
  152. package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
  153. package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
  154. package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
  155. package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
  156. package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
  157. package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
  158. package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
  159. package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
  160. package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
  161. package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
  162. package/lib/repository/base/BaseRepository.js +7 -9
  163. package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
  164. package/lib/repository/token/TokenUsageStore.js +4 -2
  165. package/lib/service/automation/ActionPipeline.js +1 -1
  166. package/lib/service/automation/AutomationOrchestrator.js +8 -4
  167. package/lib/service/automation/ContextCollector.js +7 -5
  168. package/lib/service/automation/DirectiveDetector.js +23 -16
  169. package/lib/service/automation/FileWatcher.js +112 -56
  170. package/lib/service/automation/TriggerResolver.js +6 -4
  171. package/lib/service/automation/handlers/AlinkHandler.js +24 -12
  172. package/lib/service/automation/handlers/CreateHandler.js +19 -20
  173. package/lib/service/automation/handlers/DraftHandler.js +14 -8
  174. package/lib/service/automation/handlers/GuardHandler.js +93 -63
  175. package/lib/service/automation/handlers/HeaderHandler.js +1 -6
  176. package/lib/service/automation/handlers/SearchHandler.js +155 -88
  177. package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
  178. package/lib/service/candidate/SimilarityService.js +25 -9
  179. package/lib/service/chat/AnalystAgent.js +50 -24
  180. package/lib/service/chat/CandidateGuardrail.js +143 -17
  181. package/lib/service/chat/ChatAgent.js +655 -260
  182. package/lib/service/chat/ContextWindow.js +116 -71
  183. package/lib/service/chat/ConversationStore.js +77 -36
  184. package/lib/service/chat/EpisodicConsolidator.js +47 -23
  185. package/lib/service/chat/HandoffProtocol.js +98 -22
  186. package/lib/service/chat/Memory.js +34 -14
  187. package/lib/service/chat/ProducerAgent.js +40 -20
  188. package/lib/service/chat/ProjectSemanticMemory.js +109 -78
  189. package/lib/service/chat/ReasoningLayer.js +148 -70
  190. package/lib/service/chat/ReasoningTrace.js +44 -32
  191. package/lib/service/chat/TaskPipeline.js +39 -19
  192. package/lib/service/chat/ToolRegistry.js +48 -29
  193. package/lib/service/chat/WorkingMemory.js +44 -18
  194. package/lib/service/chat/tools.js +1096 -494
  195. package/lib/service/context/RecipeExtractor.js +132 -51
  196. package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
  197. package/lib/service/cursor/KnowledgeCompressor.js +25 -22
  198. package/lib/service/cursor/RulesGenerator.js +13 -7
  199. package/lib/service/cursor/SkillsSyncer.js +77 -27
  200. package/lib/service/cursor/TokenBudget.js +2 -2
  201. package/lib/service/cursor/TopicClassifier.js +54 -20
  202. package/lib/service/guard/ComplianceReporter.js +55 -43
  203. package/lib/service/guard/ExclusionManager.js +67 -29
  204. package/lib/service/guard/GuardCheckEngine.js +381 -86
  205. package/lib/service/guard/GuardFeedbackLoop.js +22 -10
  206. package/lib/service/guard/GuardService.js +29 -19
  207. package/lib/service/guard/RuleLearner.js +55 -23
  208. package/lib/service/guard/SourceFileCollector.js +27 -20
  209. package/lib/service/guard/ViolationsStore.js +43 -38
  210. package/lib/service/knowledge/CodeEntityGraph.js +147 -82
  211. package/lib/service/knowledge/ConfidenceRouter.js +12 -10
  212. package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
  213. package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
  214. package/lib/service/knowledge/KnowledgeService.js +222 -112
  215. package/lib/service/module/ModuleService.js +969 -0
  216. package/lib/service/quality/FeedbackCollector.js +27 -15
  217. package/lib/service/quality/QualityScorer.js +78 -24
  218. package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
  219. package/lib/service/recipe/RecipeParser.js +78 -45
  220. package/lib/service/search/CoarseRanker.js +43 -28
  221. package/lib/service/search/CrossEncoderReranker.js +32 -21
  222. package/lib/service/search/InvertedIndex.js +21 -7
  223. package/lib/service/search/MultiSignalRanker.js +90 -28
  224. package/lib/service/search/RetrievalFunnel.js +45 -24
  225. package/lib/service/search/SearchEngine.js +255 -103
  226. package/lib/service/skills/EventAggregator.js +32 -15
  227. package/lib/service/skills/SignalCollector.js +140 -64
  228. package/lib/service/skills/SkillAdvisor.js +79 -42
  229. package/lib/service/skills/SkillHooks.js +16 -14
  230. package/lib/service/snippet/PlaceholderConverter.js +5 -0
  231. package/lib/service/snippet/SnippetFactory.js +116 -99
  232. package/lib/service/snippet/SnippetInstaller.js +234 -62
  233. package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
  234. package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
  235. package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
  236. package/lib/service/wiki/WikiGenerator.js +637 -263
  237. package/lib/shared/DimensionCopyRegistry.js +472 -0
  238. package/lib/shared/LanguageService.js +399 -0
  239. package/lib/shared/PathGuard.js +45 -28
  240. package/lib/shared/RecipeReadinessChecker.js +72 -12
  241. package/lib/shared/constants.js +41 -41
  242. package/lib/shared/errors/BaseError.js +2 -2
  243. package/lib/shared/errors/index.js +4 -4
  244. package/lib/shared/similarity.js +25 -8
  245. package/lib/shared/token-utils.js +6 -2
  246. package/lib/shared/utils/common.js +12 -4
  247. package/package.json +49 -13
  248. package/scripts/bench-real-projects.mjs +256 -0
  249. package/scripts/build-native-ui.js +30 -30
  250. package/scripts/clear-old-vector-index.js +5 -35
  251. package/scripts/clear-vector-cache.js +7 -37
  252. package/scripts/collect-test-project-stats.mjs +160 -0
  253. package/scripts/diagnose-mcp.js +41 -32
  254. package/scripts/ensure-parse-package.js +6 -9
  255. package/scripts/generate-recipe-drafts.js +116 -77
  256. package/scripts/init-db.js +3 -20
  257. package/scripts/init-snippets.js +305 -0
  258. package/scripts/init-vector-db.js +173 -170
  259. package/scripts/install-cursor-skill.js +148 -104
  260. package/scripts/install-full.js +8 -21
  261. package/scripts/install-vscode-copilot.js +146 -145
  262. package/scripts/migrate-md-to-knowledge.mjs +139 -151
  263. package/scripts/postinstall-safe.js +5 -17
  264. package/scripts/recipe-audit.js +106 -82
  265. package/scripts/release.js +283 -323
  266. package/scripts/setup-mcp-config.js +60 -52
  267. package/scripts/verify-context-api.js +20 -20
  268. package/skills/autosnippet-analysis/SKILL.md +10 -6
  269. package/skills/autosnippet-candidates/SKILL.md +27 -26
  270. package/skills/autosnippet-coldstart/SKILL.md +555 -38
  271. package/skills/autosnippet-concepts/SKILL.md +349 -337
  272. package/skills/autosnippet-create/SKILL.md +5 -5
  273. package/skills/autosnippet-reference-dart/SKILL.md +543 -0
  274. package/skills/autosnippet-reference-go/SKILL.md +539 -0
  275. package/skills/autosnippet-reference-java/SKILL.md +534 -0
  276. package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
  277. package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
  278. package/skills/autosnippet-reference-objc/SKILL.md +29 -6
  279. package/skills/autosnippet-reference-python/SKILL.md +800 -0
  280. package/skills/autosnippet-reference-swift/SKILL.md +70 -14
  281. package/skills/autosnippet-structure/SKILL.md +4 -4
  282. package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
  283. package/templates/recipes-setup/README.md +2 -2
  284. package/templates/recipes-setup/_template.md +1 -1
  285. package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
  286. package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
  287. package/resources/asd-entry/main.swift +0 -159
  288. package/scripts/build-asd-entry.js +0 -51
  289. package/scripts/init-xcode-snippets.js +0 -311
  290. package/template.json +0 -39
@@ -9,12 +9,20 @@ import { envelope } from '../envelope.js';
9
9
  function _projectItem(r) {
10
10
  const json = typeof r.toJSON === 'function' ? r.toJSON() : r;
11
11
  return {
12
- id: json.id, title: json.title, description: json.description,
13
- trigger: json.trigger || '', lifecycle: json.lifecycle, kind: json.kind,
14
- language: json.language, category: json.category,
15
- knowledgeType: json.knowledgeType, complexity: json.complexity,
16
- scope: json.scope, tags: json.tags || [],
17
- quality: json.quality || null, stats: json.stats || null,
12
+ id: json.id,
13
+ title: json.title,
14
+ description: json.description,
15
+ trigger: json.trigger || '',
16
+ lifecycle: json.lifecycle,
17
+ kind: json.kind,
18
+ language: json.language,
19
+ category: json.category,
20
+ knowledgeType: json.knowledgeType,
21
+ complexity: json.complexity,
22
+ scope: json.scope,
23
+ tags: json.tags || [],
24
+ quality: json.quality || null,
25
+ stats: json.stats || null,
18
26
  status: json.lifecycle,
19
27
  statistics: json.stats,
20
28
  };
@@ -23,41 +31,73 @@ function _projectItem(r) {
23
31
  export async function listByKind(ctx, kind, args) {
24
32
  const ks = ctx.container.get('knowledgeService');
25
33
  const filters = { kind };
26
- if (args.language) filters.language = args.language;
27
- if (args.category) filters.category = args.category;
34
+ if (args.language) {
35
+ filters.language = args.language;
36
+ }
37
+ if (args.category) {
38
+ filters.category = args.category;
39
+ }
28
40
  const result = await ks.list(filters, { page: 1, pageSize: args.limit || 20 });
29
41
  const items = (result?.data || []).map(_projectItem);
30
- return envelope({ success: true, data: { kind, count: items.length, total: result?.pagination?.total || items.length, items }, meta: { tool: `autosnippet_list_${kind}s` } });
42
+ return envelope({
43
+ success: true,
44
+ data: { kind, count: items.length, total: result?.pagination?.total || items.length, items },
45
+ meta: { tool: `autosnippet_list_${kind}s` },
46
+ });
31
47
  }
32
48
 
33
49
  export async function listRecipes(ctx, args) {
34
50
  const ks = ctx.container.get('knowledgeService');
35
51
  const filters = {};
36
- if (args.kind) filters.kind = args.kind;
37
- if (args.language) filters.language = args.language;
38
- if (args.category) filters.category = args.category;
39
- if (args.knowledgeType) filters.knowledgeType = args.knowledgeType;
40
- if (args.complexity) filters.complexity = args.complexity;
41
- if (args.status) filters.lifecycle = args.status;
52
+ if (args.kind) {
53
+ filters.kind = args.kind;
54
+ }
55
+ if (args.language) {
56
+ filters.language = args.language;
57
+ }
58
+ if (args.category) {
59
+ filters.category = args.category;
60
+ }
61
+ if (args.knowledgeType) {
62
+ filters.knowledgeType = args.knowledgeType;
63
+ }
64
+ if (args.complexity) {
65
+ filters.complexity = args.complexity;
66
+ }
67
+ if (args.status) {
68
+ filters.lifecycle = args.status;
69
+ }
42
70
  const result = await ks.list(filters, { page: 1, pageSize: args.limit || 20 });
43
71
  const items = (result?.data || []).map(_projectItem);
44
- return envelope({ success: true, data: { count: items.length, total: result?.pagination?.total || items.length, items }, meta: { tool: 'autosnippet_list_recipes' } });
72
+ return envelope({
73
+ success: true,
74
+ data: { count: items.length, total: result?.pagination?.total || items.length, items },
75
+ meta: { tool: 'autosnippet_list_recipes' },
76
+ });
45
77
  }
46
78
 
47
79
  export async function getRecipe(ctx, args) {
48
- if (!args.id) throw new Error('id is required');
80
+ if (!args.id) {
81
+ throw new Error('id is required');
82
+ }
49
83
  const ks = ctx.container.get('knowledgeService');
50
84
  const entry = await ks.get(args.id);
51
- if (!entry) throw new Error(`Knowledge entry not found: ${args.id}`);
85
+ if (!entry) {
86
+ throw new Error(`Knowledge entry not found: ${args.id}`);
87
+ }
52
88
  const json = typeof entry.toJSON === 'function' ? entry.toJSON() : entry;
53
89
  return envelope({ success: true, data: json, meta: { tool: 'autosnippet_get_recipe' } });
54
90
  }
55
91
 
56
92
  export async function recipeInsights(ctx, args) {
57
- if (!args.id) throw new Error('id is required');
93
+ if (!args.id) {
94
+ throw new Error('id is required');
95
+ }
58
96
  const ks = ctx.container.get('knowledgeService');
59
97
  const entry = await ks.get(args.id);
60
- if (!entry) throw new Error(`Knowledge entry not found: ${args.id}`);
98
+ if (!entry) {
99
+ throw new Error(`Knowledge entry not found: ${args.id}`);
100
+ }
61
101
  const json = typeof entry.toJSON === 'function' ? entry.toJSON() : entry;
62
102
 
63
103
  // 聚合关系摘要
@@ -123,7 +163,9 @@ export async function recipeInsights(ctx, args) {
123
163
  }
124
164
 
125
165
  export async function confirmUsage(ctx, args) {
126
- if (!args.recipeId) throw new Error('recipeId is required');
166
+ if (!args.recipeId) {
167
+ throw new Error('recipeId is required');
168
+ }
127
169
  const ks = ctx.container.get('knowledgeService');
128
170
  const usageType = args.usageType || 'adoption';
129
171
  const feedback = args.feedback || null;
@@ -143,7 +185,9 @@ export async function confirmUsage(ctx, args) {
143
185
  comment: feedback,
144
186
  });
145
187
  }
146
- } catch { /* feedbackCollector 降级不影响主流程 */ }
188
+ } catch {
189
+ /* feedbackCollector 降级不影响主流程 */
190
+ }
147
191
  }
148
192
 
149
193
  return envelope({
@@ -17,42 +17,85 @@ export async function validateCandidate(ctx, args) {
17
17
  const suggestions = [];
18
18
 
19
19
  // Layer 1: 核心必填
20
- if (!c.title?.trim()) errors.push('缺少 title');
21
- if (!c.code?.trim() && args.strict) errors.push('strict 模式下需要 code');
22
- if (!c.language) warnings.push('缺少 language');
20
+ if (!c.title?.trim()) {
21
+ errors.push('缺少 title');
22
+ }
23
+ if (!c.code?.trim() && args.strict) {
24
+ errors.push('strict 模式下需要 code');
25
+ }
26
+ if (!c.language) {
27
+ warnings.push('缺少 language');
28
+ }
23
29
 
24
30
  // Layer 2: 分类
25
- if (!c.category) warnings.push('缺少 category');
26
- if (!c.knowledgeType) warnings.push('缺少 knowledgeType(code-pattern/architecture/best-practice/...)');
27
- if (!c.complexity) suggestions.push({ field: 'complexity', value: 'intermediate' });
31
+ if (!c.category) {
32
+ warnings.push('缺少 category');
33
+ }
34
+ if (!c.knowledgeType) {
35
+ warnings.push('缺少 knowledgeType(code-pattern/architecture/best-practice/...)');
36
+ }
37
+ if (!c.complexity) {
38
+ suggestions.push({ field: 'complexity', value: 'intermediate' });
39
+ }
28
40
 
29
41
  // Layer 3: 描述文档
30
- if (!c.trigger?.trim()) warnings.push('缺少 trigger(建议 @ 开头)');
42
+ if (!c.trigger?.trim()) {
43
+ warnings.push('缺少 trigger(建议 @ 开头)');
44
+ }
31
45
  if (c.trigger && !c.trigger.startsWith('@')) {
32
46
  suggestions.push({ field: 'trigger', value: `@${c.trigger.replace(/^@+/, '')}` });
33
47
  }
34
- if (!c.summary?.trim() && !c.description?.trim()) warnings.push('缺少 summary 或 description');
35
- if (!c.usageGuide?.trim()) warnings.push('缺少 usageGuide');
48
+ if (!c.summary?.trim() && !c.description?.trim()) {
49
+ warnings.push('缺少 summary 或 description');
50
+ }
51
+ if (!c.usageGuide?.trim()) {
52
+ warnings.push('缺少 usageGuide');
53
+ }
36
54
 
37
55
  // Layer 4: 结构化内容
38
- if (!c.rationale) warnings.push('缺少 rationale(设计原理)');
39
- if (!Array.isArray(c.headers) || c.headers.length === 0) warnings.push('缺少 headers(import 声明)');
40
- if (!c.steps && !c.codeChanges) suggestions.push({ field: 'steps', value: '[{title, description, code}]' });
56
+ if (!c.rationale) {
57
+ warnings.push('缺少 rationale(设计原理)');
58
+ }
59
+ if (!Array.isArray(c.headers) || c.headers.length === 0) {
60
+ warnings.push('缺少 headers(import 声明)');
61
+ }
62
+ if (!c.steps && !c.codeChanges) {
63
+ suggestions.push({ field: 'steps', value: '[{title, description, code}]' });
64
+ }
41
65
 
42
66
  // Layer 5: 约束与关系
43
- if (!c.constraints) suggestions.push({ field: 'constraints', value: '{boundaries[], preconditions[], sideEffects[], guards[]}' });
67
+ if (!c.constraints) {
68
+ suggestions.push({
69
+ field: 'constraints',
70
+ value: '{boundaries[], preconditions[], sideEffects[], guards[]}',
71
+ });
72
+ }
44
73
 
45
74
  // Reasoning 推理依据
46
75
  if (!c.reasoning) {
47
76
  errors.push('缺少 reasoning(推理依据 — whyStandard + sources + confidence)');
48
77
  } else {
49
- if (!c.reasoning.whyStandard?.trim()) errors.push('reasoning.whyStandard 不能为空');
50
- if (!Array.isArray(c.reasoning.sources) || c.reasoning.sources.length === 0) errors.push('reasoning.sources 至少包含一项来源');
51
- if (typeof c.reasoning.confidence !== 'number' || c.reasoning.confidence < 0 || c.reasoning.confidence > 1) warnings.push('reasoning.confidence 应为 0-1 的数字');
78
+ if (!c.reasoning.whyStandard?.trim()) {
79
+ errors.push('reasoning.whyStandard 不能为空');
80
+ }
81
+ if (!Array.isArray(c.reasoning.sources) || c.reasoning.sources.length === 0) {
82
+ errors.push('reasoning.sources 至少包含一项来源');
83
+ }
84
+ if (
85
+ typeof c.reasoning.confidence !== 'number' ||
86
+ c.reasoning.confidence < 0 ||
87
+ c.reasoning.confidence > 1
88
+ ) {
89
+ warnings.push('reasoning.confidence 应为 0-1 的数字');
90
+ }
52
91
  }
53
92
 
54
93
  const ok = errors.length === 0;
55
- return envelope({ success: ok, data: { ok, errors, warnings, suggestions }, meta: { tool: 'autosnippet_validate_candidate' } });
94
+ return envelope({
95
+ success: ok,
96
+ data: { ok, errors, warnings, suggestions },
97
+ meta: { tool: 'autosnippet_validate_candidate' },
98
+ });
56
99
  }
57
100
 
58
101
  export async function checkDuplicate(ctx, args) {
@@ -63,7 +106,11 @@ export async function checkDuplicate(ctx, args) {
63
106
  threshold: args.threshold ?? 0.7,
64
107
  topK: args.topK ?? 5,
65
108
  });
66
- return envelope({ success: true, data: { similar }, meta: { tool: 'autosnippet_check_duplicate' } });
109
+ return envelope({
110
+ success: true,
111
+ data: { similar },
112
+ meta: { tool: 'autosnippet_check_duplicate' },
113
+ });
67
114
  }
68
115
 
69
116
  // ─── 语义字段缺失诊断(无 AI 依赖) ──────────────────────────
@@ -78,14 +125,33 @@ export async function enrichCandidates(ctx, args) {
78
125
  }
79
126
 
80
127
  const knowledgeService = ctx.container.get('knowledgeService');
81
- if (!knowledgeService) throw new Error('KnowledgeService not available');
128
+ if (!knowledgeService) {
129
+ throw new Error('KnowledgeService not available');
130
+ }
82
131
 
83
- const SEMANTIC_KEYS = ['content.rationale', 'knowledgeType', 'complexity', 'scope', 'content.steps', 'constraints'];
132
+ const SEMANTIC_KEYS = [
133
+ 'content.rationale',
134
+ 'knowledgeType',
135
+ 'complexity',
136
+ 'scope',
137
+ 'content.steps',
138
+ 'constraints',
139
+ ];
84
140
  const RECIPE_READY_KEYS = [
85
- { key: 'category', check: v => v && ['View','Service','Tool','Model','Network','Storage','UI','Utility'].includes(v), hint: 'category 必须为 8 标准值之一' },
86
- { key: 'trigger', check: v => v && v.startsWith('@'), hint: 'trigger 必须以 @ 开头' },
87
- { key: 'description', check: v => !!v, hint: '知识条目描述' },
88
- { key: 'headers', check: v => Array.isArray(v) && v.length > 0, hint: '完整 import 语句数组' },
141
+ {
142
+ key: 'category',
143
+ check: (v) =>
144
+ v &&
145
+ ['View', 'Service', 'Tool', 'Model', 'Network', 'Storage', 'UI', 'Utility'].includes(v),
146
+ hint: 'category 必须为 8 标准值之一',
147
+ },
148
+ { key: 'trigger', check: (v) => v?.startsWith('@'), hint: 'trigger 必须以 @ 开头' },
149
+ { key: 'description', check: (v) => !!v, hint: '知识条目描述' },
150
+ {
151
+ key: 'headers',
152
+ check: (v) => Array.isArray(v) && v.length > 0,
153
+ hint: '完整 import 语句数组',
154
+ },
89
155
  ];
90
156
 
91
157
  const results = [];
@@ -105,11 +171,17 @@ export async function enrichCandidates(ctx, args) {
105
171
  for (const keyPath of SEMANTIC_KEYS) {
106
172
  const parts = keyPath.split('.');
107
173
  let val = json;
108
- for (const p of parts) { val = val?.[p]; }
109
- if (val === undefined || val === null || val === '' ||
110
- (typeof val === 'string' && val.trim() === '') ||
111
- (Array.isArray(val) && val.length === 0) ||
112
- (typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length === 0)) {
174
+ for (const p of parts) {
175
+ val = val?.[p];
176
+ }
177
+ if (
178
+ val === undefined ||
179
+ val === null ||
180
+ val === '' ||
181
+ (typeof val === 'string' && val.trim() === '') ||
182
+ (Array.isArray(val) && val.length === 0) ||
183
+ (typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length === 0)
184
+ ) {
113
185
  missing.push(keyPath);
114
186
  }
115
187
  }
@@ -134,10 +206,20 @@ export async function enrichCandidates(ctx, args) {
134
206
  recipeReadyMissing,
135
207
  complete: missing.length === 0 && recipeReadyMissing.length === 0,
136
208
  });
137
- if (missing.length > 0) needsEnrichment++;
138
- if (recipeReadyMissing.length > 0) needsRecipeFields++;
209
+ if (missing.length > 0) {
210
+ needsEnrichment++;
211
+ }
212
+ if (recipeReadyMissing.length > 0) {
213
+ needsRecipeFields++;
214
+ }
139
215
  } catch (err) {
140
- results.push({ id, found: false, error: err.message, missingFields: [], recipeReadyMissing: [] });
216
+ results.push({
217
+ id,
218
+ found: false,
219
+ error: err.message,
220
+ missingFields: [],
221
+ recipeReadyMissing: [],
222
+ });
141
223
  }
142
224
  }
143
225
 
@@ -149,9 +231,10 @@ export async function enrichCandidates(ctx, args) {
149
231
  needsRecipeFields,
150
232
  fullyComplete: ids.length - Math.max(needsEnrichment, needsRecipeFields),
151
233
  entries: results,
152
- hint: (needsEnrichment > 0 || needsRecipeFields > 0)
153
- ? '请 Agent 根据 missingFields(语义)和 recipeReadyMissing(必填)自行补全后重新提交'
154
- : '所有条目字段完整',
234
+ hint:
235
+ needsEnrichment > 0 || needsRecipeFields > 0
236
+ ? '请 Agent 根据 missingFields(语义)和 recipeReadyMissing(必填)自行补全后重新提交'
237
+ : '所有条目字段完整',
155
238
  },
156
239
  meta: { tool: 'autosnippet_enrich_candidates' },
157
240
  });
@@ -7,13 +7,13 @@
7
7
  * 不包含业务逻辑,仅做参数解构 → 路由 → 转发。
8
8
  */
9
9
 
10
- import * as searchHandlers from './search.js';
10
+ import * as bootstrapHandlers from './bootstrap.js';
11
11
  import * as browseHandlers from './browse.js';
12
- import * as structureHandlers from './structure.js';
12
+ import * as candidateHandlers from './candidate.js';
13
13
  import * as guardHandlers from './guard.js';
14
+ import * as searchHandlers from './search.js';
14
15
  import * as skillHandlers from './skill.js';
15
- import * as bootstrapHandlers from './bootstrap.js';
16
- import * as candidateHandlers from './candidate.js';
16
+ import * as structureHandlers from './structure.js';
17
17
 
18
18
  // ─── autosnippet_search (整合 4 → 1) ────────────────────────
19
19
 
@@ -33,8 +33,6 @@ export async function consolidatedSearch(ctx, args) {
33
33
  return searchHandlers.semanticSearch(ctx, args);
34
34
  case 'context':
35
35
  return searchHandlers.contextSearch(ctx, args);
36
- case 'auto':
37
- case 'bm25':
38
36
  default:
39
37
  return searchHandlers.search(ctx, { ...args, mode });
40
38
  }
@@ -71,7 +69,9 @@ export async function consolidatedKnowledge(ctx, args) {
71
69
  }
72
70
  return browseHandlers.confirmUsage(ctx, args);
73
71
  default:
74
- throw new Error(`Unknown knowledge operation: ${op}. Expected: list, get, insights, confirm_usage`);
72
+ throw new Error(
73
+ `Unknown knowledge operation: ${op}. Expected: list, get, insights, confirm_usage`
74
+ );
75
75
  }
76
76
  }
77
77
 
@@ -108,7 +108,9 @@ export async function consolidatedStructure(ctx, args) {
108
108
  */
109
109
  export async function consolidatedGraph(ctx, args) {
110
110
  const op = args.operation;
111
- if (!op) throw new Error('Missing required parameter: operation. Expected: query, impact, path, stats');
111
+ if (!op) {
112
+ throw new Error('Missing required parameter: operation. Expected: query, impact, path, stats');
113
+ }
112
114
  switch (op) {
113
115
  case 'query':
114
116
  return structureHandlers.graphQuery(ctx, args);
@@ -137,7 +139,9 @@ export async function consolidatedGuard(ctx, args) {
137
139
  if (args.code) {
138
140
  return guardHandlers.guardCheck(ctx, args);
139
141
  }
140
- throw new Error('autosnippet_guard requires either "code" (single check) or "files" (batch audit) parameter');
142
+ throw new Error(
143
+ 'autosnippet_guard requires either "code" (single check) or "files" (batch audit) parameter'
144
+ );
141
145
  }
142
146
 
143
147
  // ─── autosnippet_skill (整合 6 → 1) ─────────────────────────
@@ -153,7 +157,11 @@ export async function consolidatedGuard(ctx, args) {
153
157
  */
154
158
  export async function consolidatedSkill(ctx, args) {
155
159
  const op = args.operation;
156
- if (!op) throw new Error('Missing required parameter: operation. Expected: list, load, create, update, delete, suggest');
160
+ if (!op) {
161
+ throw new Error(
162
+ 'Missing required parameter: operation. Expected: list, load, create, update, delete, suggest'
163
+ );
164
+ }
157
165
 
158
166
  // loadSkill expects { skillName }, map from { name }
159
167
  if (args.name && !args.skillName) {
@@ -174,7 +182,9 @@ export async function consolidatedSkill(ctx, args) {
174
182
  case 'suggest':
175
183
  return skillHandlers.suggestSkills(ctx);
176
184
  default:
177
- throw new Error(`Unknown skill operation: ${op}. Expected: list, load, create, update, delete, suggest`);
185
+ throw new Error(
186
+ `Unknown skill operation: ${op}. Expected: list, load, create, update, delete, suggest`
187
+ );
178
188
  }
179
189
  }
180
190
 
@@ -188,7 +198,9 @@ export async function consolidatedSkill(ctx, args) {
188
198
  */
189
199
  export async function consolidatedBootstrap(ctx, args) {
190
200
  const op = args.operation;
191
- if (!op) throw new Error('Missing required parameter: operation. Expected: knowledge, refine, scan');
201
+ if (!op) {
202
+ throw new Error('Missing required parameter: operation. Expected: knowledge, refine, scan');
203
+ }
192
204
  switch (op) {
193
205
  case 'knowledge':
194
206
  return bootstrapHandlers.bootstrapKnowledge(ctx, args);
@@ -248,7 +260,21 @@ export async function enhancedSubmitKnowledge(ctx, args) {
248
260
  data: {
249
261
  missingFields: readiness.missing,
250
262
  suggestions: readiness.suggestions,
251
- requiredFields: ['title', 'language', 'content', 'kind', 'doClause', 'category', 'trigger', 'description', 'headers', 'usageGuide', 'knowledgeType', 'rationale (in content.rationale)'],
263
+ requiredFields: [
264
+ 'title',
265
+ 'language',
266
+ 'content (pattern/markdown)',
267
+ 'content.rationale',
268
+ 'kind (rule/pattern/fact)',
269
+ 'doClause',
270
+ 'category (View/Service/Tool/Model/Network/Storage/UI/Utility)',
271
+ 'trigger (@前缀)',
272
+ 'description',
273
+ 'headers (import 语句数组)',
274
+ 'usageGuide (### 章节格式)',
275
+ 'knowledgeType',
276
+ 'reasoning (whyStandard + sources + confidence)',
277
+ ],
252
278
  },
253
279
  meta: { tool: 'autosnippet_submit_knowledge' },
254
280
  });
@@ -258,7 +284,9 @@ export async function enhancedSubmitKnowledge(ctx, args) {
258
284
  const result = await submitKnowledge(ctx, args);
259
285
 
260
286
  // 如果提交本身失败,直接返回
261
- if (result && !result.success) return result;
287
+ if (result && !result.success) {
288
+ return result;
289
+ }
262
290
 
263
291
  // ── 附加去重检测结果(非阻塞) ──
264
292
  let duplicateCheck = null;
@@ -269,10 +297,14 @@ export async function enhancedSubmitKnowledge(ctx, args) {
269
297
  summary: args.description || '',
270
298
  code: args.content?.pattern || '',
271
299
  };
272
- const dedupResult = await candidateHandlers.checkDuplicate(ctx, { candidate: dedupCandidate, threshold: 0.7, topK: 3 });
300
+ const dedupResult = await candidateHandlers.checkDuplicate(ctx, {
301
+ candidate: dedupCandidate,
302
+ threshold: 0.7,
303
+ topK: 3,
304
+ });
273
305
  if (dedupResult?.data) {
274
306
  duplicateCheck = {
275
- hasSimilar: dedupResult.data.hasDuplicate ?? (dedupResult.data.matches?.length > 0),
307
+ hasSimilar: dedupResult.data.hasDuplicate ?? dedupResult.data.matches?.length > 0,
276
308
  closest: dedupResult.data.matches?.[0] || null,
277
309
  };
278
310
  }
@@ -282,7 +314,7 @@ export async function enhancedSubmitKnowledge(ctx, args) {
282
314
  }
283
315
 
284
316
  // 将去重结果附到响应中
285
- if (result && result.data) {
317
+ if (result?.data) {
286
318
  result.data.duplicateCheck = duplicateCheck;
287
319
  }
288
320