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,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module DiscovererPreference
|
|
3
|
+
* @description Discoverer 用户偏好持久化 + 冲突检测
|
|
4
|
+
*
|
|
5
|
+
* 当多个 Discoverer 匹配且置信度接近时,允许用户确认选择并持久化。
|
|
6
|
+
* CLI 上下文使用 readline 交互,MCP/HTTP 上下文返回 ambiguous 标记。
|
|
7
|
+
*/
|
|
8
|
+
export interface DiscovererPreferenceData {
|
|
9
|
+
selectedDiscoverer: string;
|
|
10
|
+
selectedAt: string;
|
|
11
|
+
alternatives: string[];
|
|
12
|
+
userConfirmed: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface DetectMatch {
|
|
15
|
+
discovererId: string;
|
|
16
|
+
displayName: string;
|
|
17
|
+
confidence: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ConflictResult {
|
|
20
|
+
ambiguous: boolean;
|
|
21
|
+
reason?: string;
|
|
22
|
+
matches: DetectMatch[];
|
|
23
|
+
recommended?: DetectMatch;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 检测 Discoverer 匹配结果是否存在冲突/模糊
|
|
27
|
+
*/
|
|
28
|
+
export declare function detectConflict(matches: DetectMatch[]): ConflictResult;
|
|
29
|
+
/**
|
|
30
|
+
* 加载已保存的 Discoverer 偏好
|
|
31
|
+
* @returns 偏好数据,或 null(无偏好/文件不存在/损坏)
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadPreference(projectRoot: string): DiscovererPreferenceData | null;
|
|
34
|
+
/**
|
|
35
|
+
* 保存 Discoverer 偏好
|
|
36
|
+
*/
|
|
37
|
+
export declare function savePreference(projectRoot: string, discovererId: string, alternatives: string[], userConfirmed: boolean): void;
|
|
38
|
+
/**
|
|
39
|
+
* CLI 交互式确认 Discoverer 选择
|
|
40
|
+
* 仅在 CLI 终端上下文(stdin 可用)时有效
|
|
41
|
+
*
|
|
42
|
+
* @returns 用户选择的 Discoverer ID,或 null(非交互环境/超时)
|
|
43
|
+
*/
|
|
44
|
+
export declare function promptDiscovererChoice(matches: DetectMatch[], recommended?: DetectMatch): Promise<string | null>;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module DiscovererPreference
|
|
3
|
+
* @description Discoverer 用户偏好持久化 + 冲突检测
|
|
4
|
+
*
|
|
5
|
+
* 当多个 Discoverer 匹配且置信度接近时,允许用户确认选择并持久化。
|
|
6
|
+
* CLI 上下文使用 readline 交互,MCP/HTTP 上下文返回 ambiguous 标记。
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
// ── Constants ───────────────────────────────────────
|
|
11
|
+
const PREFERENCE_DIR = '.autosnippet';
|
|
12
|
+
const PREFERENCE_FILE = 'discoverer-preference.json';
|
|
13
|
+
/** 两个 Discoverer confidence 差值低于此阈值视为模糊 */
|
|
14
|
+
const AMBIGUITY_THRESHOLD = 0.1;
|
|
15
|
+
/** 最高 confidence 低于此值视为启发式不确定 */
|
|
16
|
+
const HEURISTIC_UNCERTAIN_THRESHOLD = 0.6;
|
|
17
|
+
// ── Conflict Detection ──────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* 检测 Discoverer 匹配结果是否存在冲突/模糊
|
|
20
|
+
*/
|
|
21
|
+
export function detectConflict(matches) {
|
|
22
|
+
if (matches.length === 0) {
|
|
23
|
+
return { ambiguous: false, matches };
|
|
24
|
+
}
|
|
25
|
+
if (matches.length === 1) {
|
|
26
|
+
return { ambiguous: false, matches, recommended: matches[0] };
|
|
27
|
+
}
|
|
28
|
+
const top = matches[0];
|
|
29
|
+
const second = matches[1];
|
|
30
|
+
// 条件 1: 多个高置信度结果 (≥ 0.60)
|
|
31
|
+
const highConfCount = matches.filter((m) => m.confidence >= 0.6).length;
|
|
32
|
+
// 条件 2: top-1 与 top-2 差距 < 阈值
|
|
33
|
+
const closeDelta = top.confidence - second.confidence < AMBIGUITY_THRESHOLD;
|
|
34
|
+
// 条件 3: 最高分仍低于阈值(仅启发式命中)
|
|
35
|
+
const heuristicOnly = top.confidence < HEURISTIC_UNCERTAIN_THRESHOLD;
|
|
36
|
+
if (highConfCount >= 2 && closeDelta) {
|
|
37
|
+
return {
|
|
38
|
+
ambiguous: true,
|
|
39
|
+
reason: `Multiple build systems detected with similar confidence (${top.displayName}: ${top.confidence.toFixed(2)} vs ${second.displayName}: ${second.confidence.toFixed(2)})`,
|
|
40
|
+
matches,
|
|
41
|
+
recommended: top,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (heuristicOnly) {
|
|
45
|
+
return {
|
|
46
|
+
ambiguous: true,
|
|
47
|
+
reason: `No definitive build system identified (highest: ${top.displayName} at ${top.confidence.toFixed(2)})`,
|
|
48
|
+
matches,
|
|
49
|
+
recommended: top,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { ambiguous: false, matches, recommended: top };
|
|
53
|
+
}
|
|
54
|
+
// ── Preference Persistence ──────────────────────────
|
|
55
|
+
/**
|
|
56
|
+
* 获取偏好文件路径
|
|
57
|
+
*/
|
|
58
|
+
function getPreferencePath(projectRoot) {
|
|
59
|
+
return join(projectRoot, PREFERENCE_DIR, PREFERENCE_FILE);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 加载已保存的 Discoverer 偏好
|
|
63
|
+
* @returns 偏好数据,或 null(无偏好/文件不存在/损坏)
|
|
64
|
+
*/
|
|
65
|
+
export function loadPreference(projectRoot) {
|
|
66
|
+
const prefPath = getPreferencePath(projectRoot);
|
|
67
|
+
if (!existsSync(prefPath)) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const content = readFileSync(prefPath, 'utf8');
|
|
72
|
+
const data = JSON.parse(content);
|
|
73
|
+
// 基本结构校验
|
|
74
|
+
if (typeof data.selectedDiscoverer !== 'string' || typeof data.userConfirmed !== 'boolean') {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 保存 Discoverer 偏好
|
|
85
|
+
*/
|
|
86
|
+
export function savePreference(projectRoot, discovererId, alternatives, userConfirmed) {
|
|
87
|
+
const prefPath = getPreferencePath(projectRoot);
|
|
88
|
+
const prefDir = join(projectRoot, PREFERENCE_DIR);
|
|
89
|
+
if (!existsSync(prefDir)) {
|
|
90
|
+
mkdirSync(prefDir, { recursive: true });
|
|
91
|
+
}
|
|
92
|
+
const data = {
|
|
93
|
+
selectedDiscoverer: discovererId,
|
|
94
|
+
selectedAt: new Date().toISOString(),
|
|
95
|
+
alternatives,
|
|
96
|
+
userConfirmed,
|
|
97
|
+
};
|
|
98
|
+
writeFileSync(prefPath, JSON.stringify(data, null, 2), 'utf8');
|
|
99
|
+
}
|
|
100
|
+
// ── CLI Interactive Prompt ──────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* CLI 交互式确认 Discoverer 选择
|
|
103
|
+
* 仅在 CLI 终端上下文(stdin 可用)时有效
|
|
104
|
+
*
|
|
105
|
+
* @returns 用户选择的 Discoverer ID,或 null(非交互环境/超时)
|
|
106
|
+
*/
|
|
107
|
+
export async function promptDiscovererChoice(matches, recommended) {
|
|
108
|
+
// 检测是否在可交互终端
|
|
109
|
+
if (!process.stdin.isTTY) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const { createInterface } = await import('node:readline');
|
|
113
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
114
|
+
const question = (prompt) => new Promise((resolve) => {
|
|
115
|
+
rl.question(prompt, (answer) => {
|
|
116
|
+
resolve(answer.trim());
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
console.log('\n⚠️ 项目构建系统识别需要确认\n');
|
|
121
|
+
console.log('检测到以下构建系统配置:');
|
|
122
|
+
for (let i = 0; i < matches.length; i++) {
|
|
123
|
+
const m = matches[i];
|
|
124
|
+
const rec = recommended && m.discovererId === recommended.discovererId ? ' ← 推荐' : '';
|
|
125
|
+
console.log(` [${i + 1}] ${m.displayName} confidence: ${m.confidence.toFixed(2)}${rec}`);
|
|
126
|
+
}
|
|
127
|
+
const defaultIdx = recommended
|
|
128
|
+
? matches.findIndex((m) => m.discovererId === recommended.discovererId) + 1
|
|
129
|
+
: 1;
|
|
130
|
+
const answer = await question(`\n请选择主要构建系统 [1-${matches.length}],或按回车使用推荐 (${defaultIdx}): `);
|
|
131
|
+
const choice = answer === '' ? defaultIdx : Number.parseInt(answer, 10);
|
|
132
|
+
if (choice >= 1 && choice <= matches.length) {
|
|
133
|
+
return matches[choice - 1].discovererId;
|
|
134
|
+
}
|
|
135
|
+
// 无效输入, 使用推荐
|
|
136
|
+
return recommended?.discovererId ?? matches[0].discovererId;
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
rl.close();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 检测顺序:按 confidence 降序。多个匹配时取最高 confidence。
|
|
6
6
|
* 若全部未命中,回退到 GenericDiscoverer(目录扫描兜底)。
|
|
7
|
+
*
|
|
8
|
+
* 支持用户偏好持久化: 当匹配模糊时,保存/加载用户选择。
|
|
7
9
|
*/
|
|
10
|
+
import type { ConflictResult } from './DiscovererPreference.js';
|
|
8
11
|
import type { ProjectDiscoverer } from './ProjectDiscoverer.js';
|
|
9
12
|
export declare class DiscovererRegistry {
|
|
10
13
|
#private;
|
|
@@ -17,12 +20,18 @@ export declare class DiscovererRegistry {
|
|
|
17
20
|
detect(projectRoot: string): Promise<ProjectDiscoverer>;
|
|
18
21
|
/**
|
|
19
22
|
* 检测所有匹配的 Discoverer(用于混合项目)
|
|
20
|
-
*
|
|
23
|
+
* 若存在用户偏好,将偏好 Discoverer 提升到首位。
|
|
24
|
+
* @returns 按 confidence 降序排列的匹配结果(偏好优先)
|
|
21
25
|
*/
|
|
22
26
|
detectAll(projectRoot: string): Promise<{
|
|
23
27
|
discoverer: ProjectDiscoverer;
|
|
24
28
|
confidence: number;
|
|
25
29
|
}[]>;
|
|
30
|
+
/**
|
|
31
|
+
* 分析检测结果的冲突/模糊性
|
|
32
|
+
* @returns 冲突分析结果,含 ambiguous 标记和推荐
|
|
33
|
+
*/
|
|
34
|
+
analyzeConflict(projectRoot: string): Promise<ConflictResult>;
|
|
26
35
|
/** 获取所有已注册的 Discoverer */
|
|
27
36
|
getAll(): ProjectDiscoverer[];
|
|
28
37
|
}
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 检测顺序:按 confidence 降序。多个匹配时取最高 confidence。
|
|
6
6
|
* 若全部未命中,回退到 GenericDiscoverer(目录扫描兜底)。
|
|
7
|
+
*
|
|
8
|
+
* 支持用户偏好持久化: 当匹配模糊时,保存/加载用户选择。
|
|
7
9
|
*/
|
|
10
|
+
import { detectConflict, loadPreference } from './DiscovererPreference.js';
|
|
8
11
|
export class DiscovererRegistry {
|
|
9
12
|
#discoverers = [];
|
|
10
13
|
/**
|
|
@@ -38,7 +41,8 @@ export class DiscovererRegistry {
|
|
|
38
41
|
}
|
|
39
42
|
/**
|
|
40
43
|
* 检测所有匹配的 Discoverer(用于混合项目)
|
|
41
|
-
*
|
|
44
|
+
* 若存在用户偏好,将偏好 Discoverer 提升到首位。
|
|
45
|
+
* @returns 按 confidence 降序排列的匹配结果(偏好优先)
|
|
42
46
|
*/
|
|
43
47
|
async detectAll(projectRoot) {
|
|
44
48
|
const results = await Promise.all(this.#discoverers.map(async (d) => ({
|
|
@@ -47,10 +51,46 @@ export class DiscovererRegistry {
|
|
|
47
51
|
.detect(projectRoot)
|
|
48
52
|
.catch(() => ({ match: false, confidence: 0, reason: 'detect error' })),
|
|
49
53
|
})));
|
|
50
|
-
|
|
54
|
+
const matched = results
|
|
51
55
|
.filter((r) => r.result.match)
|
|
52
56
|
.sort((a, b) => b.result.confidence - a.result.confidence)
|
|
53
57
|
.map((r) => ({ discoverer: r.discoverer, confidence: r.result.confidence }));
|
|
58
|
+
// 如果有用户持久化偏好,将偏好 Discoverer 提升到首位
|
|
59
|
+
const preference = loadPreference(projectRoot);
|
|
60
|
+
if (preference?.userConfirmed) {
|
|
61
|
+
const prefIdx = matched.findIndex((m) => m.discoverer.id === preference.selectedDiscoverer);
|
|
62
|
+
if (prefIdx > 0) {
|
|
63
|
+
const [preferred] = matched.splice(prefIdx, 1);
|
|
64
|
+
matched.unshift(preferred);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return matched;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 分析检测结果的冲突/模糊性
|
|
71
|
+
* @returns 冲突分析结果,含 ambiguous 标记和推荐
|
|
72
|
+
*/
|
|
73
|
+
async analyzeConflict(projectRoot) {
|
|
74
|
+
const results = await Promise.all(this.#discoverers.map(async (d) => ({
|
|
75
|
+
discoverer: d,
|
|
76
|
+
result: await d
|
|
77
|
+
.detect(projectRoot)
|
|
78
|
+
.catch(() => ({ match: false, confidence: 0, reason: 'detect error' })),
|
|
79
|
+
})));
|
|
80
|
+
const matches = results
|
|
81
|
+
.filter((r) => r.result.match)
|
|
82
|
+
.sort((a, b) => b.result.confidence - a.result.confidence)
|
|
83
|
+
.map((r) => ({
|
|
84
|
+
discovererId: r.discoverer.id,
|
|
85
|
+
displayName: r.discoverer.displayName,
|
|
86
|
+
confidence: r.result.confidence,
|
|
87
|
+
}));
|
|
88
|
+
// 如果有用户偏好,直接信任
|
|
89
|
+
const preference = loadPreference(projectRoot);
|
|
90
|
+
if (preference?.userConfirmed) {
|
|
91
|
+
return { ambiguous: false, matches, recommended: matches[0] };
|
|
92
|
+
}
|
|
93
|
+
return detectConflict(matches);
|
|
54
94
|
}
|
|
55
95
|
/** 获取所有已注册的 Discoverer */
|
|
56
96
|
getAll() {
|
|
@@ -25,6 +25,17 @@ export interface DependencyEdge {
|
|
|
25
25
|
from: string;
|
|
26
26
|
to: string;
|
|
27
27
|
type: string;
|
|
28
|
+
/** 依赖作用域 (如 CMake PUBLIC/PRIVATE, Gradle implementation/api) */
|
|
29
|
+
scope?: string;
|
|
30
|
+
/** 构建配置 (如 Gradle configuration) */
|
|
31
|
+
configuration?: string;
|
|
32
|
+
/** 跨语言桥接类型 (如 flutter-engine / native-module / cinterop) */
|
|
33
|
+
bridgeType?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface DependencyGraphLayer {
|
|
36
|
+
name: string;
|
|
37
|
+
order: number;
|
|
38
|
+
accessibleLayers: string[];
|
|
28
39
|
}
|
|
29
40
|
export interface DependencyGraph {
|
|
30
41
|
nodes: (string | {
|
|
@@ -33,9 +44,17 @@ export interface DependencyGraph {
|
|
|
33
44
|
type?: string;
|
|
34
45
|
fullPath?: string;
|
|
35
46
|
indirect?: boolean;
|
|
47
|
+
/** 标签 (如 Nx tags, Bazel visibility) */
|
|
48
|
+
tags?: string[];
|
|
49
|
+
/** 可见性 (如 Bazel //visibility:public) */
|
|
50
|
+
visibility?: string[];
|
|
51
|
+
/** Convention 角色 (如 Gradle convention plugin 推断的角色) */
|
|
52
|
+
conventionRole?: string;
|
|
36
53
|
[key: string]: unknown;
|
|
37
54
|
})[];
|
|
38
55
|
edges: DependencyEdge[];
|
|
56
|
+
/** 层级元数据(来自自研构建系统的分层声明) */
|
|
57
|
+
layers?: DependencyGraphLayer[];
|
|
39
58
|
}
|
|
40
59
|
export declare class ProjectDiscoverer {
|
|
41
60
|
/** 检测此 Discoverer 是否适用于给定项目 */
|
|
@@ -7,7 +7,9 @@ import { DiscovererRegistry } from './DiscovererRegistry.js';
|
|
|
7
7
|
export declare function getDiscovererRegistry(): DiscovererRegistry;
|
|
8
8
|
/** 重置 Registry(仅用于测试) */
|
|
9
9
|
export declare function resetDiscovererRegistry(): void;
|
|
10
|
+
export { CustomConfigDiscoverer } from './CustomConfigDiscoverer.js';
|
|
10
11
|
export { DartDiscoverer } from './DartDiscoverer.js';
|
|
12
|
+
export { type ConflictResult, type DetectMatch, type DiscovererPreferenceData, detectConflict, loadPreference, promptDiscovererChoice, savePreference, } from './DiscovererPreference.js';
|
|
11
13
|
export { DiscovererRegistry } from './DiscovererRegistry.js';
|
|
12
14
|
export { GenericDiscoverer } from './GenericDiscoverer.js';
|
|
13
15
|
export { GoDiscoverer } from './GoDiscoverer.js';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @module discovery/index
|
|
3
3
|
* @description ProjectDiscoverer 系统入口 - 初始化 Registry 并注册所有 Discoverer
|
|
4
4
|
*/
|
|
5
|
+
import { CustomConfigDiscoverer } from './CustomConfigDiscoverer.js';
|
|
5
6
|
import { DartDiscoverer } from './DartDiscoverer.js';
|
|
6
7
|
import { DiscovererRegistry } from './DiscovererRegistry.js';
|
|
7
8
|
import { GenericDiscoverer } from './GenericDiscoverer.js';
|
|
@@ -24,6 +25,7 @@ export function getDiscovererRegistry() {
|
|
|
24
25
|
.register(new GoDiscoverer())
|
|
25
26
|
.register(new DartDiscoverer())
|
|
26
27
|
.register(new RustDiscoverer())
|
|
28
|
+
.register(new CustomConfigDiscoverer())
|
|
27
29
|
.register(new GenericDiscoverer());
|
|
28
30
|
}
|
|
29
31
|
return _registry;
|
|
@@ -32,7 +34,9 @@ export function getDiscovererRegistry() {
|
|
|
32
34
|
export function resetDiscovererRegistry() {
|
|
33
35
|
_registry = null;
|
|
34
36
|
}
|
|
37
|
+
export { CustomConfigDiscoverer } from './CustomConfigDiscoverer.js';
|
|
35
38
|
export { DartDiscoverer } from './DartDiscoverer.js';
|
|
39
|
+
export { detectConflict, loadPreference, promptDiscovererChoice, savePreference, } from './DiscovererPreference.js';
|
|
36
40
|
export { DiscovererRegistry } from './DiscovererRegistry.js';
|
|
37
41
|
export { GenericDiscoverer } from './GenericDiscoverer.js';
|
|
38
42
|
export { GoDiscoverer } from './GoDiscoverer.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module CMakeParser
|
|
3
|
+
* @description CMake 轻量解析器 — 从 CMakeLists.txt 提取项目拓扑
|
|
4
|
+
*
|
|
5
|
+
* 支持解析:
|
|
6
|
+
* - project() — 项目名和版本
|
|
7
|
+
* - add_subdirectory() — 子目录发现
|
|
8
|
+
* - add_library() / add_executable() — 目标声明
|
|
9
|
+
* - target_link_libraries() — 依赖关系
|
|
10
|
+
*
|
|
11
|
+
* 设计策略: 仅解析顶层调用,不跟踪控制流 (if/else/macro)
|
|
12
|
+
*/
|
|
13
|
+
export interface ParsedCMakeProject {
|
|
14
|
+
projectName: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
subdirectories: string[];
|
|
17
|
+
targets: CMakeTarget[];
|
|
18
|
+
}
|
|
19
|
+
export interface CMakeTarget {
|
|
20
|
+
name: string;
|
|
21
|
+
type: 'executable' | 'static-library' | 'shared-library' | 'interface-library';
|
|
22
|
+
sources: string[];
|
|
23
|
+
linkDependencies: CMakeLinkDep[];
|
|
24
|
+
}
|
|
25
|
+
export interface CMakeLinkDep {
|
|
26
|
+
target: string;
|
|
27
|
+
scope: 'PUBLIC' | 'PRIVATE' | 'INTERFACE';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 解析 CMakeLists.txt 内容
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseCMakeProject(content: string): ParsedCMakeProject;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module CMakeParser
|
|
3
|
+
* @description CMake 轻量解析器 — 从 CMakeLists.txt 提取项目拓扑
|
|
4
|
+
*
|
|
5
|
+
* 支持解析:
|
|
6
|
+
* - project() — 项目名和版本
|
|
7
|
+
* - add_subdirectory() — 子目录发现
|
|
8
|
+
* - add_library() / add_executable() — 目标声明
|
|
9
|
+
* - target_link_libraries() — 依赖关系
|
|
10
|
+
*
|
|
11
|
+
* 设计策略: 仅解析顶层调用,不跟踪控制流 (if/else/macro)
|
|
12
|
+
*/
|
|
13
|
+
// ── 正则模式 ────────────────────────────────────────
|
|
14
|
+
const PROJECT_RE = /project\(\s*(\w+)(?:\s+VERSION\s+([\d.]+))?/;
|
|
15
|
+
const ADD_SUBDIRECTORY_RE = /add_subdirectory\(\s*(\S+)\s*\)/g;
|
|
16
|
+
// add_library(name STATIC src1.cpp src2.cpp) — 允许多行
|
|
17
|
+
const ADD_LIBRARY_RE = /add_library\(\s*(\w+)\s+(STATIC|SHARED|INTERFACE|MODULE|OBJECT)?\s*([\s\S]*?)\)/g;
|
|
18
|
+
const ADD_EXECUTABLE_RE = /add_executable\(\s*(\w+)\s*([\s\S]*?)\)/g;
|
|
19
|
+
// target_link_libraries(target PUBLIC|PRIVATE|INTERFACE dep1 dep2)
|
|
20
|
+
const TARGET_LINK_RE = /target_link_libraries\(\s*(\w+)\s+([\s\S]*?)\)/g;
|
|
21
|
+
// ── 公开 API ────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* 解析 CMakeLists.txt 内容
|
|
24
|
+
*/
|
|
25
|
+
export function parseCMakeProject(content) {
|
|
26
|
+
const result = {
|
|
27
|
+
projectName: '',
|
|
28
|
+
subdirectories: [],
|
|
29
|
+
targets: [],
|
|
30
|
+
};
|
|
31
|
+
// 移除注释
|
|
32
|
+
const cleaned = removeComments(content);
|
|
33
|
+
// 解析 project()
|
|
34
|
+
const projMatch = cleaned.match(PROJECT_RE);
|
|
35
|
+
if (projMatch) {
|
|
36
|
+
result.projectName = projMatch[1];
|
|
37
|
+
result.version = projMatch[2];
|
|
38
|
+
}
|
|
39
|
+
// 解析 add_subdirectory()
|
|
40
|
+
const subdirRe = new RegExp(ADD_SUBDIRECTORY_RE.source, 'g');
|
|
41
|
+
let m;
|
|
42
|
+
while ((m = subdirRe.exec(cleaned)) !== null) {
|
|
43
|
+
result.subdirectories.push(m[1]);
|
|
44
|
+
}
|
|
45
|
+
// 解析 add_library()
|
|
46
|
+
const targetMap = new Map();
|
|
47
|
+
const libRe = new RegExp(ADD_LIBRARY_RE.source, 'gs');
|
|
48
|
+
while ((m = libRe.exec(cleaned)) !== null) {
|
|
49
|
+
const name = m[1];
|
|
50
|
+
const typeStr = (m[2] ?? 'STATIC').toUpperCase();
|
|
51
|
+
const sourcesStr = m[3] ?? '';
|
|
52
|
+
const typeMap = {
|
|
53
|
+
STATIC: 'static-library',
|
|
54
|
+
SHARED: 'shared-library',
|
|
55
|
+
INTERFACE: 'interface-library',
|
|
56
|
+
MODULE: 'shared-library',
|
|
57
|
+
OBJECT: 'static-library',
|
|
58
|
+
};
|
|
59
|
+
const target = {
|
|
60
|
+
name,
|
|
61
|
+
type: typeMap[typeStr] ?? 'static-library',
|
|
62
|
+
sources: extractSourceFiles(sourcesStr),
|
|
63
|
+
linkDependencies: [],
|
|
64
|
+
};
|
|
65
|
+
targetMap.set(name, target);
|
|
66
|
+
}
|
|
67
|
+
// 解析 add_executable()
|
|
68
|
+
const exeRe = new RegExp(ADD_EXECUTABLE_RE.source, 'gs');
|
|
69
|
+
while ((m = exeRe.exec(cleaned)) !== null) {
|
|
70
|
+
const name = m[1];
|
|
71
|
+
const sourcesStr = m[2] ?? '';
|
|
72
|
+
const target = {
|
|
73
|
+
name,
|
|
74
|
+
type: 'executable',
|
|
75
|
+
sources: extractSourceFiles(sourcesStr),
|
|
76
|
+
linkDependencies: [],
|
|
77
|
+
};
|
|
78
|
+
targetMap.set(name, target);
|
|
79
|
+
}
|
|
80
|
+
// 解析 target_link_libraries()
|
|
81
|
+
const linkRe = new RegExp(TARGET_LINK_RE.source, 'gs');
|
|
82
|
+
while ((m = linkRe.exec(cleaned)) !== null) {
|
|
83
|
+
const targetName = m[1];
|
|
84
|
+
const depsStr = m[2];
|
|
85
|
+
const target = targetMap.get(targetName);
|
|
86
|
+
if (!target) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
target.linkDependencies = parseLinkDependencies(depsStr);
|
|
90
|
+
}
|
|
91
|
+
result.targets = [...targetMap.values()];
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
// ── 内部函数 ────────────────────────────────────────
|
|
95
|
+
function removeComments(content) {
|
|
96
|
+
return content
|
|
97
|
+
.split('\n')
|
|
98
|
+
.map((line) => {
|
|
99
|
+
const commentIdx = line.indexOf('#');
|
|
100
|
+
if (commentIdx === -1) {
|
|
101
|
+
return line;
|
|
102
|
+
}
|
|
103
|
+
// 简单处理:不检查字符串内的 #
|
|
104
|
+
return line.substring(0, commentIdx);
|
|
105
|
+
})
|
|
106
|
+
.join('\n');
|
|
107
|
+
}
|
|
108
|
+
function extractSourceFiles(str) {
|
|
109
|
+
const sources = [];
|
|
110
|
+
// 提取非关键字的 token
|
|
111
|
+
const tokens = str.trim().split(/\s+/);
|
|
112
|
+
for (const token of tokens) {
|
|
113
|
+
const clean = token.trim();
|
|
114
|
+
if (clean === '' ||
|
|
115
|
+
clean === 'STATIC' ||
|
|
116
|
+
clean === 'SHARED' ||
|
|
117
|
+
clean === 'INTERFACE' ||
|
|
118
|
+
clean === 'MODULE' ||
|
|
119
|
+
clean === 'OBJECT' ||
|
|
120
|
+
clean === 'PUBLIC' ||
|
|
121
|
+
clean === 'PRIVATE' ||
|
|
122
|
+
clean === 'IMPORTED' ||
|
|
123
|
+
clean === 'ALIAS' ||
|
|
124
|
+
clean === 'EXCLUDE_FROM_ALL' ||
|
|
125
|
+
clean.startsWith('$')) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
sources.push(clean);
|
|
129
|
+
}
|
|
130
|
+
return sources;
|
|
131
|
+
}
|
|
132
|
+
function parseLinkDependencies(str) {
|
|
133
|
+
const deps = [];
|
|
134
|
+
const tokens = str.trim().split(/\s+/);
|
|
135
|
+
let currentScope = 'PUBLIC';
|
|
136
|
+
for (const token of tokens) {
|
|
137
|
+
const clean = token.trim();
|
|
138
|
+
if (clean === 'PUBLIC' || clean === 'PRIVATE' || clean === 'INTERFACE') {
|
|
139
|
+
currentScope = clean;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (clean === '' || clean.startsWith('$') || clean.startsWith('#')) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
deps.push({ target: clean, scope: currentScope });
|
|
146
|
+
}
|
|
147
|
+
return deps;
|
|
148
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module GradleDslParser
|
|
3
|
+
* @description Gradle DSL 轻量解析器 — 从 settings.gradle.kts / build.gradle.kts 提取项目拓扑
|
|
4
|
+
*
|
|
5
|
+
* 支持解析:
|
|
6
|
+
* - settings.gradle.kts: rootProject.name + include() 模块声明
|
|
7
|
+
* - build.gradle.kts: plugins {} + dependencies {} (project-to-project)
|
|
8
|
+
* - settings.gradle (Groovy 语法)
|
|
9
|
+
*
|
|
10
|
+
* 同时支持 Kotlin DSL 和 Groovy DSL 的正则模式。
|
|
11
|
+
*/
|
|
12
|
+
export interface ParsedGradleProject {
|
|
13
|
+
rootProjectName: string;
|
|
14
|
+
includedModules: GradleModule[];
|
|
15
|
+
versionCatalog?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface GradleModule {
|
|
18
|
+
path: string;
|
|
19
|
+
directory: string;
|
|
20
|
+
conventionPlugin?: string;
|
|
21
|
+
dependencies: GradleDep[];
|
|
22
|
+
}
|
|
23
|
+
export interface GradleDep {
|
|
24
|
+
configuration: string;
|
|
25
|
+
target: string;
|
|
26
|
+
isProject: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 解析 settings.gradle.kts / settings.gradle 内容
|
|
30
|
+
* 提取 rootProject 名和所有 include 模块
|
|
31
|
+
*
|
|
32
|
+
* 当传入 build 文件内容时(附带 module 参数),解析 plugins 和 dependencies 到该模块上
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseGradleProject(content: string, existingModule?: GradleModule): ParsedGradleProject;
|
|
35
|
+
/**
|
|
36
|
+
* 检测 build 文件中是否使用了 Kotlin Multiplatform 插件
|
|
37
|
+
*/
|
|
38
|
+
export declare function isKmpBuildFile(content: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* 从 convention plugin id 推断模块角色
|
|
41
|
+
* 例: "myapp.android.feature" → "feature"
|
|
42
|
+
*/
|
|
43
|
+
export declare function inferConventionRole(pluginId: string): string | undefined;
|