autosnippet 3.3.6 → 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 +8 -4
- package/dist/lib/agent/AgentRuntime.d.ts +2 -2
- package/dist/lib/agent/AgentRuntime.js +26 -18
- 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/domain/ChatAgentTasks.js +4 -0
- package/dist/lib/agent/forced-summary.js +7 -2
- 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 +8 -21
- 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/ConfigWatcher.d.ts +64 -0
- package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
- package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
- package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
- package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
- package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
- package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
- package/dist/lib/core/discovery/index.d.ts +2 -0
- package/dist/lib/core/discovery/index.js +4 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
- 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/KnowledgeEntry.d.ts +7 -1
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
- 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/ai/AiProvider.d.ts +12 -0
- package/dist/lib/external/ai/AiProvider.js +24 -0
- package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
- package/dist/lib/external/ai/AiProviderManager.js +193 -0
- package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
- package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
- package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
- package/dist/lib/external/ai/providers/MockProvider.js +290 -14
- package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
- package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
- package/dist/lib/external/lark/LarkTransport.js +10 -2
- 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/mock-pipeline.d.ts +20 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
- package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
- 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.d.ts +9 -0
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
- package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
- 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 +109 -30
- package/dist/lib/http/routes/candidates.js +11 -4
- package/dist/lib/http/routes/commands.js +10 -1
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/health.js +11 -0
- package/dist/lib/http/routes/modules.js +27 -0
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +66 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/http/utils/routeHelpers.js +2 -1
- 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.d.ts +6 -5
- package/dist/lib/injection/ServiceContainer.js +18 -31
- package/dist/lib/injection/ServiceMap.d.ts +22 -0
- package/dist/lib/injection/modules/AiModule.d.ts +6 -9
- package/dist/lib/injection/modules/AiModule.js +82 -39
- 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.d.ts +54 -7
- package/dist/lib/service/cleanup/CleanupService.js +291 -40
- 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 +45 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
- 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 +97 -46
- 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/module/ModuleService.js +10 -19
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
- package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
- package/dist/lib/service/panorama/LayerInferrer.js +118 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
- package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
- package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +49 -69
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
- package/dist/lib/service/panorama/RoleRefiner.js +92 -282
- package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
- package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
- 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 +6 -8
- package/dist/lib/service/skills/SignalCollector.js +34 -60
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
- package/dist/lib/service/vector/ContextualEnricher.js +4 -0
- 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 +19 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/developer-identity.d.ts +18 -0
- package/dist/lib/shared/developer-identity.js +62 -0
- package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
- package/dist/lib/shared/schemas/http-requests.js +9 -6
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/knowledge-wire.d.ts +1 -0
- 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-D1aVZYFW.js +0 -1
- package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
- package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mock-pipeline.ts — Mock AI Bootstrap 轻量管线
|
|
3
|
+
*
|
|
4
|
+
* 当 AI Provider 为 mock 时,利用 Phase 1-4 已收集的真实数据
|
|
5
|
+
* (AST、依赖图、文件列表、Panorama) 为每个维度生成模板化候选知识。
|
|
6
|
+
*
|
|
7
|
+
* 不调用 AI,但走完完整的 submit → dimension_complete 流程,
|
|
8
|
+
* 使 Dashboard 能正常展示知识库、健康雷达等 UI。
|
|
9
|
+
*
|
|
10
|
+
* @module pipeline/mock-pipeline
|
|
11
|
+
*/
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import Logger from '#infra/logging/Logger.js';
|
|
14
|
+
import { BootstrapEventEmitter } from '#service/bootstrap/BootstrapEventEmitter.js';
|
|
15
|
+
const logger = Logger.getInstance();
|
|
16
|
+
// ── 模板生成器 ────────────────────────────────────────────
|
|
17
|
+
/** 从 AST 指标提取代码统计 */
|
|
18
|
+
function extractAstStats(ast) {
|
|
19
|
+
if (!ast) {
|
|
20
|
+
return { classes: 0, protocols: 0, functions: 0 };
|
|
21
|
+
}
|
|
22
|
+
const pm = (ast.projectMetrics ?? ast);
|
|
23
|
+
return {
|
|
24
|
+
classes: pm.totalClasses ?? 0,
|
|
25
|
+
protocols: pm.totalProtocols ?? 0,
|
|
26
|
+
functions: pm.totalFunctions ?? 0,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 从文件列表中按 target 分组并提取代表性文件 */
|
|
30
|
+
function getRepresentativeFiles(files, targetFileMap) {
|
|
31
|
+
const result = new Map();
|
|
32
|
+
if (targetFileMap) {
|
|
33
|
+
for (const [target, paths] of Object.entries(targetFileMap)) {
|
|
34
|
+
result.set(target, paths.slice(0, 5));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (files) {
|
|
38
|
+
const grouped = new Map();
|
|
39
|
+
for (const f of files) {
|
|
40
|
+
const target = f.targetName || 'default';
|
|
41
|
+
const list = grouped.get(target) || [];
|
|
42
|
+
list.push(f.relativePath || f.name);
|
|
43
|
+
grouped.set(target, list);
|
|
44
|
+
}
|
|
45
|
+
for (const [target, paths] of grouped) {
|
|
46
|
+
result.set(target, paths.slice(0, 5));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
/** 从文件内容中提取 import 语句(作为 headers)*/
|
|
52
|
+
function extractImports(content, lang) {
|
|
53
|
+
const imports = [];
|
|
54
|
+
const lines = content.split('\n').slice(0, 30);
|
|
55
|
+
for (const line of lines) {
|
|
56
|
+
const trimmed = line.trim();
|
|
57
|
+
if (lang === 'swift' && trimmed.startsWith('import ')) {
|
|
58
|
+
imports.push(trimmed);
|
|
59
|
+
}
|
|
60
|
+
else if ((lang === 'typescript' || lang === 'javascript') && trimmed.startsWith('import ')) {
|
|
61
|
+
imports.push(trimmed);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return [...new Set(imports)].slice(0, 5);
|
|
65
|
+
}
|
|
66
|
+
/** 从文件内容中提取类/结构体/协议名 */
|
|
67
|
+
function extractTypes(content) {
|
|
68
|
+
const types = [];
|
|
69
|
+
for (const m of content.matchAll(/(?:class|struct|protocol|enum|interface|type)\s+(\w+)/g)) {
|
|
70
|
+
types.push(m[1]);
|
|
71
|
+
}
|
|
72
|
+
return [...new Set(types)].slice(0, 10);
|
|
73
|
+
}
|
|
74
|
+
/** 生成 kebab-case trigger */
|
|
75
|
+
function toKebab(text) {
|
|
76
|
+
return text
|
|
77
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
78
|
+
.replace(/[\s_]+/g, '-')
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/[^a-z0-9-]/g, '')
|
|
81
|
+
.slice(0, 40);
|
|
82
|
+
}
|
|
83
|
+
// ── 维度级候选生成 ────────────────────────────────────────
|
|
84
|
+
/** 为单个维度生成 Mock 候选 */
|
|
85
|
+
function generateDimensionCandidates(dimId, dimLabel, files, lang, projectName, astStats, targetFiles) {
|
|
86
|
+
const candidates = [];
|
|
87
|
+
// 从文件中收集有代表性的类型和源文件
|
|
88
|
+
const allTypes = [];
|
|
89
|
+
const allSources = [];
|
|
90
|
+
const allImports = [];
|
|
91
|
+
const dimFiles = files?.filter((f) => {
|
|
92
|
+
const p = f.relativePath?.toLowerCase() || f.name.toLowerCase();
|
|
93
|
+
// 根据维度 ID 做简单相关性匹配
|
|
94
|
+
switch (dimId) {
|
|
95
|
+
case 'architecture':
|
|
96
|
+
return (p.includes('coordinator') ||
|
|
97
|
+
p.includes('delegate') ||
|
|
98
|
+
p.includes('service') ||
|
|
99
|
+
p.includes('manager'));
|
|
100
|
+
case 'code-pattern':
|
|
101
|
+
return p.includes('extension') || p.includes('helper') || p.includes('util');
|
|
102
|
+
case 'naming-style':
|
|
103
|
+
return true; // 全局适用
|
|
104
|
+
case 'error-handling':
|
|
105
|
+
return p.includes('error') || p.includes('result') || p.includes('handler');
|
|
106
|
+
case 'networking':
|
|
107
|
+
return (p.includes('network') ||
|
|
108
|
+
p.includes('api') ||
|
|
109
|
+
p.includes('request') ||
|
|
110
|
+
p.includes('http'));
|
|
111
|
+
case 'data-model':
|
|
112
|
+
return p.includes('model') || p.includes('entity') || p.includes('dto');
|
|
113
|
+
case 'testing-quality':
|
|
114
|
+
return p.includes('test') || p.includes('spec') || p.includes('mock');
|
|
115
|
+
case 'ui-patterns':
|
|
116
|
+
return (p.includes('view') ||
|
|
117
|
+
p.includes('controller') ||
|
|
118
|
+
p.includes('cell') ||
|
|
119
|
+
p.includes('component'));
|
|
120
|
+
case 'concurrency':
|
|
121
|
+
return (p.includes('actor') ||
|
|
122
|
+
p.includes('async') ||
|
|
123
|
+
p.includes('queue') ||
|
|
124
|
+
p.includes('dispatch'));
|
|
125
|
+
case 'storage':
|
|
126
|
+
return (p.includes('store') ||
|
|
127
|
+
p.includes('cache') ||
|
|
128
|
+
p.includes('database') ||
|
|
129
|
+
p.includes('persist'));
|
|
130
|
+
default:
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}) || [];
|
|
134
|
+
// 提取文件中的类型和导入
|
|
135
|
+
for (const f of dimFiles.slice(0, 10)) {
|
|
136
|
+
allTypes.push(...extractTypes(f.content || ''));
|
|
137
|
+
allSources.push(f.relativePath || f.name);
|
|
138
|
+
allImports.push(...extractImports(f.content || '', lang));
|
|
139
|
+
}
|
|
140
|
+
// 如果没找到相关文件,用全部文件兜底
|
|
141
|
+
if (allTypes.length === 0 && files) {
|
|
142
|
+
for (const f of files.slice(0, 5)) {
|
|
143
|
+
allTypes.push(...extractTypes(f.content || ''));
|
|
144
|
+
allSources.push(f.relativePath || f.name);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const uniqueTypes = [...new Set(allTypes)].slice(0, 8);
|
|
148
|
+
const uniqueSources = [...new Set(allSources)].slice(0, 5);
|
|
149
|
+
const uniqueImports = [...new Set(allImports)].slice(0, 5);
|
|
150
|
+
// 为每个维度生成 3 个候选
|
|
151
|
+
const templates = getDimensionTemplates(dimId, dimLabel, uniqueTypes, uniqueSources, lang, projectName, astStats);
|
|
152
|
+
for (const tpl of templates.slice(0, 3)) {
|
|
153
|
+
candidates.push({
|
|
154
|
+
...tpl,
|
|
155
|
+
headers: uniqueImports,
|
|
156
|
+
sourceRefs: uniqueSources.slice(0, 3),
|
|
157
|
+
reasoning: {
|
|
158
|
+
whyStandard: `基于 ${projectName} 项目 ${dimFiles.length} 个相关文件的代码分析(Mock 模式自动生成)`,
|
|
159
|
+
sources: uniqueSources.slice(0, 3),
|
|
160
|
+
confidence: 0.7,
|
|
161
|
+
},
|
|
162
|
+
tags: ['mock-generated', dimId, lang],
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return candidates;
|
|
166
|
+
}
|
|
167
|
+
/** 根据维度 ID 返回候选模板 */
|
|
168
|
+
function getDimensionTemplates(dimId, dimLabel, types, sources, lang, projectName, ast) {
|
|
169
|
+
const typeList = types.length > 0 ? types.slice(0, 3).join('、') : '核心模块';
|
|
170
|
+
const typeFirst = types[0] || 'AppModule';
|
|
171
|
+
const srcFirst = sources[0] || 'Sources/Main.swift';
|
|
172
|
+
const base = {
|
|
173
|
+
language: lang,
|
|
174
|
+
knowledgeType: dimId,
|
|
175
|
+
};
|
|
176
|
+
switch (dimId) {
|
|
177
|
+
case 'architecture':
|
|
178
|
+
return [
|
|
179
|
+
{
|
|
180
|
+
...base,
|
|
181
|
+
title: `${projectName} 分层架构模式`,
|
|
182
|
+
description: `项目采用分层架构,包含 ${ast.classes} 个类、${ast.protocols} 个协议`,
|
|
183
|
+
trigger: `@${toKebab(projectName)}-layered-arch`,
|
|
184
|
+
kind: 'pattern',
|
|
185
|
+
category: 'Architecture',
|
|
186
|
+
topicHint: 'architecture',
|
|
187
|
+
content: {
|
|
188
|
+
markdown: `### ${projectName} 分层架构\n\n项目基于分层架构设计,核心类型包括 ${typeList}。\n\n**层次结构**:\n- 表现层: View/Controller\n- 业务层: Service/Manager\n- 数据层: Repository/Store\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ 此条目由 Mock AI 基于代码结构自动生成`,
|
|
189
|
+
rationale: `分层架构是 ${projectName} 的核心设计决策,确保模块间关注点分离`,
|
|
190
|
+
},
|
|
191
|
+
coreCode: `// ${lang === 'swift' ? 'protocol' : 'interface'} ${typeFirst}Service { ... }`,
|
|
192
|
+
doClause: `Follow the layered architecture with ${typeFirst} as the core service boundary`,
|
|
193
|
+
dontClause: 'Do not bypass service layer to access data layer directly',
|
|
194
|
+
whenClause: 'When adding new features or modules to the project',
|
|
195
|
+
usageGuide: `### 使用指南\n\n遵循 ${projectName} 的分层架构进行模块设计。`,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
...base,
|
|
199
|
+
title: `${typeFirst} 依赖注入约定`,
|
|
200
|
+
description: `${typeFirst} 等核心类型通过依赖注入管理生命周期`,
|
|
201
|
+
trigger: `@${toKebab(typeFirst)}-di-pattern`,
|
|
202
|
+
kind: 'pattern',
|
|
203
|
+
category: 'Architecture',
|
|
204
|
+
topicHint: 'architecture',
|
|
205
|
+
content: {
|
|
206
|
+
markdown: `### 依赖注入约定\n\n${projectName} 使用依赖注入管理 ${typeList} 等组件的生命周期。\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
|
|
207
|
+
rationale: '依赖注入提高可测试性和模块解耦',
|
|
208
|
+
},
|
|
209
|
+
coreCode: `${lang === 'swift' ? `class ${typeFirst} {\n init(service: Service) { }\n}` : `class ${typeFirst} {\n constructor(private service: Service) {}\n}`}`,
|
|
210
|
+
doClause: `Use constructor injection for ${typeFirst} dependencies`,
|
|
211
|
+
dontClause: 'Do not use service locator or global singletons',
|
|
212
|
+
whenClause: `When creating or modifying ${typeFirst} and its dependencies`,
|
|
213
|
+
usageGuide: `### 使用指南\n\n通过构造器注入依赖项。`,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
...base,
|
|
217
|
+
title: `${projectName} 模块通信约定`,
|
|
218
|
+
description: `模块间通过协议/接口进行通信,避免直接耦合`,
|
|
219
|
+
trigger: `@${toKebab(projectName)}-module-comm`,
|
|
220
|
+
kind: 'rule',
|
|
221
|
+
category: 'Architecture',
|
|
222
|
+
topicHint: 'architecture',
|
|
223
|
+
content: {
|
|
224
|
+
markdown: `### 模块通信\n\n${projectName} 的模块通信遵循接口隔离原则,${ast.protocols} 个协议定义了清晰的边界。\n\n> ⚠️ Mock AI 自动生成`,
|
|
225
|
+
rationale: '接口隔离确保模块可独立演进和测试',
|
|
226
|
+
},
|
|
227
|
+
coreCode: `${lang === 'swift' ? `protocol ${typeFirst}Protocol {\n func execute() async\n}` : `interface I${typeFirst} {\n execute(): Promise<void>\n}`}`,
|
|
228
|
+
doClause: 'Define protocols/interfaces for all cross-module communication',
|
|
229
|
+
dontClause: 'Do not import concrete implementations across module boundaries',
|
|
230
|
+
whenClause: 'When modules need to communicate or share data',
|
|
231
|
+
usageGuide: `### 使用指南\n\n定义协议作为模块间通信契约。`,
|
|
232
|
+
},
|
|
233
|
+
];
|
|
234
|
+
case 'code-pattern':
|
|
235
|
+
return [
|
|
236
|
+
{
|
|
237
|
+
...base,
|
|
238
|
+
title: `${typeFirst} 扩展方法约定`,
|
|
239
|
+
description: `使用扩展方法为 ${typeFirst} 添加功能,保持核心类型精简`,
|
|
240
|
+
trigger: `@${toKebab(typeFirst)}-extension-pattern`,
|
|
241
|
+
kind: 'pattern',
|
|
242
|
+
category: 'Tool',
|
|
243
|
+
topicHint: 'conventions',
|
|
244
|
+
content: {
|
|
245
|
+
markdown: `### 扩展方法约定\n\n${projectName} 广泛使用扩展方法组织代码,${typeList} 等类型均采用此模式。\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
|
|
246
|
+
rationale: '扩展方法使核心类型保持精简,增强可读性',
|
|
247
|
+
},
|
|
248
|
+
coreCode: `${lang === 'swift' ? `extension ${typeFirst} {\n func helper() { }\n}` : `// ${typeFirst}.extensions.ts`}`,
|
|
249
|
+
doClause: `Group related functionality in ${lang === 'swift' ? 'extensions' : 'utility modules'}`,
|
|
250
|
+
dontClause: 'Do not bloat core types with unrelated methods',
|
|
251
|
+
whenClause: `When adding utility or convenience methods to ${typeFirst}`,
|
|
252
|
+
usageGuide: `### 使用指南\n\n按功能分组创建扩展文件。`,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
...base,
|
|
256
|
+
title: `${projectName} 类型安全惯例`,
|
|
257
|
+
description: `项目统一使用强类型和类型守卫确保安全`,
|
|
258
|
+
trigger: `@${toKebab(projectName)}-type-safety`,
|
|
259
|
+
kind: 'rule',
|
|
260
|
+
category: 'Tool',
|
|
261
|
+
topicHint: 'conventions',
|
|
262
|
+
content: {
|
|
263
|
+
markdown: `### 类型安全\n\n${projectName} 强制类型安全,包含 ${ast.classes} 个类和 ${ast.protocols} 个协议定义。\n\n> ⚠️ Mock AI 自动生成`,
|
|
264
|
+
rationale: '类型安全减少运行时错误',
|
|
265
|
+
},
|
|
266
|
+
coreCode: `${lang === 'swift' ? 'guard let value = optional else { return }' : 'if (value === undefined) { return; }'}`,
|
|
267
|
+
doClause: 'Use type guards and optional binding for safe access',
|
|
268
|
+
dontClause: 'Do not use force unwrapping or type casting without checks',
|
|
269
|
+
whenClause: 'When handling optional values or type conversions',
|
|
270
|
+
usageGuide: `### 使用指南\n\n始终使用安全的类型转换。`,
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
...base,
|
|
274
|
+
title: `${projectName} 命名约定`,
|
|
275
|
+
description: `文件和类型命名遵循一致的约定`,
|
|
276
|
+
trigger: `@${toKebab(projectName)}-naming-conventions`,
|
|
277
|
+
kind: 'rule',
|
|
278
|
+
category: 'Tool',
|
|
279
|
+
topicHint: 'conventions',
|
|
280
|
+
content: {
|
|
281
|
+
markdown: `### 命名约定\n\n${projectName} 使用一致的命名风格。类型: PascalCase, 方法/属性: camelCase。\n\n> ⚠️ Mock AI 自动生成`,
|
|
282
|
+
rationale: '统一命名提高代码可读性',
|
|
283
|
+
},
|
|
284
|
+
coreCode: `// ${typeFirst}.swift / ${typeFirst}.ts`,
|
|
285
|
+
doClause: 'Follow PascalCase for types and camelCase for members',
|
|
286
|
+
dontClause: 'Do not use abbreviations or inconsistent casing',
|
|
287
|
+
whenClause: 'When naming new types, methods, or properties',
|
|
288
|
+
usageGuide: `### 使用指南\n\n遵循项目既有命名风格。`,
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
default:
|
|
292
|
+
return [
|
|
293
|
+
{
|
|
294
|
+
...base,
|
|
295
|
+
title: `${projectName} ${dimLabel}实践`,
|
|
296
|
+
description: `${dimLabel}维度的最佳实践,基于 ${typeList} 等代码分析`,
|
|
297
|
+
trigger: `@${toKebab(projectName)}-${toKebab(dimLabel)}-practice`,
|
|
298
|
+
kind: 'pattern',
|
|
299
|
+
category: 'Tool',
|
|
300
|
+
topicHint: dimId.includes('network')
|
|
301
|
+
? 'networking'
|
|
302
|
+
: dimId.includes('ui')
|
|
303
|
+
? 'ui'
|
|
304
|
+
: 'conventions',
|
|
305
|
+
content: {
|
|
306
|
+
markdown: `### ${dimLabel}\n\n${projectName} 在 ${dimLabel} 方面的实践,涉及 ${typeList} 等核心类型。\n\n**文件统计**: ${ast.classes} 类, ${ast.protocols} 协议, ${ast.functions} 函数\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
|
|
307
|
+
rationale: `${dimLabel}是项目质量的重要维度`,
|
|
308
|
+
},
|
|
309
|
+
coreCode: `// See ${srcFirst}`,
|
|
310
|
+
doClause: `Follow established ${dimLabel} patterns in the project`,
|
|
311
|
+
dontClause: `Do not deviate from the project's ${dimLabel} conventions`,
|
|
312
|
+
whenClause: `When working on ${dimLabel}-related code`,
|
|
313
|
+
usageGuide: `### 使用指南\n\n遵循项目的 ${dimLabel} 约定。`,
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
...base,
|
|
317
|
+
title: `${typeFirst} ${dimLabel}约定`,
|
|
318
|
+
description: `${typeFirst} 相关的 ${dimLabel} 约定`,
|
|
319
|
+
trigger: `@${toKebab(typeFirst)}-${toKebab(dimLabel)}`,
|
|
320
|
+
kind: 'rule',
|
|
321
|
+
category: 'Tool',
|
|
322
|
+
topicHint: dimId.includes('network') ? 'networking' : 'conventions',
|
|
323
|
+
content: {
|
|
324
|
+
markdown: `### ${typeFirst} ${dimLabel}\n\n${typeFirst} 遵循的 ${dimLabel} 约定。\n\n> ⚠️ Mock AI 自动生成`,
|
|
325
|
+
rationale: `基于 ${typeFirst} 的实际代码模式`,
|
|
326
|
+
},
|
|
327
|
+
coreCode: `// ${typeFirst} — ${dimLabel}`,
|
|
328
|
+
doClause: `Apply ${dimLabel} patterns consistent with ${typeFirst}`,
|
|
329
|
+
dontClause: `Do not introduce inconsistent ${dimLabel} approaches`,
|
|
330
|
+
whenClause: `When modifying ${typeFirst} or related components`,
|
|
331
|
+
usageGuide: `### 使用指南\n\n参考 ${typeFirst} 的既有实现。`,
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
...base,
|
|
335
|
+
title: `${projectName} ${dimLabel}检查清单`,
|
|
336
|
+
description: `${dimLabel}方面的代码审查清单`,
|
|
337
|
+
trigger: `@${toKebab(projectName)}-${toKebab(dimLabel)}-checklist`,
|
|
338
|
+
kind: 'fact',
|
|
339
|
+
category: 'Tool',
|
|
340
|
+
topicHint: 'conventions',
|
|
341
|
+
content: {
|
|
342
|
+
markdown: `### ${dimLabel} 检查清单\n\n1. 遵循项目既有模式\n2. 确保类型安全\n3. 添加适当的错误处理\n4. 保持代码一致性\n\n> ⚠️ Mock AI 自动生成`,
|
|
343
|
+
rationale: `${dimLabel}检查清单帮助保持代码质量`,
|
|
344
|
+
},
|
|
345
|
+
coreCode: `// ${dimLabel} checklist applied`,
|
|
346
|
+
doClause: `Review code against the ${dimLabel} checklist before committing`,
|
|
347
|
+
dontClause: `Do not skip ${dimLabel} review for shortcuts`,
|
|
348
|
+
whenClause: `During code review for ${dimLabel}-related changes`,
|
|
349
|
+
usageGuide: `### 使用指南\n\n在代码审查时参考此清单。`,
|
|
350
|
+
},
|
|
351
|
+
];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// ── Mock Pipeline 入口 ────────────────────────────────────────
|
|
355
|
+
/**
|
|
356
|
+
* fillDimensionsMock — Mock AI 轻量管线
|
|
357
|
+
*
|
|
358
|
+
* 利用 Phase 1-4 的真实数据(AST、文件列表、Panorama)自动生成候选知识,
|
|
359
|
+
* 不调用任何 AI API,但走完 submit → dimension_complete 的完整流程。
|
|
360
|
+
*/
|
|
361
|
+
export async function fillDimensionsMock(view, dimensions) {
|
|
362
|
+
const { snapshot, projectRoot } = view;
|
|
363
|
+
const ctx = view.ctx;
|
|
364
|
+
const emitter = new BootstrapEventEmitter(ctx.container);
|
|
365
|
+
const projectName = path.basename(projectRoot);
|
|
366
|
+
const primaryLang = snapshot.language.primaryLang ?? 'unknown';
|
|
367
|
+
const astStats = extractAstStats(snapshot.ast);
|
|
368
|
+
const allFiles = snapshot.allFiles;
|
|
369
|
+
const targetFileMap = view.targetFileMap;
|
|
370
|
+
const repFiles = getRepresentativeFiles(allFiles, targetFileMap);
|
|
371
|
+
logger.info(`[MockPipeline] ═══ Starting Mock bootstrap — ${dimensions.length} dimensions, ` +
|
|
372
|
+
`${allFiles?.length || 0} files, lang=${primaryLang}`);
|
|
373
|
+
emitter.emitProgress('bootstrap:mock-mode', {
|
|
374
|
+
message: '🧪 Mock AI 模式 — 基于代码结构自动生成知识候选(非 AI 深度分析)',
|
|
375
|
+
mockMode: true,
|
|
376
|
+
});
|
|
377
|
+
const knowledgeService = ctx.container.get('knowledgeService');
|
|
378
|
+
let totalCreated = 0;
|
|
379
|
+
for (const dim of dimensions) {
|
|
380
|
+
const dimStartTime = Date.now();
|
|
381
|
+
const dimLabel = dim.label ?? dim.id;
|
|
382
|
+
emitter.emitProgress('bootstrap:dimension-start', {
|
|
383
|
+
dimensionId: dim.id,
|
|
384
|
+
dimensionLabel: dimLabel,
|
|
385
|
+
mockMode: true,
|
|
386
|
+
});
|
|
387
|
+
logger.info(`[MockPipeline] ── Dimension "${dim.id}" (${dimLabel}) ──`);
|
|
388
|
+
// 生成候选
|
|
389
|
+
const candidates = generateDimensionCandidates(dim.id, dimLabel, allFiles, primaryLang, projectName, astStats, repFiles);
|
|
390
|
+
const createdIds = [];
|
|
391
|
+
for (const candidate of candidates) {
|
|
392
|
+
try {
|
|
393
|
+
const entry = await knowledgeService.create({
|
|
394
|
+
...candidate,
|
|
395
|
+
source: 'mock-bootstrap',
|
|
396
|
+
}, { userId: 'mock-ai' });
|
|
397
|
+
createdIds.push(entry.id);
|
|
398
|
+
totalCreated++;
|
|
399
|
+
// 尝试自动评分(非关键路径)
|
|
400
|
+
try {
|
|
401
|
+
await knowledgeService.updateQuality?.(entry.id, { userId: 'mock-ai' });
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
/* best effort */
|
|
405
|
+
}
|
|
406
|
+
logger.info(`[MockPipeline] ✅ Created: "${candidate.title}" → ${entry.id}`);
|
|
407
|
+
}
|
|
408
|
+
catch (err) {
|
|
409
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
410
|
+
logger.warn(`[MockPipeline] ⚠️ Failed to create "${candidate.title}": ${msg}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const durationMs = Date.now() - dimStartTime;
|
|
414
|
+
emitter.emitDimensionComplete(dim.id, {
|
|
415
|
+
type: 'candidate',
|
|
416
|
+
extracted: candidates.length,
|
|
417
|
+
created: createdIds.length,
|
|
418
|
+
status: 'mock-pipeline-complete',
|
|
419
|
+
degraded: false,
|
|
420
|
+
durationMs,
|
|
421
|
+
toolCallCount: 0,
|
|
422
|
+
source: 'mock-pipeline',
|
|
423
|
+
});
|
|
424
|
+
logger.info(`[MockPipeline] ✅ "${dim.id}": ${createdIds.length}/${candidates.length} candidates, ${durationMs}ms`);
|
|
425
|
+
}
|
|
426
|
+
emitter.emitProgress('bootstrap:mock-complete', {
|
|
427
|
+
message: `🧪 Mock Bootstrap 完成: ${totalCreated} 个候选知识已生成`,
|
|
428
|
+
totalCreated,
|
|
429
|
+
mockMode: true,
|
|
430
|
+
});
|
|
431
|
+
logger.info(`[MockPipeline] ═══ Mock bootstrap complete — ${totalCreated} candidates from ${dimensions.length} dimensions`);
|
|
432
|
+
}
|
|
@@ -20,6 +20,7 @@ import { ExplorationTracker } from '#agent/context/ExplorationTracker.js';
|
|
|
20
20
|
import { EpisodicConsolidator } from '#agent/domain/EpisodicConsolidator.js';
|
|
21
21
|
import { ANALYST_BUDGET } from '#agent/domain/insight-analyst.js';
|
|
22
22
|
import { MemoryCoordinator } from '#agent/memory/MemoryCoordinator.js';
|
|
23
|
+
import { MemoryEmbeddingStore } from '#agent/memory/MemoryEmbeddingStore.js';
|
|
23
24
|
import { PersistentMemory } from '#agent/memory/PersistentMemory.js';
|
|
24
25
|
import { SessionStore } from '#agent/memory/SessionStore.js';
|
|
25
26
|
import { PRESETS } from '#agent/presets.js';
|
|
@@ -32,6 +33,7 @@ import { clearCheckpoints, loadCheckpoints, saveDimensionCheckpoint } from './ch
|
|
|
32
33
|
import { buildTierReflection, DIMENSION_CONFIGS_V3, getFullDimensionConfig, } from './dimension-configs.js';
|
|
33
34
|
import { DimensionContext, parseDimensionDigest } from './dimension-context.js';
|
|
34
35
|
import { IncrementalBootstrap } from './IncrementalBootstrap.js';
|
|
36
|
+
import { fillDimensionsMock } from './mock-pipeline.js';
|
|
35
37
|
import { TierScheduler } from './tier-scheduler.js';
|
|
36
38
|
const logger = Logger.getInstance();
|
|
37
39
|
// ──────────────────────────────────────────────────────────────────
|
|
@@ -116,21 +118,22 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
116
118
|
logger.info(`[Insight-v3] ═══ fillDimensionsV3 entered — ${isIncremental ? 'INCREMENTAL' : 'FULL'} pipeline`);
|
|
117
119
|
let allFiles = snapshot.allFiles;
|
|
118
120
|
// ═══════════════════════════════════════════════════════════
|
|
119
|
-
// Step 0: AI 可用性检查 (v7.2: 使用 AgentFactory)
|
|
121
|
+
// Step 0: AI 可用性检查 (v7.2: 使用 AgentFactory + AiProviderManager)
|
|
120
122
|
// ═══════════════════════════════════════════════════════════
|
|
121
123
|
let agentFactory = null;
|
|
124
|
+
let isMockMode = false;
|
|
122
125
|
try {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!
|
|
127
|
-
agentFactory =
|
|
126
|
+
// 通过 AiProviderManager 统一检查 mock 模式
|
|
127
|
+
const manager = ctx.container.singletons?._aiProviderManager;
|
|
128
|
+
isMockMode = manager?.isMock ?? false;
|
|
129
|
+
if (!isMockMode) {
|
|
130
|
+
agentFactory = ctx.container.get('agentFactory');
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
133
|
catch {
|
|
131
134
|
/* not available */
|
|
132
135
|
}
|
|
133
|
-
if (!agentFactory) {
|
|
136
|
+
if (!agentFactory && !isMockMode) {
|
|
134
137
|
logger.error('[Insight-v3] AI Provider not available — bootstrap requires AI');
|
|
135
138
|
emitter.emitProgress('bootstrap:ai-unavailable', {
|
|
136
139
|
message: 'AI Provider 不可用,Bootstrap 需要 AI 才能运行。请先配置 AI Provider(如 OpenAI、Anthropic 等)后重试。',
|
|
@@ -140,6 +143,12 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
140
143
|
}
|
|
141
144
|
return;
|
|
142
145
|
}
|
|
146
|
+
// Mock AI: 走 mock-pipeline 轻量管线
|
|
147
|
+
if (isMockMode) {
|
|
148
|
+
logger.info('[Insight-v3] Mock AI detected — routing to mock-pipeline');
|
|
149
|
+
await fillDimensionsMock(view, dimensions);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
143
152
|
// ═══════════════════════════════════════════════════════════
|
|
144
153
|
// Step 0.5: 构建 ProjectGraph
|
|
145
154
|
// ═══════════════════════════════════════════════════════════
|
|
@@ -151,7 +160,7 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
151
160
|
timeoutMs: 15_000,
|
|
152
161
|
})) ?? null;
|
|
153
162
|
if (projectGraph) {
|
|
154
|
-
const overview = projectGraph.getOverview();
|
|
163
|
+
const overview = await projectGraph.getOverview();
|
|
155
164
|
logger.info(`[Insight-v3] ProjectGraph: ${overview.totalClasses} classes, ${overview.totalProtocols} protocols (${overview.buildTimeMs}ms)`);
|
|
156
165
|
}
|
|
157
166
|
}
|
|
@@ -225,7 +234,11 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
225
234
|
catch {
|
|
226
235
|
// EmbedProvider 不可用时 fallback 到无向量模式
|
|
227
236
|
}
|
|
228
|
-
semanticMemory = new PersistentMemory(db, {
|
|
237
|
+
semanticMemory = new PersistentMemory(db, {
|
|
238
|
+
logger,
|
|
239
|
+
embeddingFn,
|
|
240
|
+
embeddingStore: new MemoryEmbeddingStore(projectRoot),
|
|
241
|
+
});
|
|
229
242
|
const smStats = semanticMemory.getStats();
|
|
230
243
|
if (smStats.total > 0) {
|
|
231
244
|
logger.info(`[Insight-v3] Loaded ${smStats.total} semantic memories from previous bootstrap ` +
|
|
@@ -240,10 +253,11 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
240
253
|
let codeEntityGraphInst = null;
|
|
241
254
|
try {
|
|
242
255
|
const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
256
|
+
const entityRepo = ctx.container.get('codeEntityRepository');
|
|
257
|
+
const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
|
|
258
|
+
if (entityRepo && edgeRepo) {
|
|
259
|
+
codeEntityGraphInst = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
|
|
260
|
+
const topo = await codeEntityGraphInst.getTopology();
|
|
247
261
|
if (topo.totalEntities > 0) {
|
|
248
262
|
logger.info(`[Insight-v3] CodeEntityGraph: ${topo.totalEntities} entities, ${topo.totalEdges} edges`);
|
|
249
263
|
}
|
|
@@ -311,6 +325,7 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
311
325
|
// ── 跨维度去重集合 (实例级持久化,等效旧 ChatAgent.#globalSubmittedTitles/Patterns) ──
|
|
312
326
|
const globalSubmittedTitles = new Set();
|
|
313
327
|
const globalSubmittedPatterns = new Set();
|
|
328
|
+
const globalSubmittedTriggers = new Set();
|
|
314
329
|
// ── Rescan 模式: 预种已有 recipe 标题到去重集合,防止重复创建 ──
|
|
315
330
|
const existingRecipesList = existingRecipes;
|
|
316
331
|
if (existingRecipesList && existingRecipesList.length > 0) {
|
|
@@ -319,8 +334,12 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
319
334
|
if (r.title && r.status !== 'decaying') {
|
|
320
335
|
globalSubmittedTitles.add(r.title.toLowerCase().trim());
|
|
321
336
|
}
|
|
337
|
+
// ★ trigger 全部预种(含 decaying),防止 trigger 冲突
|
|
338
|
+
if (r.trigger) {
|
|
339
|
+
globalSubmittedTriggers.add(r.trigger.toLowerCase().trim());
|
|
340
|
+
}
|
|
322
341
|
}
|
|
323
|
-
logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size}
|
|
342
|
+
logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size} titles + ${globalSubmittedTriggers.size} triggers into dedup set`);
|
|
324
343
|
}
|
|
325
344
|
// 构建 rescanContext 供 Analyst/Producer prompt 使用(区分 healthy/decaying)
|
|
326
345
|
const rescanContext = existingRecipesList
|
|
@@ -579,7 +598,7 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
579
598
|
modules: Object.keys(targetFileMap || {}),
|
|
580
599
|
},
|
|
581
600
|
// ── 引擎增强参数 (PipelineStrategy → reactLoop 透传) ──
|
|
582
|
-
contextWindow: agentFactory
|
|
601
|
+
contextWindow: agentFactory?.createContextWindow({ isSystem: true }),
|
|
583
602
|
// B1 fix: 分析阶段使用 analyst 策略 (SCAN→EXPLORE→VERIFY→SUMMARIZE)
|
|
584
603
|
// 而非 bootstrap (EXPLORE→PRODUCE→SUMMARIZE),避免 PRODUCE nudge 浪费轮次
|
|
585
604
|
// B3 fix: 透传完整 ANALYST_BUDGET (searchBudget/maxSubmits/softSubmitLimit/idleRoundsToExit)
|
|
@@ -589,6 +608,7 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
589
608
|
sharedState: {
|
|
590
609
|
submittedTitles: globalSubmittedTitles,
|
|
591
610
|
submittedPatterns: globalSubmittedPatterns,
|
|
611
|
+
submittedTriggers: globalSubmittedTriggers,
|
|
592
612
|
_dimensionMeta: {
|
|
593
613
|
id: dimId,
|
|
594
614
|
outputType: dimConfig.outputType || 'candidate',
|
|
@@ -986,9 +1006,10 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
986
1006
|
// ═══════════════════════════════════════════════════════════
|
|
987
1007
|
try {
|
|
988
1008
|
const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
|
|
989
|
-
const
|
|
990
|
-
|
|
991
|
-
|
|
1009
|
+
const entityRepo = ctx.container.get('codeEntityRepository');
|
|
1010
|
+
const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
|
|
1011
|
+
if (entityRepo && edgeRepo) {
|
|
1012
|
+
const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
|
|
992
1013
|
// 收集所有维度产出的候选 (从 Producer toolCalls 中提取)
|
|
993
1014
|
const allCandidates = [];
|
|
994
1015
|
for (const dimData of Object.values(dimensionCandidates)) {
|
|
@@ -1007,7 +1028,7 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
1007
1028
|
}
|
|
1008
1029
|
}
|
|
1009
1030
|
if (allCandidates.length > 0) {
|
|
1010
|
-
const relResult = ceg.populateFromCandidateRelations(allCandidates);
|
|
1031
|
+
const relResult = await ceg.populateFromCandidateRelations(allCandidates);
|
|
1011
1032
|
logger.info(`[Insight-v3] Code Entity Graph relations: ${relResult.edgesCreated} edges from ${allCandidates.length} candidates (${relResult.durationMs}ms)`);
|
|
1012
1033
|
}
|
|
1013
1034
|
}
|
|
@@ -1025,7 +1046,10 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
1025
1046
|
try {
|
|
1026
1047
|
const db = ctx.container.get('database');
|
|
1027
1048
|
if (db) {
|
|
1028
|
-
const semanticMemory = new PersistentMemory(db, {
|
|
1049
|
+
const semanticMemory = new PersistentMemory(db, {
|
|
1050
|
+
logger,
|
|
1051
|
+
embeddingStore: new MemoryEmbeddingStore(projectRoot),
|
|
1052
|
+
});
|
|
1029
1053
|
const consolidator = new EpisodicConsolidator(semanticMemory, { logger });
|
|
1030
1054
|
consolidationResult = consolidator.consolidate(sessionStore, {
|
|
1031
1055
|
bootstrapSession: sessionId,
|
|
@@ -1144,10 +1168,11 @@ export async function fillDimensionsV3(view, dimensions) {
|
|
|
1144
1168
|
// Phase E: 附加 Code Entity Graph 拓扑到报告
|
|
1145
1169
|
try {
|
|
1146
1170
|
const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
|
|
1147
|
-
const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
const
|
|
1171
|
+
const entityRepo = ctx.container.get('codeEntityRepository');
|
|
1172
|
+
const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
|
|
1173
|
+
if (entityRepo && edgeRepo) {
|
|
1174
|
+
const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
|
|
1175
|
+
const topo = await ceg.getTopology();
|
|
1151
1176
|
report.codeEntityGraph = {
|
|
1152
1177
|
entities: topo.entities,
|
|
1153
1178
|
edges: topo.edges,
|
|
@@ -21,6 +21,14 @@ export async function bootstrapRefine(ctx, args) {
|
|
|
21
21
|
errorCode: 'MISSING_AI_PROVIDER',
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
// Mock 模式下跳过 AI 润色
|
|
25
|
+
if (aiProvider.name === 'mock') {
|
|
26
|
+
return envelope({
|
|
27
|
+
success: false,
|
|
28
|
+
message: 'AI Provider 未配置,当前为 Mock 模式。请先配置 API Key。',
|
|
29
|
+
errorCode: 'MOCK_MODE',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
24
32
|
// 接入 BootstrapTaskManager 双通道推送 refine:* 事件
|
|
25
33
|
let onProgress = null;
|
|
26
34
|
try {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Phase 1 → 文件收集(DiscovererRegistry → 多语言项目类型检测)
|
|
10
10
|
* Phase 1.5 → AST 代码结构分析(tree-sitter + SFC 预处理)
|
|
11
11
|
* Phase 1.6 → Code Entity Graph(代码实体关系图谱)
|
|
12
|
-
* Phase
|
|
12
|
+
* Phase 2.2 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
|
|
13
13
|
* Phase 2 → 依赖关系 → knowledge_edges
|
|
14
14
|
* Phase 2.1 → Module 实体写入 Entity Graph
|
|
15
15
|
* Phase 3 → Guard 规则审计
|