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.
- package/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +7 -4
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +4 -17
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.js +8 -4
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -273,7 +273,7 @@ export async function dimensionComplete(ctx, args) {
|
|
|
273
273
|
if (knowledgeGraphService && keyFindings.length > 0) {
|
|
274
274
|
// 将每个 keyFinding 创建为知识图谱中的实体
|
|
275
275
|
for (const finding of keyFindings) {
|
|
276
|
-
knowledgeGraphService.addEdge(dimensionId, 'dimension', finding.substring(0, 80), 'finding', 'discovered_in', { source: 'external-agent-bootstrap', sessionId: session.id });
|
|
276
|
+
await knowledgeGraphService.addEdge(dimensionId, 'dimension', finding.substring(0, 80), 'finding', 'discovered_in', { source: 'external-agent-bootstrap', sessionId: session.id });
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
}
|
|
@@ -351,7 +351,7 @@ export async function dimensionComplete(ctx, args) {
|
|
|
351
351
|
if (panoramaService &&
|
|
352
352
|
typeof panoramaService.rescan === 'function') {
|
|
353
353
|
await panoramaService.rescan();
|
|
354
|
-
const overview = panoramaService.getOverview();
|
|
354
|
+
const overview = await panoramaService.getOverview();
|
|
355
355
|
logger.info(`[DimensionComplete] Panorama refreshed — ${overview.moduleCount} modules, ${overview.gapCount} gaps`);
|
|
356
356
|
}
|
|
357
357
|
}
|
|
@@ -388,7 +388,11 @@ export async function dimensionComplete(ctx, args) {
|
|
|
388
388
|
const db = ctx.container.get?.('database') ?? ctx.container.get?.('db');
|
|
389
389
|
if (db && session.sessionStore) {
|
|
390
390
|
const { PersistentMemory } = await import('#agent/memory/PersistentMemory.js');
|
|
391
|
-
const
|
|
391
|
+
const { MemoryEmbeddingStore } = await import('#agent/memory/MemoryEmbeddingStore.js');
|
|
392
|
+
const semanticMemory = new PersistentMemory(db, {
|
|
393
|
+
logger,
|
|
394
|
+
embeddingStore: new MemoryEmbeddingStore(projectRoot),
|
|
395
|
+
});
|
|
392
396
|
const consolidator = new EpisodicConsolidator(semanticMemory, { logger });
|
|
393
397
|
const result = await consolidator.consolidate(session.sessionStore, {
|
|
394
398
|
bootstrapSession: session.id,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import type { ServiceContainer } from '#inject/ServiceContainer.js';
|
|
16
16
|
import type { EvolveInput } from '#shared/schemas/mcp-tools.js';
|
|
17
17
|
/** MCP handler context */
|
|
18
|
+
/** MCP handler context */
|
|
18
19
|
interface McpContext {
|
|
19
20
|
container: ServiceContainer;
|
|
20
21
|
logger: {
|
|
@@ -46,15 +46,12 @@ export async function evolveExternal(ctx, args) {
|
|
|
46
46
|
const proposalRepo = ctx.container.get('proposalRepository');
|
|
47
47
|
const knowledgeService = ctx.container.get('knowledgeService');
|
|
48
48
|
const supervisor = ctx.container.get('lifecycleSupervisor');
|
|
49
|
-
const
|
|
50
|
-
const rawDb = dbConn?.db ?? null;
|
|
49
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
51
50
|
for (const decision of decisions) {
|
|
52
51
|
try {
|
|
53
52
|
// O4: Recipe 存在性前置检查
|
|
54
|
-
if (
|
|
55
|
-
const exists =
|
|
56
|
-
.prepare('SELECT 1 FROM knowledge_entries WHERE id = ?')
|
|
57
|
-
.get(decision.recipeId);
|
|
53
|
+
if (knowledgeRepo) {
|
|
54
|
+
const exists = await knowledgeRepo.findById(decision.recipeId);
|
|
58
55
|
if (!exists) {
|
|
59
56
|
result.errors.push({ recipeId: decision.recipeId, error: 'Recipe not found' });
|
|
60
57
|
result.processed++;
|
|
@@ -111,7 +108,7 @@ export async function evolveExternal(ctx, args) {
|
|
|
111
108
|
// O1: 优先通过 RecipeLifecycleSupervisor 执行,回退到 KnowledgeService
|
|
112
109
|
const reason = decision.reason || 'IDE Agent confirmed deprecation';
|
|
113
110
|
if (supervisor) {
|
|
114
|
-
const transResult = supervisor.transition({
|
|
111
|
+
const transResult = await supervisor.transition({
|
|
115
112
|
recipeId: decision.recipeId,
|
|
116
113
|
targetState: 'deprecated',
|
|
117
114
|
trigger: 'manual-deprecation',
|
|
@@ -167,17 +164,17 @@ export async function evolveExternal(ctx, args) {
|
|
|
167
164
|
break;
|
|
168
165
|
}
|
|
169
166
|
case 'skip': {
|
|
170
|
-
if (decision.skipReason === 'still_valid' &&
|
|
167
|
+
if (decision.skipReason === 'still_valid' && knowledgeRepo) {
|
|
171
168
|
// P4: 更新 stats.lastVerifiedAt 而非 updated_at
|
|
172
169
|
try {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
.
|
|
180
|
-
|
|
170
|
+
const entry = await knowledgeRepo.findById(decision.recipeId);
|
|
171
|
+
if (entry) {
|
|
172
|
+
const stats = (typeof entry.stats === 'object'
|
|
173
|
+
? entry.stats
|
|
174
|
+
: {});
|
|
175
|
+
stats.lastVerifiedAt = Date.now();
|
|
176
|
+
await knowledgeRepo.updateStats(decision.recipeId, stats);
|
|
177
|
+
}
|
|
181
178
|
result.refreshed++;
|
|
182
179
|
}
|
|
183
180
|
catch {
|
|
@@ -211,7 +211,7 @@ export async function guardReview(ctx, args) {
|
|
|
211
211
|
});
|
|
212
212
|
}
|
|
213
213
|
// 2. 预加载 rule recipe 缓存
|
|
214
|
-
const recipeMap = _loadRuleRecipes(ctx);
|
|
214
|
+
const recipeMap = await _loadRuleRecipes(ctx);
|
|
215
215
|
// 3. 创建引擎,注入 Enhancement Pack
|
|
216
216
|
const engine = _getOrCreateEngine(ctx, GuardCheckEngine);
|
|
217
217
|
await _injectEnhancementGuardRules(engine, ctx);
|
|
@@ -355,24 +355,17 @@ export async function guardReview(ctx, args) {
|
|
|
355
355
|
* 预加载所有 rule 类型 recipe 的修复字段
|
|
356
356
|
* 构建 guardId → recipe 映射
|
|
357
357
|
*/
|
|
358
|
-
function _loadRuleRecipes(ctx) {
|
|
358
|
+
async function _loadRuleRecipes(ctx) {
|
|
359
359
|
const map = new Map();
|
|
360
360
|
try {
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const rows = db
|
|
365
|
-
.prepare(`
|
|
366
|
-
SELECT id, title, doClause, dontClause, coreCode, constraints
|
|
367
|
-
FROM knowledge_entries
|
|
368
|
-
WHERE (kind = 'rule' OR knowledgeType = 'boundary-constraint')
|
|
369
|
-
AND lifecycle = 'active'
|
|
370
|
-
`)
|
|
371
|
-
.all();
|
|
372
|
-
for (const row of rows) {
|
|
361
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
362
|
+
const entries = await knowledgeRepo.findActiveGuardRecipes();
|
|
363
|
+
for (const row of entries) {
|
|
373
364
|
try {
|
|
374
|
-
const constraints =
|
|
375
|
-
|
|
365
|
+
const constraints = typeof row.constraints === 'object' && row.constraints
|
|
366
|
+
? row.constraints
|
|
367
|
+
: JSON.parse(row.constraints || '{}');
|
|
368
|
+
const guards = (constraints.guards || []);
|
|
376
369
|
for (const g of guards) {
|
|
377
370
|
if (g.id) {
|
|
378
371
|
map.set(g.id, {
|
|
@@ -675,8 +668,7 @@ export async function guardReverseAudit(ctx, args) {
|
|
|
675
668
|
reverseGuard = ctx.container.get('reverseGuard');
|
|
676
669
|
}
|
|
677
670
|
catch {
|
|
678
|
-
|
|
679
|
-
reverseGuard = new ReverseGuard(db.getDb());
|
|
671
|
+
reverseGuard = new ReverseGuard(ctx.container.get('knowledgeRepository'), ctx.container.get('codeEntityRepository'), ctx.container.get('recipeSourceRefRepository'));
|
|
680
672
|
}
|
|
681
673
|
const maxFiles = args.maxFiles || 200;
|
|
682
674
|
const projectFiles = await collectSourceFilesWithContent(projectRoot, { maxFiles });
|
|
@@ -717,8 +709,7 @@ export async function guardCoverageMatrix(ctx, _args) {
|
|
|
717
709
|
analyzer = ctx.container.get('coverageAnalyzer');
|
|
718
710
|
}
|
|
719
711
|
catch {
|
|
720
|
-
|
|
721
|
-
analyzer = new CoverageAnalyzer(db.getDb());
|
|
712
|
+
analyzer = new CoverageAnalyzer(ctx.container.get('knowledgeRepository'), ctx.container.get('guardViolationRepository'));
|
|
722
713
|
}
|
|
723
714
|
// 构建 moduleFiles 映射 — 从 Panorama 或目录结构推断
|
|
724
715
|
const moduleFiles = await _buildModuleFiles(ctx, projectRoot);
|
|
@@ -798,11 +789,11 @@ async function _buildModuleFiles(ctx, projectRoot) {
|
|
|
798
789
|
const moduleFiles = new Map();
|
|
799
790
|
try {
|
|
800
791
|
const panorama = ctx.container.get('panoramaService');
|
|
801
|
-
const
|
|
802
|
-
if (
|
|
803
|
-
for (const mod of
|
|
792
|
+
const result = await panorama.getResult();
|
|
793
|
+
if (result?.modules) {
|
|
794
|
+
for (const [name, mod] of result.modules) {
|
|
804
795
|
if (mod.files?.length > 0) {
|
|
805
|
-
moduleFiles.set(
|
|
796
|
+
moduleFiles.set(name, mod.files);
|
|
806
797
|
}
|
|
807
798
|
}
|
|
808
799
|
}
|
|
@@ -31,7 +31,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
31
31
|
await panoramaService.ensureData();
|
|
32
32
|
switch (op) {
|
|
33
33
|
case 'overview': {
|
|
34
|
-
const overview = panoramaService.getOverview();
|
|
34
|
+
const overview = await panoramaService.getOverview();
|
|
35
35
|
return envelope({
|
|
36
36
|
success: true,
|
|
37
37
|
data: overview,
|
|
@@ -47,7 +47,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
47
47
|
meta: { tool: 'autosnippet_panorama' },
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
const detail = panoramaService.getModule(moduleName);
|
|
50
|
+
const detail = await panoramaService.getModule(moduleName);
|
|
51
51
|
if (!detail) {
|
|
52
52
|
return envelope({
|
|
53
53
|
success: false,
|
|
@@ -62,7 +62,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
case 'gaps': {
|
|
65
|
-
const gaps = panoramaService.getGaps();
|
|
65
|
+
const gaps = await panoramaService.getGaps();
|
|
66
66
|
return envelope({
|
|
67
67
|
success: true,
|
|
68
68
|
data: { gaps },
|
|
@@ -70,7 +70,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
case 'health': {
|
|
73
|
-
const health = panoramaService.getHealth();
|
|
73
|
+
const health = await panoramaService.getHealth();
|
|
74
74
|
return envelope({
|
|
75
75
|
success: true,
|
|
76
76
|
data: health,
|
|
@@ -94,7 +94,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
94
94
|
meta: { tool: 'autosnippet_panorama' },
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
-
const report = metabolism.runFullCycle();
|
|
97
|
+
const report = await metabolism.runFullCycle();
|
|
98
98
|
return envelope({
|
|
99
99
|
success: true,
|
|
100
100
|
data: report,
|
|
@@ -110,7 +110,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
110
110
|
meta: { tool: 'autosnippet_panorama' },
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
const results = decayDetector.scanAll();
|
|
113
|
+
const results = await decayDetector.scanAll();
|
|
114
114
|
return envelope({
|
|
115
115
|
success: true,
|
|
116
116
|
data: { results },
|
|
@@ -126,8 +126,8 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
126
126
|
meta: { tool: 'autosnippet_panorama' },
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
|
-
const checkResult = stagingManager.checkAndPromote();
|
|
130
|
-
const currentStaging = stagingManager.listStaging();
|
|
129
|
+
const checkResult = await stagingManager.checkAndPromote();
|
|
130
|
+
const currentStaging = await stagingManager.listStaging();
|
|
131
131
|
return envelope({
|
|
132
132
|
success: true,
|
|
133
133
|
data: { checkResult, currentStaging },
|
|
@@ -143,7 +143,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
143
143
|
meta: { tool: 'autosnippet_panorama' },
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
const suggestions = suggester.analyzeAll();
|
|
146
|
+
const suggestions = await suggester.analyzeAll();
|
|
147
147
|
return envelope({
|
|
148
148
|
success: true,
|
|
149
149
|
data: { suggestions },
|
|
@@ -65,10 +65,7 @@ export async function rescanExternal(ctx, args) {
|
|
|
65
65
|
? ctx.container.get('knowledgeSyncService')
|
|
66
66
|
: null;
|
|
67
67
|
if (syncService) {
|
|
68
|
-
const
|
|
69
|
-
? db.getDb()
|
|
70
|
-
: db;
|
|
71
|
-
const syncReport = syncService.sync(rawDb, {
|
|
68
|
+
const syncReport = syncService.sync(db, {
|
|
72
69
|
force: true,
|
|
73
70
|
});
|
|
74
71
|
ctx.logger.info('[Rescan] KnowledgeSyncService sync complete', {
|
|
@@ -117,7 +114,11 @@ export async function rescanExternal(ctx, args) {
|
|
|
117
114
|
// Step 4: Recipe 证据验证 + 快速衰退
|
|
118
115
|
// ═══════════════════════════════════════════════════════════
|
|
119
116
|
const auditor = new RecipeRelevanceAuditor({
|
|
120
|
-
|
|
117
|
+
knowledgeRepo: ctx.container.get('knowledgeRepository'),
|
|
118
|
+
proposalRepo: ctx.container.singletons
|
|
119
|
+
?.proposalRepository
|
|
120
|
+
? ctx.container.get('proposalRepository')
|
|
121
|
+
: undefined,
|
|
121
122
|
logger: ctx.logger,
|
|
122
123
|
});
|
|
123
124
|
const codeEntities = extractCodeEntities(astProjectSummary);
|
|
@@ -132,7 +133,7 @@ export async function rescanExternal(ctx, args) {
|
|
|
132
133
|
// ═══════════════════════════════════════════════════════════
|
|
133
134
|
// 按需过滤维度
|
|
134
135
|
const dimensions = args.dimensions?.length
|
|
135
|
-
? allDimensions.filter((d) => args.dimensions
|
|
136
|
+
? allDimensions.filter((d) => args.dimensions?.includes(d.id))
|
|
136
137
|
: allDimensions;
|
|
137
138
|
// 创建 Session
|
|
138
139
|
const sessionManager = getOrCreateSessionManager(ctx.container);
|
|
@@ -71,10 +71,7 @@ export async function rescanInternal(ctx, args) {
|
|
|
71
71
|
/* not registered */
|
|
72
72
|
}
|
|
73
73
|
if (syncService) {
|
|
74
|
-
const
|
|
75
|
-
? db.getDb()
|
|
76
|
-
: db;
|
|
77
|
-
const syncReport = syncService.sync(rawDb, {
|
|
74
|
+
const syncReport = syncService.sync(db, {
|
|
78
75
|
force: true,
|
|
79
76
|
});
|
|
80
77
|
ctx.logger.info('[Rescan-Internal] KnowledgeSyncService sync complete', {
|
|
@@ -119,7 +116,14 @@ export async function rescanInternal(ctx, args) {
|
|
|
119
116
|
// ═══════════════════════════════════════════════════════════
|
|
120
117
|
// Step 4: Recipe 证据验证 + 快速衰退
|
|
121
118
|
// ═══════════════════════════════════════════════════════════
|
|
122
|
-
const auditor = new RecipeRelevanceAuditor({
|
|
119
|
+
const auditor = new RecipeRelevanceAuditor({
|
|
120
|
+
knowledgeRepo: ctx.container.get('knowledgeRepository'),
|
|
121
|
+
proposalRepo: ctx.container.singletons
|
|
122
|
+
?.proposalRepository
|
|
123
|
+
? ctx.container.get('proposalRepository')
|
|
124
|
+
: undefined,
|
|
125
|
+
logger: ctx.logger,
|
|
126
|
+
});
|
|
123
127
|
const codeEntities = extractCodeEntities(astProjectSummary);
|
|
124
128
|
const dependencyEdges = extractDependencyEdges(depGraphData);
|
|
125
129
|
const auditSummary = await auditor.audit(recipeSnapshot.entries, {
|
|
@@ -30,7 +30,9 @@ function getSearchEngine(ctx) {
|
|
|
30
30
|
async function getFallbackEngine(ctx) {
|
|
31
31
|
const { SearchEngine } = await import('#service/search/SearchEngine.js');
|
|
32
32
|
const db = ctx.container.get('database');
|
|
33
|
-
|
|
33
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
34
|
+
const sourceRefRepo = ctx.container.get('recipeSourceRefRepository');
|
|
35
|
+
return new SearchEngine(db, { knowledgeRepo, sourceRefRepo });
|
|
34
36
|
}
|
|
35
37
|
/** 根据 kind 参数过滤 items */
|
|
36
38
|
function filterByKind(items, kind) {
|
|
@@ -648,11 +648,11 @@ export async function suggestSkills(ctx) {
|
|
|
648
648
|
}
|
|
649
649
|
// ── Fallback: 直接使用 SkillAdvisor ──
|
|
650
650
|
const { SkillAdvisor } = await import('#service/skills/SkillAdvisor.js');
|
|
651
|
-
const dbConn = ctx?.container?.get?.('database') || null;
|
|
652
|
-
const database = dbConn?.getDb?.() || dbConn || null;
|
|
653
651
|
const projectRoot = resolveProjectRoot(ctx?.container);
|
|
654
|
-
const
|
|
655
|
-
const
|
|
652
|
+
const knowledgeRepo = ctx?.container?.get?.('knowledgeRepository') || null;
|
|
653
|
+
const auditRepo = ctx?.container?.get?.('auditRepository') || null;
|
|
654
|
+
const advisor = new SkillAdvisor(projectRoot, { knowledgeRepo, auditRepo });
|
|
655
|
+
const result = await advisor.suggest();
|
|
656
656
|
return JSON.stringify({
|
|
657
657
|
success: true,
|
|
658
658
|
data: result,
|
|
@@ -236,7 +236,7 @@ export async function getTargetMetadata(ctx, args) {
|
|
|
236
236
|
try {
|
|
237
237
|
const graphService = ctx.container?.get('knowledgeGraphService');
|
|
238
238
|
if (graphService) {
|
|
239
|
-
const edges = graphService.getEdges(target.name, 'module', 'both');
|
|
239
|
+
const edges = await graphService.getEdges(target.name, 'module', 'both');
|
|
240
240
|
meta.graphEdges = {
|
|
241
241
|
outgoing: (edges.outgoing || []).map((e) => ({
|
|
242
242
|
toId: e.toId,
|
|
@@ -270,10 +270,10 @@ export async function graphQuery(ctx, args) {
|
|
|
270
270
|
let data;
|
|
271
271
|
try {
|
|
272
272
|
if (args.relation) {
|
|
273
|
-
data = graphService.getRelated(args.nodeId, nodeType, args.relation);
|
|
273
|
+
data = await graphService.getRelated(args.nodeId, nodeType, args.relation);
|
|
274
274
|
}
|
|
275
275
|
else {
|
|
276
|
-
data = graphService.getEdges(args.nodeId, nodeType, direction);
|
|
276
|
+
data = await graphService.getEdges(args.nodeId, nodeType, direction);
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
catch (err) {
|
|
@@ -302,7 +302,7 @@ export async function graphImpact(ctx, args) {
|
|
|
302
302
|
const nodeType = args.nodeType || 'recipe';
|
|
303
303
|
let impacted;
|
|
304
304
|
try {
|
|
305
|
-
impacted = graphService.getImpactAnalysis(args.nodeId, nodeType, args.maxDepth ?? 3);
|
|
305
|
+
impacted = await graphService.getImpactAnalysis(args.nodeId, nodeType, args.maxDepth ?? 3);
|
|
306
306
|
}
|
|
307
307
|
catch (err) {
|
|
308
308
|
// knowledge_edges 表不存在时 graceful 降级
|
|
@@ -360,9 +360,7 @@ async function _fallbackRelationsFromRecipe(ctx, nodeId, relation, direction) {
|
|
|
360
360
|
const incoming = [];
|
|
361
361
|
if (direction === 'both' || direction === 'in') {
|
|
362
362
|
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
363
|
-
const reverseRows = knowledgeRepo.
|
|
364
|
-
.prepare(`SELECT id, relations FROM knowledge_entries WHERE relations LIKE ? AND id != ?`)
|
|
365
|
-
.all(`%${nodeId}%`, nodeId);
|
|
363
|
+
const reverseRows = await knowledgeRepo.findByRelationLike(nodeId, nodeId);
|
|
366
364
|
for (const row of reverseRows) {
|
|
367
365
|
try {
|
|
368
366
|
const rels = JSON.parse(row.relations || '{}');
|
|
@@ -399,9 +397,7 @@ async function _fallbackRelationsFromRecipe(ctx, nodeId, relation, direction) {
|
|
|
399
397
|
async function _fallbackImpactFromRecipe(ctx, nodeId) {
|
|
400
398
|
try {
|
|
401
399
|
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
402
|
-
const rows = knowledgeRepo.
|
|
403
|
-
.prepare(`SELECT id, title, relations FROM knowledge_entries WHERE relations LIKE ? AND id != ?`)
|
|
404
|
-
.all(`%${nodeId}%`, nodeId);
|
|
400
|
+
const rows = await knowledgeRepo.findByRelationLike(nodeId, nodeId);
|
|
405
401
|
const impacted = [];
|
|
406
402
|
for (const row of rows) {
|
|
407
403
|
try {
|
|
@@ -448,7 +444,7 @@ export async function graphPath(ctx, args) {
|
|
|
448
444
|
const maxDepth = Math.min(Math.max(args.maxDepth ?? 5, 1), 10);
|
|
449
445
|
let result;
|
|
450
446
|
try {
|
|
451
|
-
result = graphService.findPath(args.fromId, fromType, args.toId, toType, maxDepth);
|
|
447
|
+
result = await graphService.findPath(args.fromId, fromType, args.toId, toType, maxDepth);
|
|
452
448
|
}
|
|
453
449
|
catch (err) {
|
|
454
450
|
if (err instanceof Error && err.message?.includes('no such table')) {
|
|
@@ -568,7 +564,7 @@ export async function graphStats(ctx) {
|
|
|
568
564
|
}
|
|
569
565
|
let stats;
|
|
570
566
|
try {
|
|
571
|
-
stats = graphService.getStats();
|
|
567
|
+
stats = await graphService.getStats();
|
|
572
568
|
}
|
|
573
569
|
catch (err) {
|
|
574
570
|
if (err instanceof Error && err.message?.includes('no such table')) {
|
|
@@ -22,46 +22,22 @@ export async function health(ctx) {
|
|
|
22
22
|
}
|
|
23
23
|
// 2) Database 连通性 + 知识库统计
|
|
24
24
|
try {
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
const db = typeof dbConn.getDb === 'function' ? dbConn.getDb() : dbConn;
|
|
29
|
-
db.prepare('SELECT 1').get();
|
|
25
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
26
|
+
if (knowledgeRepo) {
|
|
27
|
+
const stats = (await knowledgeRepo.getStats());
|
|
30
28
|
checks.database = true;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
// V3: knowledge_entries 统一表(lifecycle 替代 status)
|
|
34
|
-
const rStats = db
|
|
35
|
-
.prepare(`
|
|
36
|
-
SELECT COUNT(*) as total,
|
|
37
|
-
SUM(CASE WHEN lifecycle='active' THEN 1 ELSE 0 END) as active,
|
|
38
|
-
SUM(CASE WHEN kind='rule' THEN 1 ELSE 0 END) as rules,
|
|
39
|
-
SUM(CASE WHEN kind='pattern' THEN 1 ELSE 0 END) as patterns,
|
|
40
|
-
SUM(CASE WHEN kind='fact' THEN 1 ELSE 0 END) as facts
|
|
41
|
-
FROM knowledge_entries
|
|
42
|
-
`)
|
|
43
|
-
.get();
|
|
44
|
-
const cPending = db
|
|
45
|
-
.prepare(`
|
|
46
|
-
SELECT COUNT(*) as total,
|
|
47
|
-
SUM(CASE WHEN lifecycle='pending' THEN 1 ELSE 0 END) as pending
|
|
48
|
-
FROM knowledge_entries
|
|
49
|
-
`)
|
|
50
|
-
.get();
|
|
29
|
+
if (stats) {
|
|
51
30
|
knowledgeBase = {
|
|
52
31
|
recipes: {
|
|
53
|
-
total:
|
|
54
|
-
active:
|
|
55
|
-
rules:
|
|
56
|
-
patterns:
|
|
57
|
-
facts:
|
|
32
|
+
total: stats.total,
|
|
33
|
+
active: stats.active,
|
|
34
|
+
rules: stats.rules,
|
|
35
|
+
patterns: stats.patterns,
|
|
36
|
+
facts: stats.facts,
|
|
58
37
|
},
|
|
59
|
-
candidates: { total:
|
|
38
|
+
candidates: { total: stats.total, pending: stats.pending },
|
|
60
39
|
};
|
|
61
40
|
}
|
|
62
|
-
catch {
|
|
63
|
-
/* 统计查询失败不影响 health */
|
|
64
|
-
}
|
|
65
41
|
}
|
|
66
42
|
}
|
|
67
43
|
catch (e) {
|
|
@@ -135,33 +135,31 @@ router.post('/config', validate(AiConfigBody), async (req, res) => {
|
|
|
135
135
|
router.post('/mock/cleanup', async (_req, res) => {
|
|
136
136
|
const container = getContainer();
|
|
137
137
|
const knowledgeService = container.get('knowledgeService');
|
|
138
|
-
const
|
|
139
|
-
const rawDb = dbConn.getDb();
|
|
138
|
+
const knowledgeRepo = container.get('knowledgeRepository');
|
|
140
139
|
// 查找所有 mock 来源的候选
|
|
141
140
|
const mockSources = ['mock-bootstrap', 'mock-pipeline'];
|
|
142
141
|
let totalDeleted = 0;
|
|
143
142
|
for (const source of mockSources) {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
.all(source);
|
|
147
|
-
for (const row of rows) {
|
|
143
|
+
const ids = await knowledgeRepo.findIdsBySource(source);
|
|
144
|
+
for (const id of ids) {
|
|
148
145
|
try {
|
|
149
|
-
await knowledgeService.delete(
|
|
146
|
+
await knowledgeService.delete(id, { userId: 'system:mock-cleanup' });
|
|
150
147
|
totalDeleted++;
|
|
151
148
|
}
|
|
152
149
|
catch {
|
|
153
|
-
logger.debug(`Mock cleanup: failed to delete ${
|
|
150
|
+
logger.debug(`Mock cleanup: failed to delete ${id}`);
|
|
154
151
|
}
|
|
155
152
|
}
|
|
156
153
|
}
|
|
157
|
-
// 清理
|
|
154
|
+
// 清理 bootstrap 来源的 semantic_memories
|
|
158
155
|
try {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
.
|
|
156
|
+
const memoryRepo = container.get('memoryRepository');
|
|
157
|
+
if (memoryRepo) {
|
|
158
|
+
await memoryRepo.clearBootstrapMemories();
|
|
159
|
+
}
|
|
162
160
|
}
|
|
163
161
|
catch {
|
|
164
|
-
//
|
|
162
|
+
// memoryRepository 可能未注册
|
|
165
163
|
}
|
|
166
164
|
logger.info(`Mock cleanup completed: ${totalDeleted} entries deleted`);
|
|
167
165
|
const rt = getRealtimeService();
|
|
@@ -67,8 +67,7 @@ router.get('/reverse', async (req, res) => {
|
|
|
67
67
|
reverseGuard = container.get('reverseGuard');
|
|
68
68
|
}
|
|
69
69
|
catch {
|
|
70
|
-
|
|
71
|
-
reverseGuard = new ReverseGuard(db.getDb());
|
|
70
|
+
reverseGuard = new ReverseGuard(container.get('knowledgeRepository'), container.get('codeEntityRepository'), container.get('recipeSourceRefRepository'));
|
|
72
71
|
}
|
|
73
72
|
const maxFiles = req.query.maxFiles ? Number(req.query.maxFiles) : 200;
|
|
74
73
|
const projectFiles = await collectSourceFilesWithContent(projectRoot, { maxFiles });
|
|
@@ -111,14 +110,13 @@ router.get('/coverage', async (_req, res) => {
|
|
|
111
110
|
analyzer = container.get('coverageAnalyzer');
|
|
112
111
|
}
|
|
113
112
|
catch {
|
|
114
|
-
|
|
115
|
-
analyzer = new CoverageAnalyzer(db.getDb());
|
|
113
|
+
analyzer = new CoverageAnalyzer(container.get('knowledgeRepository'), container.get('guardViolationRepository'));
|
|
116
114
|
}
|
|
117
115
|
// 从 Panorama 或目录结构获取模块文件
|
|
118
116
|
const moduleFiles = new Map();
|
|
119
117
|
try {
|
|
120
118
|
const panorama = container.get('panoramaService');
|
|
121
|
-
const overview = panorama.getOverview();
|
|
119
|
+
const overview = await panorama.getOverview();
|
|
122
120
|
if (overview?.modules) {
|
|
123
121
|
for (const mod of overview.modules) {
|
|
124
122
|
if (mod.files?.length > 0) {
|
|
@@ -31,7 +31,7 @@ router.get('/', async (req, res) => {
|
|
|
31
31
|
if (typeof panoramaService.ensureData === 'function') {
|
|
32
32
|
await panoramaService.ensureData();
|
|
33
33
|
}
|
|
34
|
-
const overview = panoramaService.getOverview();
|
|
34
|
+
const overview = await panoramaService.getOverview();
|
|
35
35
|
res.json({ success: true, data: overview });
|
|
36
36
|
}
|
|
37
37
|
catch (err) {
|
|
@@ -62,7 +62,7 @@ router.get('/health', async (req, res) => {
|
|
|
62
62
|
if (typeof panoramaService.ensureData === 'function') {
|
|
63
63
|
await panoramaService.ensureData();
|
|
64
64
|
}
|
|
65
|
-
const health = panoramaService.getHealth();
|
|
65
|
+
const health = await panoramaService.getHealth();
|
|
66
66
|
res.json({ success: true, data: health });
|
|
67
67
|
}
|
|
68
68
|
catch (err) {
|
|
@@ -93,7 +93,7 @@ router.get('/gaps', async (req, res) => {
|
|
|
93
93
|
if (typeof panoramaService.ensureData === 'function') {
|
|
94
94
|
await panoramaService.ensureData();
|
|
95
95
|
}
|
|
96
|
-
const gaps = panoramaService.getGaps();
|
|
96
|
+
const gaps = await panoramaService.getGaps();
|
|
97
97
|
res.json({ success: true, data: gaps });
|
|
98
98
|
}
|
|
99
99
|
catch (err) {
|
|
@@ -124,8 +124,8 @@ router.get('/coverage', async (req, res) => {
|
|
|
124
124
|
if (typeof panoramaService.ensureData === 'function') {
|
|
125
125
|
await panoramaService.ensureData();
|
|
126
126
|
}
|
|
127
|
-
const overview = panoramaService.getOverview();
|
|
128
|
-
const gaps = panoramaService.getGaps?.() ?? [];
|
|
127
|
+
const overview = await panoramaService.getOverview();
|
|
128
|
+
const gaps = (await panoramaService.getGaps?.()) ?? [];
|
|
129
129
|
// 构建模块级覆盖率数据:从 overview.layers 中提取每个模块的文件数和 recipe 数
|
|
130
130
|
const modules = [];
|
|
131
131
|
for (const layer of overview.layers || []) {
|
|
@@ -187,7 +187,7 @@ router.get('/module/:name', async (req, res) => {
|
|
|
187
187
|
if (typeof panoramaService.ensureData === 'function') {
|
|
188
188
|
await panoramaService.ensureData();
|
|
189
189
|
}
|
|
190
|
-
const detail = panoramaService.getModule(req.params.name);
|
|
190
|
+
const detail = await panoramaService.getModule(req.params.name);
|
|
191
191
|
if (!detail) {
|
|
192
192
|
res.status(404).json({
|
|
193
193
|
success: false,
|
|
@@ -220,7 +220,7 @@ router.post('/governance/cycle', async (_req, res) => {
|
|
|
220
220
|
});
|
|
221
221
|
return;
|
|
222
222
|
}
|
|
223
|
-
const report = metabolism.runFullCycle();
|
|
223
|
+
const report = await metabolism.runFullCycle();
|
|
224
224
|
res.json({ success: true, data: report });
|
|
225
225
|
}
|
|
226
226
|
catch (err) {
|
|
@@ -245,7 +245,7 @@ router.get('/governance/decay', async (_req, res) => {
|
|
|
245
245
|
});
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
248
|
-
const results = decayDetector.scanAll();
|
|
248
|
+
const results = await decayDetector.scanAll();
|
|
249
249
|
res.json({ success: true, data: { results } });
|
|
250
250
|
}
|
|
251
251
|
catch (err) {
|
|
@@ -270,8 +270,8 @@ router.post('/governance/staging-check', async (_req, res) => {
|
|
|
270
270
|
});
|
|
271
271
|
return;
|
|
272
272
|
}
|
|
273
|
-
const checkResult = stagingManager.checkAndPromote();
|
|
274
|
-
const currentStaging = stagingManager.listStaging();
|
|
273
|
+
const checkResult = await stagingManager.checkAndPromote();
|
|
274
|
+
const currentStaging = await stagingManager.listStaging();
|
|
275
275
|
res.json({ success: true, data: { checkResult, currentStaging } });
|
|
276
276
|
}
|
|
277
277
|
catch (err) {
|
|
@@ -296,7 +296,7 @@ router.get('/governance/staging', async (_req, res) => {
|
|
|
296
296
|
});
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
299
|
-
const entries = stagingManager.listStaging();
|
|
299
|
+
const entries = await stagingManager.listStaging();
|
|
300
300
|
res.json({ success: true, data: { entries } });
|
|
301
301
|
}
|
|
302
302
|
catch (err) {
|
|
@@ -321,7 +321,7 @@ router.get('/governance/enhancements', async (_req, res) => {
|
|
|
321
321
|
});
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
324
|
-
const suggestions = suggester.analyzeAll();
|
|
324
|
+
const suggestions = await suggester.analyzeAll();
|
|
325
325
|
res.json({ success: true, data: { suggestions } });
|
|
326
326
|
}
|
|
327
327
|
catch (err) {
|