autosnippet 3.3.7 → 3.3.8

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 (211) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  4. package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +7 -4
  7. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  8. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  9. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  10. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  11. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  12. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  13. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  14. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  15. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  16. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  17. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  18. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  19. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  20. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  21. package/dist/lib/agent/memory/SessionStore.js +0 -2
  22. package/dist/lib/agent/tools/ast-graph.js +21 -19
  23. package/dist/lib/agent/tools/infrastructure.js +3 -2
  24. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  25. package/dist/lib/agent/tools/project-access.js +5 -4
  26. package/dist/lib/bootstrap.js +2 -1
  27. package/dist/lib/cli/AiScanService.js +4 -17
  28. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  29. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  30. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  31. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
  32. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
  33. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  34. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  35. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  36. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  37. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  38. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  39. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  40. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  41. package/dist/lib/domain/knowledge/index.js +1 -1
  42. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  43. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  44. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
  45. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  46. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  47. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
  48. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
  49. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  50. package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
  51. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  52. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  53. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  54. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  55. package/dist/lib/external/mcp/handlers/search.js +3 -1
  56. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  57. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  58. package/dist/lib/external/mcp/handlers/system.js +10 -34
  59. package/dist/lib/http/routes/ai.js +11 -13
  60. package/dist/lib/http/routes/guardReport.js +3 -5
  61. package/dist/lib/http/routes/panorama.js +12 -12
  62. package/dist/lib/http/routes/recipes.js +59 -8
  63. package/dist/lib/http/routes/remote.js +3 -13
  64. package/dist/lib/http/routes/search.js +11 -8
  65. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  66. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  67. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  68. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  69. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  70. package/dist/lib/injection/ServiceContainer.js +7 -4
  71. package/dist/lib/injection/ServiceMap.d.ts +20 -0
  72. package/dist/lib/injection/modules/AppModule.js +2 -1
  73. package/dist/lib/injection/modules/GuardModule.js +5 -5
  74. package/dist/lib/injection/modules/InfraModule.js +60 -0
  75. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  76. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  77. package/dist/lib/injection/modules/VectorModule.js +3 -0
  78. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  79. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  80. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  81. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  82. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  83. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  84. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  85. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  86. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  87. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  88. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  89. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  90. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  91. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  92. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  93. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  94. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  95. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  96. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  97. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  98. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  99. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  100. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  101. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  102. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  103. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  104. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  105. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  106. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  107. package/dist/lib/repository/session/SessionRepository.js +110 -0
  108. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  109. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  110. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  111. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  112. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  113. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  114. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  115. package/dist/lib/service/cleanup/CleanupService.js +8 -4
  116. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  117. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  118. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  119. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  120. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  121. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  122. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  123. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  124. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  125. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  126. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  127. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  128. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  129. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  130. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  131. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  132. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  133. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  134. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  135. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  136. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  137. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  138. package/dist/lib/service/evolution/StagingManager.js +37 -95
  139. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  140. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  141. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  142. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  143. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  144. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  145. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  146. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  147. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  148. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  149. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
  150. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
  151. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  152. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  153. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  154. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  155. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  156. package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
  157. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  158. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  159. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  160. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  161. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
  162. package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
  163. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  164. package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
  165. package/dist/lib/service/panorama/LayerInferrer.js +1 -1
  166. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
  167. package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
  168. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
  169. package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
  170. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  171. package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
  172. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  173. package/dist/lib/service/panorama/PanoramaService.js +41 -66
  174. package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
  175. package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
  176. package/dist/lib/service/panorama/RoleRefiner.js +52 -283
  177. package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
  178. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  179. package/dist/lib/service/quality/QualityScorer.js +157 -83
  180. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  181. package/dist/lib/service/search/SearchEngine.js +32 -37
  182. package/dist/lib/service/signal/HitRecorder.js +5 -5
  183. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  184. package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
  185. package/dist/lib/service/skills/SignalCollector.js +28 -55
  186. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  187. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  188. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  189. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  190. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  191. package/dist/lib/service/vector/VectorService.js +3 -0
  192. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  193. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  194. package/dist/lib/shared/LanguageProfiles.js +939 -0
  195. package/dist/lib/shared/LanguageService.d.ts +6 -0
  196. package/dist/lib/shared/LanguageService.js +16 -0
  197. package/dist/lib/shared/constants.d.ts +19 -19
  198. package/dist/lib/shared/constants.js +10 -10
  199. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  200. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  201. package/dist/lib/types/project-snapshot-builder.js +0 -1
  202. package/dist/lib/types/project-snapshot.d.ts +0 -1
  203. package/dist/lib/types/project-snapshot.js +0 -1
  204. package/dist/lib/types/snapshot-views.d.ts +0 -2
  205. package/dist/lib/types/snapshot-views.js +0 -1
  206. package/package.json +2 -1
  207. package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
  208. package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
  209. package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
  210. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  211. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -6,6 +6,7 @@
