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
@@ -5,13 +5,13 @@
5
5
  */
6
6
 
7
7
  import express from 'express';
8
- import { asyncHandler } from '../middleware/errorHandler.js';
8
+ import Logger from '../../infrastructure/logging/Logger.js';
9
9
  import { getServiceContainer } from '../../injection/ServiceContainer.js';
10
10
  import { ValidationError } from '../../shared/errors/index.js';
11
- import Logger from '../../infrastructure/logging/Logger.js';
11
+ import { asyncHandler } from '../middleware/errorHandler.js';
12
12
  import { getContext, safeInt } from '../utils/routeHelpers.js';
13
13
 
14
- const logger = Logger.getInstance();
14
+ const _logger = Logger.getInstance();
15
15
  const router = express.Router();
16
16
 
17
17
  const MAX_BATCH_SIZE = 100;
@@ -22,55 +22,81 @@ const MAX_BATCH_SIZE = 100;
22
22
  * GET /api/v1/knowledge
23
23
  * 获取知识条目列表(支持筛选和分页)
24
24
  */
25
- router.get('/', asyncHandler(async (req, res) => {
26
- const { lifecycle, kind, category, language, knowledgeType, scope, keyword, tag, source } = req.query;
27
- const page = safeInt(req.query.page, 1);
28
- const pageSize = safeInt(req.query.limit, 20, 1, 1000);
29
-
30
- const container = getServiceContainer();
31
- const knowledgeService = container.get('knowledgeService');
32
-
33
- if (keyword) {
34
- const result = await knowledgeService.search(keyword, { page, pageSize });
35
- return res.json({ success: true, data: result });
36
- }
37
-
38
- const filters = {};
39
- if (lifecycle) filters.lifecycle = lifecycle;
40
- if (kind) filters.kind = kind;
41
- if (category) filters.category = category;
42
- if (language) filters.language = language;
43
- if (knowledgeType) filters.knowledgeType = knowledgeType;
44
- if (scope) filters.scope = scope;
45
- if (tag) filters.tag = tag;
46
- if (source) filters.source = source;
47
-
48
- const result = await knowledgeService.list(filters, { page, pageSize });
49
- res.json({ success: true, data: result });
50
- }));
25
+ router.get(
26
+ '/',
27
+ asyncHandler(async (req, res) => {
28
+ const { lifecycle, kind, category, language, knowledgeType, scope, keyword, tag, source } =
29
+ req.query;
30
+ const page = safeInt(req.query.page, 1);
31
+ const pageSize = safeInt(req.query.limit, 20, 1, 1000);
32
+
33
+ const container = getServiceContainer();
34
+ const knowledgeService = container.get('knowledgeService');
35
+
36
+ if (keyword) {
37
+ const result = await knowledgeService.search(keyword, { page, pageSize });
38
+ return res.json({ success: true, data: result });
39
+ }
40
+
41
+ const filters = {};
42
+ if (lifecycle) {
43
+ filters.lifecycle = lifecycle;
44
+ }
45
+ if (kind) {
46
+ filters.kind = kind;
47
+ }
48
+ if (category) {
49
+ filters.category = category;
50
+ }
51
+ if (language) {
52
+ filters.language = language;
53
+ }
54
+ if (knowledgeType) {
55
+ filters.knowledgeType = knowledgeType;
56
+ }
57
+ if (scope) {
58
+ filters.scope = scope;
59
+ }
60
+ if (tag) {
61
+ filters.tag = tag;
62
+ }
63
+ if (source) {
64
+ filters.source = source;
65
+ }
66
+
67
+ const result = await knowledgeService.list(filters, { page, pageSize });
68
+ res.json({ success: true, data: result });
69
+ })
70
+ );
51
71
 
52
72
  /**
53
73
  * GET /api/v1/knowledge/stats
54
74
  * 获取统计信息
55
75
  */
56
- router.get('/stats', asyncHandler(async (req, res) => {
57
- const container = getServiceContainer();
58
- const knowledgeService = container.get('knowledgeService');
59
- const stats = await knowledgeService.getStats();
60
- res.json({ success: true, data: stats });
61
- }));
76
+ router.get(
77
+ '/stats',
78
+ asyncHandler(async (req, res) => {
79
+ const container = getServiceContainer();
80
+ const knowledgeService = container.get('knowledgeService');
81
+ const stats = await knowledgeService.getStats();
82
+ res.json({ success: true, data: stats });
83
+ })
84
+ );
62
85
 
63
86
  /**
64
87
  * GET /api/v1/knowledge/:id
65
88
  * 获取知识条目详情
66
89
  */
67
- router.get('/:id', asyncHandler(async (req, res) => {
68
- const { id } = req.params;
69
- const container = getServiceContainer();
70
- const knowledgeService = container.get('knowledgeService');
71
- const entry = await knowledgeService.get(id);
72
- res.json({ success: true, data: entry.toJSON() });
73
- }));
90
+ router.get(
91
+ '/:id',
92
+ asyncHandler(async (req, res) => {
93
+ const { id } = req.params;
94
+ const container = getServiceContainer();
95
+ const knowledgeService = container.get('knowledgeService');
96
+ const entry = await knowledgeService.get(id);
97
+ res.json({ success: true, data: entry.toJSON() });
98
+ })
99
+ );
74
100
 
75
101
  /* ═══ CRUD ═══════════════════════════════════════════════ */
76
102
 
@@ -78,51 +104,60 @@ router.get('/:id', asyncHandler(async (req, res) => {
78
104
  * POST /api/v1/knowledge
79
105
  * 创建知识条目(wire format 直通)
80
106
  */
81
- router.post('/', asyncHandler(async (req, res) => {
82
- const data = req.body;
83
-
84
- if (!data.title || !data.content) {
85
- throw new ValidationError('title and content are required');
86
- }
87
-
88
- const container = getServiceContainer();
89
- const knowledgeService = container.get('knowledgeService');
90
- const context = getContext(req);
91
-
92
- const entry = await knowledgeService.create(data, context);
93
- res.status(201).json({
94
- success: true,
95
- data: entry.toJSON(),
96
- });
97
- }));
107
+ router.post(
108
+ '/',
109
+ asyncHandler(async (req, res) => {
110
+ const data = req.body;
111
+
112
+ if (!data.title || !data.content) {
113
+ throw new ValidationError('title and content are required');
114
+ }
115
+
116
+ const container = getServiceContainer();
117
+ const knowledgeService = container.get('knowledgeService');
118
+ const context = getContext(req);
119
+
120
+ const entry = await knowledgeService.create(data, context);
121
+ res.status(201).json({
122
+ success: true,
123
+ data: entry.toJSON(),
124
+ });
125
+ })
126
+ );
98
127
 
99
128
  /**
100
129
  * PATCH /api/v1/knowledge/:id
101
130
  * 更新知识条目(白名单字段)
102
131
  */
103
- router.patch('/:id', asyncHandler(async (req, res) => {
104
- const { id } = req.params;
105
- const container = getServiceContainer();
106
- const knowledgeService = container.get('knowledgeService');
107
- const context = getContext(req);
108
-
109
- const entry = await knowledgeService.update(id, req.body, context);
110
- res.json({ success: true, data: entry.toJSON() });
111
- }));
132
+ router.patch(
133
+ '/:id',
134
+ asyncHandler(async (req, res) => {
135
+ const { id } = req.params;
136
+ const container = getServiceContainer();
137
+ const knowledgeService = container.get('knowledgeService');
138
+ const context = getContext(req);
139
+
140
+ const entry = await knowledgeService.update(id, req.body, context);
141
+ res.json({ success: true, data: entry.toJSON() });
142
+ })
143
+ );
112
144
 
113
145
  /**
114
146
  * DELETE /api/v1/knowledge/:id
115
147
  * 删除知识条目
116
148
  */
117
- router.delete('/:id', asyncHandler(async (req, res) => {
118
- const { id } = req.params;
119
- const container = getServiceContainer();
120
- const knowledgeService = container.get('knowledgeService');
121
- const context = getContext(req);
122
-
123
- const result = await knowledgeService.delete(id, context);
124
- res.json({ success: true, data: result });
125
- }));
149
+ router.delete(
150
+ '/:id',
151
+ asyncHandler(async (req, res) => {
152
+ const { id } = req.params;
153
+ const container = getServiceContainer();
154
+ const knowledgeService = container.get('knowledgeService');
155
+ const context = getContext(req);
156
+
157
+ const result = await knowledgeService.delete(id, context);
158
+ res.json({ success: true, data: result });
159
+ })
160
+ );
126
161
 
127
162
  /* ═══ 生命周期操作(3 状态: pending / active / deprecated)═══ */
128
163
 
@@ -130,49 +165,58 @@ router.delete('/:id', asyncHandler(async (req, res) => {
130
165
  * PATCH /api/v1/knowledge/:id/publish
131
166
  * 发布 (pending → active) — 仅开发者
132
167
  */
133
- router.patch('/:id/publish', asyncHandler(async (req, res) => {
134
- const { id } = req.params;
135
- const container = getServiceContainer();
136
- const knowledgeService = container.get('knowledgeService');
137
- const context = getContext(req);
138
-
139
- const entry = await knowledgeService.publish(id, context);
140
- res.json({ success: true, data: entry.toJSON() });
141
- }));
168
+ router.patch(
169
+ '/:id/publish',
170
+ asyncHandler(async (req, res) => {
171
+ const { id } = req.params;
172
+ const container = getServiceContainer();
173
+ const knowledgeService = container.get('knowledgeService');
174
+ const context = getContext(req);
175
+
176
+ const entry = await knowledgeService.publish(id, context);
177
+ res.json({ success: true, data: entry.toJSON() });
178
+ })
179
+ );
142
180
 
143
181
  /**
144
182
  * PATCH /api/v1/knowledge/:id/deprecate
145
183
  * 废弃 (pending|active → deprecated)
146
184
  */
147
- router.patch('/:id/deprecate', asyncHandler(async (req, res) => {
148
- const { id } = req.params;
149
- const { reason } = req.body;
185
+ router.patch(
186
+ '/:id/deprecate',
187
+ asyncHandler(async (req, res) => {
188
+ const { id } = req.params;
189
+ const { reason } = req.body;
150
190
 
151
- if (!reason) {
152
- throw new ValidationError('reason is required for deprecation');
153
- }
191
+ if (!reason) {
192
+ throw new ValidationError('reason is required for deprecation');
193
+ }
154
194
 
155
- const container = getServiceContainer();
156
- const knowledgeService = container.get('knowledgeService');
157
- const context = getContext(req);
195
+ const container = getServiceContainer();
196
+ const knowledgeService = container.get('knowledgeService');
197
+ const context = getContext(req);
158
198
 
159
- const entry = await knowledgeService.deprecate(id, reason, context);
160
- res.json({ success: true, data: entry.toJSON() });
161
- }));
199
+ const entry = await knowledgeService.deprecate(id, reason, context);
200
+ res.json({ success: true, data: entry.toJSON() });
201
+ })
202
+ );
162
203
 
163
204
  /**
164
205
  * PATCH /api/v1/knowledge/:id/reactivate
165
206
  * 重新激活 (deprecated → pending)
166
207
  */
167
- router.patch('/:id/reactivate', asyncHandler(async (req, res) => {
168
- const { id } = req.params;
169
- const container = getServiceContainer();
170
- const knowledgeService = container.get('knowledgeService');
171
- const context = getContext(req);
172
-
173
- const entry = await knowledgeService.reactivate(id, context);
174
- res.json({ success: true, data: entry.toJSON() });
175
- }));
208
+ router.patch(
209
+ '/:id/reactivate',
210
+ asyncHandler(async (req, res) => {
211
+ const { id } = req.params;
212
+ const container = getServiceContainer();
213
+ const knowledgeService = container.get('knowledgeService');
214
+ const context = getContext(req);
215
+
216
+ const entry = await knowledgeService.reactivate(id, context);
217
+ res.json({ success: true, data: entry.toJSON() });
218
+ })
219
+ );
176
220
 
177
221
  /* ═══ 批量操作 ═══════════════════════════════════════════ */
178
222
 
@@ -181,34 +225,43 @@ router.patch('/:id/reactivate', asyncHandler(async (req, res) => {
181
225
  * 批量发布 (pending → active)
182
226
  * 支持 autoApprovableOnly=true 参数,只发布 autoApprovable 的条目
183
227
  */
184
- router.post('/batch-publish', asyncHandler(async (req, res) => {
185
- const { ids } = req.body;
186
-
187
- if (!Array.isArray(ids) || ids.length === 0) {
188
- throw new ValidationError('ids array is required and must not be empty');
189
- }
190
- if (ids.length > MAX_BATCH_SIZE) {
191
- throw new ValidationError(`Batch size exceeds limit of ${MAX_BATCH_SIZE}`);
192
- }
193
-
194
- const container = getServiceContainer();
195
- const knowledgeService = container.get('knowledgeService');
196
- const context = getContext(req);
197
-
198
- const results = await Promise.allSettled(
199
- ids.map(id => knowledgeService.publish(id, context)),
200
- );
201
-
202
- const published = results.filter(r => r.status === 'fulfilled').map(r => r.value.toJSON());
203
- const failed = results
204
- .map((r, i) => r.status === 'rejected' ? { id: ids[i], error: r.reason?.message } : null)
205
- .filter(Boolean);
206
-
207
- res.json({
208
- success: true,
209
- data: { published, failed, total: ids.length, successCount: published.length, failureCount: failed.length },
210
- });
211
- }));
228
+ router.post(
229
+ '/batch-publish',
230
+ asyncHandler(async (req, res) => {
231
+ const { ids } = req.body;
232
+
233
+ if (!Array.isArray(ids) || ids.length === 0) {
234
+ throw new ValidationError('ids array is required and must not be empty');
235
+ }
236
+ if (ids.length > MAX_BATCH_SIZE) {
237
+ throw new ValidationError(`Batch size exceeds limit of ${MAX_BATCH_SIZE}`);
238
+ }
239
+
240
+ const container = getServiceContainer();
241
+ const knowledgeService = container.get('knowledgeService');
242
+ const context = getContext(req);
243
+
244
+ const results = await Promise.allSettled(
245
+ ids.map((id) => knowledgeService.publish(id, context))
246
+ );
247
+
248
+ const published = results.filter((r) => r.status === 'fulfilled').map((r) => r.value.toJSON());
249
+ const failed = results
250
+ .map((r, i) => (r.status === 'rejected' ? { id: ids[i], error: r.reason?.message } : null))
251
+ .filter(Boolean);
252
+
253
+ res.json({
254
+ success: true,
255
+ data: {
256
+ published,
257
+ failed,
258
+ total: ids.length,
259
+ successCount: published.length,
260
+ failureCount: failed.length,
261
+ },
262
+ });
263
+ })
264
+ );
212
265
 
213
266
  /* ═══ 使用 / 质量 ═══════════════════════════════════════ */
214
267
 
@@ -216,31 +269,37 @@ router.post('/batch-publish', asyncHandler(async (req, res) => {
216
269
  * POST /api/v1/knowledge/:id/usage
217
270
  * 记录使用(adoption / application / guard_hit / view / success)
218
271
  */
219
- router.post('/:id/usage', asyncHandler(async (req, res) => {
220
- const { id } = req.params;
221
- const { type = 'adoption', feedback } = req.body;
222
- const context = getContext(req);
272
+ router.post(
273
+ '/:id/usage',
274
+ asyncHandler(async (req, res) => {
275
+ const { id } = req.params;
276
+ const { type = 'adoption', feedback } = req.body;
277
+ const context = getContext(req);
223
278
 
224
- const container = getServiceContainer();
225
- const knowledgeService = container.get('knowledgeService');
279
+ const container = getServiceContainer();
280
+ const knowledgeService = container.get('knowledgeService');
226
281
 
227
- await knowledgeService.incrementUsage(id, type, { actor: context.userId, feedback });
228
- res.json({ success: true, message: `${type} recorded` });
229
- }));
282
+ await knowledgeService.incrementUsage(id, type, { actor: context.userId, feedback });
283
+ res.json({ success: true, message: `${type} recorded` });
284
+ })
285
+ );
230
286
 
231
287
  /**
232
288
  * PATCH /api/v1/knowledge/:id/quality
233
289
  * 重新计算质量评分
234
290
  */
235
- router.patch('/:id/quality', asyncHandler(async (req, res) => {
236
- const { id } = req.params;
237
- const context = getContext(req);
238
-
239
- const container = getServiceContainer();
240
- const knowledgeService = container.get('knowledgeService');
241
-
242
- const result = await knowledgeService.updateQuality(id, context);
243
- res.json({ success: true, data: result });
244
- }));
291
+ router.patch(
292
+ '/:id/quality',
293
+ asyncHandler(async (req, res) => {
294
+ const { id } = req.params;
295
+ const context = getContext(req);
296
+
297
+ const container = getServiceContainer();
298
+ const knowledgeService = container.get('knowledgeService');
299
+
300
+ const result = await knowledgeService.updateQuality(id, context);
301
+ res.json({ success: true, data: result });
302
+ })
303
+ );
245
304
 
246
305
  export default router;