6
6
  * 此路由仅处理 Recipe 特有的批量 AI 操作。
7
7
  */
8
8
  import express from 'express';
9
+ import { COUNTABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
9
10
  import Logger from '../../infrastructure/logging/Logger.js';
10
11
  import { getServiceContainer } from '../../injection/ServiceContainer.js';
11
12
  const router = express.Router();
@@ -77,11 +78,10 @@ router.post('/discover-relations', async (req, res) => {
77
78
  data: { status: 'error', error: 'AI Provider 未配置,当前为 Mock 模式。请先配置 API Key。' },
78
79
  });
79
80
  }
80
- // 快速检查:至少需要 2 条活跃 Recipe
81
+ // 快速检查:至少需要 2 条可消费 Recipe(active/staging/pending/evolving)
81
82
  try {
82
- const knowledgeService = container.get('knowledgeService');
83
- const { items = [], data = [] } = (await knowledgeService.list({ lifecycle: 'active' }, { page: 1, pageSize: 5 }));
84
- const count = items.length || data.length;
83
+ const knowledgeRepo = container.get('knowledgeRepository');
84
+ const count = await knowledgeRepo.countByLifecycles(COUNTABLE_LIFECYCLES);
85
85
  if (count < 2) {
86
86
  return void res.json({
87
87
  success: true,
@@ -93,7 +93,7 @@ router.post('/discover-relations', async (req, res) => {
93
93
  }
94
94
  }
95
95
  catch {
96
- // 如果 list 失败,继续尝试(让 runTask 给出具体错误)
96
+ // 如果查询失败,继续尝试(让 runTask 给出具体错误)
97
97
  }
98
98
  // 重置并启动后台任务
99
99
  resetTask();
@@ -103,11 +103,62 @@ router.post('/discover-relations', async (req, res) => {
103
103
  (async () => {
104
104
  try {
105
105
  const result = await agentFactory.discoverRelations();
106
+ const relations = result.relations || [];
107
+ const analyzed = result.analyzed || 0;
108
+ // 将 AI 发现的关系写入知识图谱
109
+ // AI 返回的 from/to 是 Recipe 标题,需要解析为实际 ID
110
+ let written = 0;
111
+ if (relations.length > 0) {
112
+ try {
113
+ const graphService = container.get('knowledgeGraphService');
114
+ const knowledgeRepo = container.get('knowledgeRepository');
115
+ // 缓存标题 → ID 映射,避免重复查询
116
+ const titleToId = new Map();
117
+ const resolveId = async (title) => {
118
+ if (titleToId.has(title)) {
119
+ return titleToId.get(title);
120
+ }
121
+ try {
122
+ const entry = await knowledgeRepo.findByTitle(title);
123
+ const id = entry?.id ?? null;
124
+ titleToId.set(title, id);
125
+ return id;
126
+ }
127
+ catch {
128
+ titleToId.set(title, null);
129
+ return null;
130
+ }
131
+ };
132
+ for (const rel of relations) {
133
+ if (!rel.from || !rel.to || !rel.type) {
134
+ continue;
135
+ }
136
+ const fromId = await resolveId(rel.from);
137
+ const toId = await resolveId(rel.to);
138
+ if (!fromId || !toId) {
139
+ continue;
140
+ }
141
+ const res = await graphService.addEdge(fromId, 'recipe', toId, 'recipe', rel.type, {
142
+ weight: 0.7,
143
+ source: 'ai-discovery',
144
+ evidence: rel.evidence || '',
145
+ });
146
+ if (res.success) {
147
+ written++;
148
+ }
149
+ }
150
+ }
151
+ catch (graphErr) {
152
+ logger.warn('Failed to write some discovered edges', {
153
+ error: graphErr.message,
154
+ });
155
+ }
156
+ }
106
157
  discoverTask.status = 'done';
107
158
  discoverTask.finishedAt = new Date().toISOString();
108
- discoverTask.discovered = result.discovered || 0;
109
- discoverTask.totalPairs = result.totalPairs || 0;
110
- discoverTask.batchErrors = result.batchErrors || 0;
159
+ discoverTask.discovered = written;
160
+ discoverTask.totalPairs = analyzed;
161
+ discoverTask.batchErrors = relations.length - written;
111
162
  discoverTask.elapsed = Math.round((new Date(discoverTask.finishedAt).getTime() - new Date(discoverTask.startedAt).getTime()) /
112
163
  1000);
113
164
  logger.info('Discover relations completed', {
@@ -21,7 +21,6 @@ import express from 'express';
21
21
  import { LarkTransport } from '../../external/lark/LarkTransport.js';
22
22
  import Logger from '../../infrastructure/logging/Logger.js';
23
23
  import { getServiceContainer } from '../../injection/ServiceContainer.js';
24
- import { RemoteCommandRepository, } from '../../repository/remote/RemoteCommandRepository.js';
25
24
  import { resolveProjectRoot } from '../../shared/resolveProjectRoot.js';
26
25
  import { RemoteHistoryQuery, RemoteNotifyBody, RemoteResultBody, RemoteSendBody, } from '../../shared/schemas/http-requests.js';
27
26
  import { validate, validateQuery } from '../middleware/validate.js';
@@ -32,19 +31,10 @@ const PENDING_TIMEOUT_SEC = 120; // pending 超过 2 分钟 → timeout
32
31
  const RUNNING_TIMEOUT_SEC = 600; // running 超过 10 分钟 → timeout
33
32
  const CLEANUP_INTERVAL_MS = 30_000; // 每 30 秒清理一次
34
33
  // ─── 数据库辅助 ─────────────────────────────────────
35
- function getDb() {
36
- const container = getServiceContainer();
37
- const database = container.get('database');
38
- return typeof database?.getDb === 'function' ? database.getDb() : database;
39
- }
40
- let _repo = null;
41
- /** 获取或创建 RemoteCommandRepository 单例 */
34
+ /** DI 容器获取 RemoteCommandRepository */
42
35
  function getRepo() {
43
- if (!_repo) {
44
- const db = getDb();
45
- _repo = new RemoteCommandRepository(db);
46
- }
47
- return _repo;
36
+ const container = getServiceContainer();
37
+ return container.get('remoteCommandRepository');
48
38
  }
49
39
  function genId() {
50
40
  return `rcmd_${Date.now().toString(36)}_${crypto.randomBytes(3).toString('hex')}`;
@@ -98,8 +98,8 @@ router.get('/graph', validateQuery(GraphQuery), async (req, res) => {
98
98
  return void res.json({ success: true, data: { outgoing: [], incoming: [] } });
99
99
  }
100
100
  const edges = relation
101
- ? graphService.getRelated(nodeId, nodeType, relation)
102
- : graphService.getEdges(nodeId, nodeType, direction);
101
+ ? await graphService.getRelated(nodeId, nodeType, relation)
102
+ : await graphService.getEdges(nodeId, nodeType, direction);
103
103
  res.json({ success: true, data: edges });
104
104
  });
105
105
  /**
@@ -114,7 +114,7 @@ router.get('/graph/impact', validateQuery(GraphImpactQuery), async (req, res) =>
114
114
  if (!graphService) {
115
115
  return void res.json({ success: true, data: [] });
116
116
  }
117
- const impact = graphService.getImpactAnalysis(nodeId, nodeType, maxDepth);
117
+ const impact = await graphService.getImpactAnalysis(nodeId, nodeType, maxDepth);
118
118
  res.json({ success: true, data: impact });
119
119
  });
120
120
  /**
@@ -129,9 +129,11 @@ router.get('/graph/all', async (req, res) => {
129
129
  if (!graphService) {
130
130
  return void res.json({ success: true, data: { edges: [], nodeLabels: {} } });
131
131
  }
132
- // 只返回 recipe 类型的关系边;module 依赖已由 /spm/dep-graph 提供
133
- const nodeType = String(req.query.nodeType || 'recipe');
134
- const edges = graphService.getAllEdges(limit, nodeType === 'all' ? undefined : nodeType);
132
+ // 默认不过滤 nodeType,返回所有知识相关边(recipe + knowledge)
133
+ // 仅当显式指定 nodeType 时才过滤(module 类由 /spm/dep-graph 提供)
134
+ const rawNodeType = req.query.nodeType;
135
+ const nodeType = rawNodeType === 'all' ? undefined : rawNodeType || undefined;
136
+ const edges = await graphService.getAllEdges(limit, nodeType);
135
137
  // 收集节点 ID + 类型 → 按类型查标签
136
138
  const nodeMap = new Map(); // id → Set<type>
137
139
  for (const e of edges) {
@@ -183,8 +185,9 @@ router.get('/graph/stats', async (req, res) => {
183
185
  data: { totalEdges: 0, byRelation: {}, nodeTypes: [] },
184
186
  });
185
187
  }
186
- const nodeType = String(req.query.nodeType || 'recipe');
187
- const stats = graphService.getStats(nodeType === 'all' ? undefined : nodeType);
188
+ const rawStatsType = req.query.nodeType;
189
+ const statsNodeType = rawStatsType === 'all' ? undefined : rawStatsType || undefined;
190
+ const stats = await graphService.getStats(statsNodeType);
188
191
  res.json({ success: true, data: stats });
189
192
  });
190
193
  /**
@@ -41,7 +41,18 @@ export declare class AuditLogger {
41
41
  startDate?: number;
42
42
  endDate?: number;
43
43
  limit?: number;
44
- }): Promise<unknown[]>;
44
+ }): Promise<{
45
+ id: string;
46
+ timestamp: number;
47
+ actor: string;
48
+ actorContext: string | null;
49
+ action: string;
50
+ resource: string | null;
51
+ operationData: string | null;
52
+ result: string;
53
+ errorMessage: string | null;
54
+ duration: number | null;
55
+ }[]>;
45
56
  /** 获取特定请求的日志 */
46
57
  getByRequestId(requestId: string): Promise<{
47
58
  id: string;
@@ -102,8 +113,14 @@ export declare class AuditLogger {
102
113
  failure: number;
103
114
  successRate: string;
104
115
  avgDuration: string;
105
- byActor: unknown[];
106
- byAction: unknown[];
116
+ byActor: {
117
+ actor: string;
118
+ count: number;
119
+ }[];
120
+ byAction: {
121
+ action: string;
122
+ count: number;
123
+ }[];
107
124
  }>;
108
125
  }
109
126
  export default AuditLogger;
@@ -1,14 +1,10 @@
1
1
  import type { DrizzleDB } from '../database/drizzle/index.js';
2
2
  export declare class AuditStore {
3
3
  #private;
4
- db: import('better-sqlite3').Database;
5
4
  constructor(db: {
6
5
  getDb: () => import('better-sqlite3').Database;
7
6
  }, drizzle?: DrizzleDB);
8
- /**
9
- * 保存审计日志
10
- * ★ Drizzle 类型安全 INSERT
11
- */
7
+ /** 保存审计日志 */
12
8
  save(entry: {
13
9
  id: string;
14
10
  timestamp: number;
@@ -21,7 +17,7 @@ export declare class AuditStore {
21
17
  error_message: string | null;
22
18
  duration: number | null;
23
19
  }): Promise<void>;
24
- /** 查询审计日志 */
20
+ /** 查询审计日志(动态多条件,全 Drizzle) */
25
21
  query(filters?: {
26
22
  actor?: string;
27
23
  action?: string;
@@ -29,11 +25,19 @@ export declare class AuditStore {
29
25
  startDate?: number;
30
26
  endDate?: number;
31
27
  limit?: number;
32
- }): unknown[];
33
- /**
34
- * 根据请求 ID 查询
35
- * ★ Drizzle 类型安全 SELECT
36
- */
28
+ }): {
29
+ id: string;
30
+ timestamp: number;
31
+ actor: string;
32
+ actorContext: string | null;
33
+ action: string;
34
+ resource: string | null;
35
+ operationData: string | null;
36
+ result: string;
37
+ errorMessage: string | null;
38
+ duration: number | null;
39
+ }[];
40
+ /** 根据请求 ID 查询 */
37
41
  findByRequestId(requestId: string): {
38
42
  id: string;
39
43
  timestamp: number;
@@ -46,10 +50,7 @@ export declare class AuditStore {
46
50
  errorMessage: string | null;
47
51
  duration: number | null;
48
52
  } | undefined;
49
- /**
50
- * 根据角色查询
51
- * ★ Drizzle 类型安全 SELECT
52
- */
53
+ /** 根据角色查询 */
53
54
  findByActor(actor: string, limit?: number): {
54
55
  id: string;
55
56
  timestamp: number;
@@ -62,10 +63,7 @@ export declare class AuditStore {
62
63
  errorMessage: string | null;
63
64
  duration: number | null;
64
65
  }[];
65
- /**
66
- * 根据操作查询
67
- * ★ Drizzle 类型安全 SELECT
68
- */
66
+ /** 根据操作查询 */
69
67
  findByAction(action: string, limit?: number): {
70
68
  id: string;
71
69
  timestamp: number;
@@ -78,10 +76,7 @@ export declare class AuditStore {
78
76
  errorMessage: string | null;
79
77
  duration: number | null;
80
78
  }[];
81
- /**
82
- * 根据结果查询
83
- * ★ Drizzle 类型安全 SELECT
84
- */
79
+ /** 根据结果查询 */
85
80
  findByResult(result: string, limit?: number): {
86
81
  id: string;
87
82
  timestamp: number;
@@ -94,7 +89,7 @@ export declare class AuditStore {
94
89
  errorMessage: string | null;
95
90
  duration: number | null;
96
91
  }[];
97
- /** 获取统计数据 */
92
+ /** 获取统计数据(全 Drizzle) */
98
93
  getStats(timeRange?: string): {
99
94
  timeRange: string;
100
95
  total: number;
@@ -102,14 +97,18 @@ export declare class AuditStore {
102
97
  failure: number;
103
98
  successRate: string;
104
99
  avgDuration: string;
105
- byActor: unknown[];
106
- byAction: unknown[];
100
+ byActor: {
101
+ actor: string;
102
+ count: number;
103
+ }[];
104
+ byAction: {
105
+ action: string;
106
+ count: number;
107
+ }[];
107
108
  };
108
109
  /**
109
110
  * 清理过期审计日志
110
- * Drizzle 类型安全 DELETE
111
- * @param [opts.maxAgeDays=90] 保留天数,超过此天数的记录将被删除
112
- * @returns }
111
+ * @param [opts.maxAgeDays=90] 保留天数
113
112
  */
114
113
  cleanup({ maxAgeDays }?: {
115
114
  maxAgeDays?: number | undefined;
@@ -1,18 +1,13 @@
1
- /** AuditStore - 审计日志存储 */
2
- import { desc, eq, sql } from 'drizzle-orm';
1
+ /** AuditStore - 审计日志存储(全 Drizzle 类型安全) */
2
+ import { and, avg, count, desc, eq, gte, lte, sql } from 'drizzle-orm';
3
3
  import { getDrizzle } from '../database/drizzle/index.js';
4
4
  import { auditLogs } from '../database/drizzle/schema.js';
5
5
  export class AuditStore {
6
- db;
7
6
  #drizzle;
8
7
  constructor(db, drizzle) {
9
- this.db = db.getDb();
10
8
  this.#drizzle = drizzle ?? getDrizzle();
11
9
  }
12
- /**
13
- * 保存审计日志
14
- * ★ Drizzle 类型安全 INSERT
15
- */
10
+ /** 保存审计日志 */
16
11
  async save(entry) {
17
12
  this.#drizzle
18
13
  .insert(auditLogs)
@@ -30,49 +25,40 @@ export class AuditStore {
30
25
  })
31
26
  .run();
32
27
  }
33
- /** 查询审计日志 */
28
+ /** 查询审计日志(动态多条件,全 Drizzle) */
34
29
  query(filters = {}) {
35
- let sql = 'SELECT * FROM audit_logs WHERE 1=1';
36
- const params = [];
30
+ const conditions = [];
37
31
  if (filters.actor) {
38
- sql += ' AND actor = ?';
39
- params.push(filters.actor);
32
+ conditions.push(eq(auditLogs.actor, filters.actor));
40
33
  }
41
34
  if (filters.action) {
42
- sql += ' AND action = ?';
43
- params.push(filters.action);
35
+ conditions.push(eq(auditLogs.action, filters.action));
44
36
  }
45
37
  if (filters.result) {
46
- sql += ' AND result = ?';
47
- params.push(filters.result);
38
+ conditions.push(eq(auditLogs.result, filters.result));
48
39
  }
49
40
  if (filters.startDate) {
50
- sql += ' AND timestamp >= ?';
51
- params.push(filters.startDate);
41
+ conditions.push(gte(auditLogs.timestamp, filters.startDate));
52
42
  }
53
43
  if (filters.endDate) {
54
- sql += ' AND timestamp <= ?';
55
- params.push(filters.endDate);
44
+ conditions.push(lte(auditLogs.timestamp, filters.endDate));
56
45
  }
57
- sql += ' ORDER BY timestamp DESC';
46
+ const condition = conditions.length > 0 ? and(...conditions) : undefined;
47
+ let query = this.#drizzle
48
+ .select()
49
+ .from(auditLogs)
50
+ .where(condition)
51
+ .orderBy(desc(auditLogs.timestamp));
58
52
  if (filters.limit) {
59
- sql += ' LIMIT ?';
60
- params.push(filters.limit);
53
+ query = query.limit(filters.limit);
61
54
  }
62
- const stmt = this.db.prepare(sql);
63
- return stmt.all(...params);
55
+ return query.all();
64
56
  }
65
- /**
66
- * 根据请求 ID 查询
67
- * ★ Drizzle 类型安全 SELECT
68
- */
57
+ /** 根据请求 ID 查询 */
69
58
  findByRequestId(requestId) {
70
59
  return this.#drizzle.select().from(auditLogs).where(eq(auditLogs.id, requestId)).get();
71
60
  }
72
- /**
73
- * 根据角色查询
74
- * ★ Drizzle 类型安全 SELECT
75
- */
61
+ /** 根据角色查询 */
76
62
  findByActor(actor, limit = 100) {
77
63
  return this.#drizzle
78
64
  .select()
@@ -82,10 +68,7 @@ export class AuditStore {
82
68
  .limit(limit)
83
69
  .all();
84
70
  }
85
- /**
86
- * 根据操作查询
87
- * ★ Drizzle 类型安全 SELECT
88
- */
71
+ /** 根据操作查询 */
89
72
  findByAction(action, limit = 100) {
90
73
  return this.#drizzle
91
74
  .select()
@@ -95,10 +78,7 @@ export class AuditStore {
95
78
  .limit(limit)
96
79
  .all();
97
80
  }
98
- /**
99
- * 根据结果查询
100
- * ★ Drizzle 类型安全 SELECT
101
- */
81
+ /** 根据结果查询 */
102
82
  findByResult(result, limit = 100) {
103
83
  return this.#drizzle
104
84
  .select()
@@ -108,66 +88,79 @@ export class AuditStore {
108
88
  .limit(limit)
109
89
  .all();
110
90
  }
111
- /** 获取统计数据 */
91
+ /** 获取统计数据(全 Drizzle) */
112
92
  getStats(timeRange = '24h') {
113
- // 计算时间范围
114
93
  const hours = timeRange === '24h' ? 24 : timeRange === '7d' ? 168 : 720; // 30d
115
94
  const startTime = Date.now() - hours * 60 * 60 * 1000;
116
- // 总数统计
117
- const total = this.db
118
- .prepare('SELECT COUNT(*) as count FROM audit_logs WHERE timestamp >= ?')
119
- .get(startTime);
120
- // 成功/失败统计
121
- const successCount = this.db
122
- .prepare("SELECT COUNT(*) as count FROM audit_logs WHERE timestamp >= ? AND result = 'success'")
123
- .get(startTime);
124
- const failureCount = this.db
125
- .prepare("SELECT COUNT(*) as count FROM audit_logs WHERE timestamp >= ? AND result = 'failure'")
126
- .get(startTime);
95
+ const startCondition = gte(auditLogs.timestamp, startTime);
96
+ // 总数
97
+ const [totalRow] = this.#drizzle
98
+ .select({ count: count() })
99
+ .from(auditLogs)
100
+ .where(startCondition)
101
+ .all();
102
+ const total = totalRow?.count ?? 0;
103
+ // 成功数
104
+ const [successRow] = this.#drizzle
105
+ .select({ count: count() })
106
+ .from(auditLogs)
107
+ .where(and(startCondition, eq(auditLogs.result, 'success')))
108
+ .all();
109
+ const successCount = successRow?.count ?? 0;
110
+ // 失败数
111
+ const [failureRow] = this.#drizzle
112
+ .select({ count: count() })
113
+ .from(auditLogs)
114
+ .where(and(startCondition, eq(auditLogs.result, 'failure')))
115
+ .all();
116
+ const failureCount = failureRow?.count ?? 0;
127
117
  // 按角色统计
128
- const byActor = this.db
129
- .prepare(`
130
- SELECT actor, COUNT(*) as count
131
- FROM audit_logs
132
- WHERE timestamp >= ?
133
- GROUP BY actor
134
- ORDER BY count DESC
135
- `)
136
- .all(startTime);
118
+ const byActor = this.#drizzle
119
+ .select({
120
+ actor: auditLogs.actor,
121
+ count: count(),
122
+ })
123
+ .from(auditLogs)
124
+ .where(startCondition)
125
+ .groupBy(auditLogs.actor)
126
+ .orderBy(desc(count()))
127
+ .all();
137
128
  // 按操作统计
138
- const byAction = this.db
139
- .prepare(`
140
- SELECT action, COUNT(*) as count
141
- FROM audit_logs
142
- WHERE timestamp >= ?
143
- GROUP BY action
144
- ORDER BY count DESC
145
- `)
146
- .all(startTime);
129
+ const byAction = this.#drizzle
130
+ .select({
131
+ action: auditLogs.action,
132
+ count: count(),
133
+ })
134
+ .from(auditLogs)
135
+ .where(startCondition)
136
+ .groupBy(auditLogs.action)
137
+ .orderBy(desc(count()))
138
+ .all();
147
139
  // 平均响应时间
148
- const avgDuration = this.db
149
- .prepare(`
150
- SELECT AVG(duration) as avg_duration
151
- FROM audit_logs
152
- WHERE timestamp >= ? AND duration IS NOT NULL
153
- `)
154
- .get(startTime);
140
+ const [avgRow] = this.#drizzle
141
+ .select({
142
+ avg_duration: avg(auditLogs.duration),
143
+ })
144
+ .from(auditLogs)
145
+ .where(and(startCondition, sql `${auditLogs.duration} IS NOT NULL`))
146
+ .all();
147
+ const avgDuration = avgRow?.avg_duration
148
+ ? `${Math.round(Number(avgRow.avg_duration))}ms`
149
+ : 'N/A';
155
150
  return {
156
151
  timeRange,
157
- total: total.count,
158
- success: successCount.count,
159
- failure: failureCount.count,
160
- successRate: total.count > 0 ? `${((successCount.count / total.count) * 100).toFixed(2)}%` : '0%',
161
- avgDuration: avgDuration.avg_duration ? `${Math.round(avgDuration.avg_duration)}ms` : 'N/A',
152
+ total,
153
+ success: successCount,
154
+ failure: failureCount,
155
+ successRate: total > 0 ? `${((successCount / total) * 100).toFixed(2)}%` : '0%',
156
+ avgDuration,
162
157
  byActor,
163
158
  byAction,
164
159
  };
165
160
  }
166
161
  /**
167
162
  * 清理过期审计日志
168
- * Drizzle 类型安全 DELETE
169
- * @param [opts.maxAgeDays=90] 保留天数,超过此天数的记录将被删除
170
- * @returns }
163
+ * @param [opts.maxAgeDays=90] 保留天数
171
164
  */
172
165
  cleanup({ maxAgeDays = 90 } = {}) {
173
166
  try {