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
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CleanupService —
|
|
2
|
+
* CleanupService — 统一数据清理策略(垃圾桶模式)
|
|
3
3
|
*
|
|
4
4
|
* 提供两种清理模式:
|
|
5
|
-
* - fullReset():
|
|
6
|
-
* - rescanClean(): Rescan
|
|
5
|
+
* - fullReset(): 全量清理 — 将旧数据打包到时间戳垃圾桶文件夹,DB 表清空
|
|
6
|
+
* - rescanClean(): Rescan 清理 — 保留 Recipe,清除衍生缓存
|
|
7
7
|
* - snapshotRecipes(): 快照当前活跃 Recipe 信息
|
|
8
|
+
* - purgeExpiredTrash(): 清除超时限的垃圾桶文件夹
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
+
* 垃圾桶设计:
|
|
11
|
+
* - 位于 .autosnippet/.trash/<ISO-timestamp>/ 下
|
|
12
|
+
* - fullReset 时先将 candidates/ recipes/ skills/ wiki/ 移入垃圾桶,再清 DB
|
|
13
|
+
* - DB 数据导出为 db-snapshot.jsonl 保存在垃圾桶内
|
|
14
|
+
* - 超过保留天数(默认 7 天)的垃圾桶在下次 fullReset 或服务启动时自动清除
|
|
15
|
+
* - 暂不提供恢复功能(需要 merge 处理过于复杂)
|
|
16
|
+
*
|
|
17
|
+
* 保留原则:
|
|
10
18
|
* - 配置数据 (config.json, constitution.yaml, boxspec.json) 永不清理
|
|
11
19
|
* - IDE 集成配置 (.vscode/, .cursor/, .github/) 永不清理
|
|
12
20
|
* - 交付物 (.cursor/rules/autosnippet-*) 由 R4 重建,不在此清理
|
|
@@ -24,6 +32,22 @@ export interface CleanupResult {
|
|
|
24
32
|
clearedTables: string[];
|
|
25
33
|
preservedRecipes: number;
|
|
26
34
|
errors: string[];
|
|
35
|
+
/** 垃圾桶信息(fullReset 时填充) */
|
|
36
|
+
trash?: {
|
|
37
|
+
/** 垃圾桶文件夹路径 */
|
|
38
|
+
folder: string;
|
|
39
|
+
/** 移入垃圾桶的文件/目录数 */
|
|
40
|
+
movedItems: number;
|
|
41
|
+
/** DB 快照行数 */
|
|
42
|
+
dbSnapshotRows: number;
|
|
43
|
+
};
|
|
44
|
+
/** 本次清除的过期垃圾桶 */
|
|
45
|
+
purgedTrash?: {
|
|
46
|
+
/** 清除的垃圾桶数 */
|
|
47
|
+
count: number;
|
|
48
|
+
/** 释放的磁盘空间估算 (bytes) */
|
|
49
|
+
freedBytes: number;
|
|
50
|
+
};
|
|
27
51
|
}
|
|
28
52
|
/** Recipe 快照条目 */
|
|
29
53
|
export interface RecipeSnapshotEntry {
|
|
@@ -60,10 +84,16 @@ export declare class CleanupService {
|
|
|
60
84
|
/** 更新 DB 引用(fullReset 后重连时调用) */
|
|
61
85
|
setDb(db: unknown): void;
|
|
62
86
|
/**
|
|
63
|
-
* 全量清理 — 用于 bootstrap
|
|
87
|
+
* 全量清理 — 用于 bootstrap 冷启动(垃圾桶模式)
|
|
88
|
+
*
|
|
89
|
+
* 流程:
|
|
90
|
+
* 1. 先清除过期垃圾桶(超过 TRASH_RETENTION_DAYS)
|
|
91
|
+
* 2. 创建时间戳垃圾桶文件夹
|
|
92
|
+
* 3. 将 candidates/ recipes/ skills/ wiki/ 移入垃圾桶
|
|
93
|
+
* 4. 导出 DB 关键表数据到 db-snapshot.jsonl
|
|
94
|
+
* 5. 清空 DB 所有数据表
|
|
95
|
+
* 6. 清除向量索引、bootstrap-report、logs 等缓存
|
|
64
96
|
*
|
|
65
|
-
* 清除: DB 所有数据表、candidates/、recipes/、skills/、wiki/、
|
|
66
|
-
* 向量索引、bootstrap-report.json、logs/signals/
|
|
67
97
|
* 保留: config.json、constitution.yaml、boxspec.json、IDE 配置
|
|
68
98
|
*/
|
|
69
99
|
fullReset(): Promise<CleanupResult>;
|
|
@@ -81,5 +111,22 @@ export declare class CleanupService {
|
|
|
81
111
|
* 用于 rescan 前记录保留的知识条目
|
|
82
112
|
*/
|
|
83
113
|
snapshotRecipes(): Promise<RecipeSnapshot>;
|
|
114
|
+
/**
|
|
115
|
+
* 清除超过保留期限的垃圾桶文件夹
|
|
116
|
+
* 可在服务启动时或 fullReset 前调用
|
|
117
|
+
*/
|
|
118
|
+
purgeExpiredTrash(): {
|
|
119
|
+
count: number;
|
|
120
|
+
freedBytes: number;
|
|
121
|
+
folders: string[];
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* 列出当前所有垃圾桶(供 Dashboard 展示)
|
|
125
|
+
*/
|
|
126
|
+
listTrashFolders(): Array<{
|
|
127
|
+
name: string;
|
|
128
|
+
createdAt: Date;
|
|
129
|
+
sizeMB: number;
|
|
130
|
+
}>;
|
|
84
131
|
}
|
|
85
132
|
export {};
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CleanupService —
|
|
2
|
+
* CleanupService — 统一数据清理策略(垃圾桶模式)
|
|
3
3
|
*
|
|
4
4
|
* 提供两种清理模式:
|
|
5
|
-
* - fullReset():
|
|
6
|
-
* - rescanClean(): Rescan
|
|
5
|
+
* - fullReset(): 全量清理 — 将旧数据打包到时间戳垃圾桶文件夹,DB 表清空
|
|
6
|
+
* - rescanClean(): Rescan 清理 — 保留 Recipe,清除衍生缓存
|
|
7
7
|
* - snapshotRecipes(): 快照当前活跃 Recipe 信息
|
|
8
|
+
* - purgeExpiredTrash(): 清除超时限的垃圾桶文件夹
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
+
* 垃圾桶设计:
|
|
11
|
+
* - 位于 .autosnippet/.trash/<ISO-timestamp>/ 下
|
|
12
|
+
* - fullReset 时先将 candidates/ recipes/ skills/ wiki/ 移入垃圾桶,再清 DB
|
|
13
|
+
* - DB 数据导出为 db-snapshot.jsonl 保存在垃圾桶内
|
|
14
|
+
* - 超过保留天数(默认 7 天)的垃圾桶在下次 fullReset 或服务启动时自动清除
|
|
15
|
+
* - 暂不提供恢复功能(需要 merge 处理过于复杂)
|
|
16
|
+
*
|
|
17
|
+
* 保留原则:
|
|
10
18
|
* - 配置数据 (config.json, constitution.yaml, boxspec.json) 永不清理
|
|
11
19
|
* - IDE 集成配置 (.vscode/, .cursor/, .github/) 永不清理
|
|
12
20
|
* - 交付物 (.cursor/rules/autosnippet-*) 由 R4 重建,不在此清理
|
|
@@ -17,37 +25,54 @@ import fs from 'node:fs';
|
|
|
17
25
|
import path from 'node:path';
|
|
18
26
|
import { CANDIDATES_DIR } from '#infra/config/Defaults.js';
|
|
19
27
|
import { getContextIndexPath, getProjectKnowledgePath, getProjectRecipesPath, getProjectSkillsPath, } from '#infra/config/Paths.js';
|
|
28
|
+
import { CONSUMABLE_LIFECYCLES, lifecycleInSql } from '../../domain/knowledge/Lifecycle.js';
|
|
20
29
|
// ── 常量 ────────────────────────────────────────────────────
|
|
21
|
-
/**
|
|
30
|
+
/** 垃圾桶根目录(相对于 .autosnippet/) */
|
|
31
|
+
const TRASH_DIR = '.trash';
|
|
32
|
+
/** 垃圾桶保留天数,超过后自动 purge */
|
|
33
|
+
const TRASH_RETENTION_DAYS = 7;
|
|
34
|
+
/** DB 快照文件名 */
|
|
35
|
+
const DB_SNAPSHOT_FILE = 'db-snapshot.jsonl';
|
|
36
|
+
/**
|
|
37
|
+
* fullReset 时清除的所有 DB 表(不含 schema_migrations)
|
|
38
|
+
*
|
|
39
|
+
* ⚠️ 顺序重要:子表必须排在父表之前,否则 FK 约束会阻止 DELETE。
|
|
40
|
+
* lifecycle_transition_events → knowledge_entries, evolution_proposals
|
|
41
|
+
* evolution_proposals → knowledge_entries
|
|
42
|
+
* recipe_source_refs → knowledge_entries (CASCADE)
|
|
43
|
+
* bootstrap_dim_files → bootstrap_snapshots (CASCADE)
|
|
44
|
+
*/
|
|
22
45
|
const ALL_DATA_TABLES = [
|
|
23
|
-
|
|
46
|
+
// ── FK 子表先删 ──
|
|
47
|
+
'lifecycle_transition_events',
|
|
48
|
+
'recipe_source_refs',
|
|
49
|
+
'evolution_proposals',
|
|
24
50
|
'knowledge_edges',
|
|
51
|
+
'bootstrap_dim_files',
|
|
52
|
+
// ── 父表后删 ──
|
|
53
|
+
'knowledge_entries',
|
|
54
|
+
'bootstrap_snapshots',
|
|
55
|
+
// ── 无 FK 依赖 ──
|
|
25
56
|
'guard_violations',
|
|
26
57
|
'audit_logs',
|
|
27
58
|
'sessions',
|
|
28
|
-
'token_usage',
|
|
29
59
|
'semantic_memories',
|
|
30
|
-
'bootstrap_snapshots',
|
|
31
|
-
'bootstrap_dim_files',
|
|
32
60
|
'code_entities',
|
|
33
61
|
'remote_commands',
|
|
34
62
|
'remote_state',
|
|
35
|
-
'evolution_proposals',
|
|
36
|
-
'recipe_source_refs',
|
|
37
63
|
];
|
|
38
64
|
/** rescanClean 时清除的 DB 表(保留知识/进化相关表) */
|
|
39
65
|
const RESCAN_CLEAN_TABLES = [
|
|
66
|
+
'bootstrap_dim_files', // FK → bootstrap_snapshots, 先删
|
|
67
|
+
'recipe_source_refs', // FK → knowledge_entries, 先删
|
|
68
|
+
'bootstrap_snapshots',
|
|
40
69
|
'code_entities',
|
|
41
70
|
'guard_violations',
|
|
42
|
-
'bootstrap_snapshots',
|
|
43
|
-
'bootstrap_dim_files',
|
|
44
71
|
'semantic_memories',
|
|
45
72
|
'sessions',
|
|
46
73
|
'audit_logs',
|
|
47
|
-
'token_usage',
|
|
48
74
|
'remote_commands',
|
|
49
75
|
'remote_state',
|
|
50
|
-
'recipe_source_refs',
|
|
51
76
|
];
|
|
52
77
|
// ── CleanupService ──────────────────────────────────────────
|
|
53
78
|
export class CleanupService {
|
|
@@ -71,12 +96,18 @@ export class CleanupService {
|
|
|
71
96
|
: db
|
|
72
97
|
: null;
|
|
73
98
|
}
|
|
74
|
-
// ─── 需求 A
|
|
99
|
+
// ─── 需求 A:全量清理(垃圾桶模式) ────────────────────
|
|
75
100
|
/**
|
|
76
|
-
* 全量清理 — 用于 bootstrap
|
|
101
|
+
* 全量清理 — 用于 bootstrap 冷启动(垃圾桶模式)
|
|
102
|
+
*
|
|
103
|
+
* 流程:
|
|
104
|
+
* 1. 先清除过期垃圾桶(超过 TRASH_RETENTION_DAYS)
|
|
105
|
+
* 2. 创建时间戳垃圾桶文件夹
|
|
106
|
+
* 3. 将 candidates/ recipes/ skills/ wiki/ 移入垃圾桶
|
|
107
|
+
* 4. 导出 DB 关键表数据到 db-snapshot.jsonl
|
|
108
|
+
* 5. 清空 DB 所有数据表
|
|
109
|
+
* 6. 清除向量索引、bootstrap-report、logs 等缓存
|
|
77
110
|
*
|
|
78
|
-
* 清除: DB 所有数据表、candidates/、recipes/、skills/、wiki/、
|
|
79
|
-
* 向量索引、bootstrap-report.json、logs/signals/
|
|
80
111
|
* 保留: config.json、constitution.yaml、boxspec.json、IDE 配置
|
|
81
112
|
*/
|
|
82
113
|
async fullReset() {
|
|
@@ -86,8 +117,34 @@ export class CleanupService {
|
|
|
86
117
|
preservedRecipes: 0,
|
|
87
118
|
errors: [],
|
|
88
119
|
};
|
|
89
|
-
this.#logger.info('[CleanupService] Starting fullReset...');
|
|
90
|
-
//
|
|
120
|
+
this.#logger.info('[CleanupService] Starting fullReset (trash-bin mode)...');
|
|
121
|
+
// 0. 清除过期垃圾桶
|
|
122
|
+
const purged = this.#purgeExpiredTrash();
|
|
123
|
+
if (purged.count > 0) {
|
|
124
|
+
result.purgedTrash = purged;
|
|
125
|
+
this.#logger.info(`[CleanupService] Purged ${purged.count} expired trash folders`);
|
|
126
|
+
}
|
|
127
|
+
// 1. 创建时间戳垃圾桶文件夹
|
|
128
|
+
const trashFolder = this.#createTrashFolder();
|
|
129
|
+
let movedItems = 0;
|
|
130
|
+
let dbSnapshotRows = 0;
|
|
131
|
+
// 2. 将知识目录移入垃圾桶(move 而非 copy,速度快)
|
|
132
|
+
const kbPath = getProjectKnowledgePath(this.#projectRoot);
|
|
133
|
+
const dirsToTrash = [
|
|
134
|
+
{ src: path.join(this.#projectRoot, CANDIDATES_DIR), name: 'candidates' },
|
|
135
|
+
{ src: getProjectRecipesPath(this.#projectRoot), name: 'recipes' },
|
|
136
|
+
{ src: getProjectSkillsPath(this.#projectRoot), name: 'skills' },
|
|
137
|
+
{ src: path.join(kbPath, 'wiki'), name: 'wiki' },
|
|
138
|
+
];
|
|
139
|
+
for (const { src, name } of dirsToTrash) {
|
|
140
|
+
const moved = this.#moveToTrash(src, path.join(trashFolder, name));
|
|
141
|
+
movedItems += moved;
|
|
142
|
+
}
|
|
143
|
+
// 3. 导出 DB 数据到垃圾桶(JSONL 格式,每行一个 {table, row})
|
|
144
|
+
if (this.#db) {
|
|
145
|
+
dbSnapshotRows = this.#exportDbToTrash(trashFolder);
|
|
146
|
+
}
|
|
147
|
+
// 4. 清空 DB 所有数据表
|
|
91
148
|
if (this.#db) {
|
|
92
149
|
for (const table of ALL_DATA_TABLES) {
|
|
93
150
|
try {
|
|
@@ -96,14 +153,14 @@ export class CleanupService {
|
|
|
96
153
|
}
|
|
97
154
|
catch (err) {
|
|
98
155
|
const msg = err instanceof Error ? err.message : String(err);
|
|
99
|
-
// 表可能不存在(未 migrate),跳过
|
|
100
156
|
if (!msg.includes('no such table')) {
|
|
101
157
|
result.errors.push(`Failed to clear ${table}: ${msg}`);
|
|
158
|
+
this.#logger.warn(`[CleanupService] DELETE FROM ${table} failed: ${msg}`);
|
|
102
159
|
}
|
|
103
160
|
}
|
|
104
161
|
}
|
|
105
|
-
//
|
|
106
|
-
for (const table of ['
|
|
162
|
+
// tasks 相关表(来自 migration 002,需先删子表)
|
|
163
|
+
for (const table of ['task_events', 'task_dependencies', 'tasks']) {
|
|
107
164
|
try {
|
|
108
165
|
this.#db.exec(`DELETE FROM ${table}`);
|
|
109
166
|
result.clearedTables.push(table);
|
|
@@ -113,23 +170,30 @@ export class CleanupService {
|
|
|
113
170
|
}
|
|
114
171
|
}
|
|
115
172
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
173
|
+
else {
|
|
174
|
+
this.#logger.warn('[CleanupService] No database reference — DB tables NOT cleared!');
|
|
175
|
+
result.errors.push('DB reference is null, database tables were not cleared');
|
|
176
|
+
}
|
|
177
|
+
// 5. 重建被移走的空目录(bootstrap 后续步骤需要)
|
|
178
|
+
for (const { src } of dirsToTrash) {
|
|
179
|
+
if (!fs.existsSync(src)) {
|
|
180
|
+
fs.mkdirSync(src, { recursive: true });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// 6. 清除向量索引
|
|
125
184
|
result.deletedFiles += this.#clearDirectory(getContextIndexPath(this.#projectRoot));
|
|
126
185
|
// 7. 删除 bootstrap-report.json
|
|
127
|
-
result.deletedFiles += this.#deleteFile(path.join(
|
|
186
|
+
result.deletedFiles += this.#deleteFile(path.join(kbPath, '.autosnippet', 'bootstrap-report.json'));
|
|
128
187
|
// 8. 清除 logs/signals/
|
|
129
|
-
result.deletedFiles += this.#clearDirectory(path.join(
|
|
130
|
-
|
|
188
|
+
result.deletedFiles += this.#clearDirectory(path.join(kbPath, '.autosnippet', 'logs', 'signals'));
|
|
189
|
+
result.deletedFiles += movedItems;
|
|
190
|
+
result.trash = { folder: trashFolder, movedItems, dbSnapshotRows };
|
|
191
|
+
this.#logger.info('[CleanupService] fullReset complete (trash-bin mode)', {
|
|
192
|
+
trashFolder: path.basename(trashFolder),
|
|
193
|
+
movedItems,
|
|
194
|
+
dbSnapshotRows,
|
|
131
195
|
tables: result.clearedTables.length,
|
|
132
|
-
|
|
196
|
+
purgedExpired: purged.count,
|
|
133
197
|
errors: result.errors.length,
|
|
134
198
|
});
|
|
135
199
|
return result;
|
|
@@ -212,12 +276,15 @@ export class CleanupService {
|
|
|
212
276
|
return { count: 0, entries: [], coverageByDimension: {} };
|
|
213
277
|
}
|
|
214
278
|
try {
|
|
279
|
+
const { sql: lcFilter, params: lcParams } = lifecycleInSql(CONSUMABLE_LIFECYCLES);
|
|
215
280
|
const rows = this.#db
|
|
216
|
-
.prepare(
|
|
281
|
+
.prepare(
|
|
282
|
+
// @escape-hatch(permanent) — dynamic lifecycle filter + json_extract
|
|
283
|
+
`SELECT id, title, trigger, category, knowledgeType, doClause,
|
|
217
284
|
sourceFile, lifecycle, content, json_extract(reasoning, '$.sources') AS sourceRefsJson
|
|
218
285
|
FROM knowledge_entries
|
|
219
|
-
WHERE
|
|
220
|
-
.all();
|
|
286
|
+
WHERE ${lcFilter}`)
|
|
287
|
+
.all(...lcParams);
|
|
221
288
|
const entries = rows.map((r) => {
|
|
222
289
|
let parsedContent;
|
|
223
290
|
try {
|
|
@@ -268,7 +335,191 @@ export class CleanupService {
|
|
|
268
335
|
return { count: 0, entries: [], coverageByDimension: {} };
|
|
269
336
|
}
|
|
270
337
|
}
|
|
338
|
+
// ─── 垃圾桶管理 ───────────────────────────────────────
|
|
339
|
+
/**
|
|
340
|
+
* 清除超过保留期限的垃圾桶文件夹
|
|
341
|
+
* 可在服务启动时或 fullReset 前调用
|
|
342
|
+
*/
|
|
343
|
+
purgeExpiredTrash() {
|
|
344
|
+
return this.#purgeExpiredTrash();
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* 列出当前所有垃圾桶(供 Dashboard 展示)
|
|
348
|
+
*/
|
|
349
|
+
listTrashFolders() {
|
|
350
|
+
const trashRoot = this.#getTrashRoot();
|
|
351
|
+
if (!fs.existsSync(trashRoot)) {
|
|
352
|
+
return [];
|
|
353
|
+
}
|
|
354
|
+
const entries = fs.readdirSync(trashRoot).sort().reverse();
|
|
355
|
+
return entries
|
|
356
|
+
.filter((name) => /^\d{4}-\d{2}-\d{2}T/.test(name))
|
|
357
|
+
.map((name) => {
|
|
358
|
+
const fullPath = path.join(trashRoot, name);
|
|
359
|
+
const stat = fs.statSync(fullPath);
|
|
360
|
+
return {
|
|
361
|
+
name,
|
|
362
|
+
createdAt: stat.birthtime,
|
|
363
|
+
sizeMB: Math.round((this.#getDirSize(fullPath) / 1024 / 1024) * 100) / 100,
|
|
364
|
+
};
|
|
365
|
+
});
|
|
366
|
+
}
|
|
271
367
|
// ─── 内部工具方法 ─────────────────────────────────────
|
|
368
|
+
/** 获取垃圾桶根目录 (.autosnippet/.trash/) */
|
|
369
|
+
#getTrashRoot() {
|
|
370
|
+
return path.join(this.#projectRoot, '.autosnippet', TRASH_DIR);
|
|
371
|
+
}
|
|
372
|
+
/** 创建时间戳垃圾桶文件夹,返回绝对路径 */
|
|
373
|
+
#createTrashFolder() {
|
|
374
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
375
|
+
const trashFolder = path.join(this.#getTrashRoot(), ts);
|
|
376
|
+
fs.mkdirSync(trashFolder, { recursive: true });
|
|
377
|
+
return trashFolder;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* 将源目录内容移入垃圾桶对应子目录
|
|
381
|
+
* 使用 rename 实现(同文件系统内是原子操作,速度极快)
|
|
382
|
+
* @returns 移动的顶层条目数
|
|
383
|
+
*/
|
|
384
|
+
#moveToTrash(srcDir, trashSubDir) {
|
|
385
|
+
if (!fs.existsSync(srcDir)) {
|
|
386
|
+
return 0;
|
|
387
|
+
}
|
|
388
|
+
const entries = fs.readdirSync(srcDir);
|
|
389
|
+
if (entries.length === 0) {
|
|
390
|
+
return 0;
|
|
391
|
+
}
|
|
392
|
+
fs.mkdirSync(trashSubDir, { recursive: true });
|
|
393
|
+
let count = 0;
|
|
394
|
+
for (const entry of entries) {
|
|
395
|
+
const src = path.join(srcDir, entry);
|
|
396
|
+
const dest = path.join(trashSubDir, entry);
|
|
397
|
+
try {
|
|
398
|
+
fs.renameSync(src, dest);
|
|
399
|
+
count++;
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
// rename 可能跨设备失败,fallback 到 copy+delete
|
|
403
|
+
try {
|
|
404
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
405
|
+
fs.rmSync(src, { recursive: true, force: true });
|
|
406
|
+
count++;
|
|
407
|
+
}
|
|
408
|
+
catch (err) {
|
|
409
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
410
|
+
this.#logger.warn(`[CleanupService] Failed to move ${entry} to trash: ${msg}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return count;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* 导出 DB 关键表数据到垃圾桶(JSONL 格式)
|
|
418
|
+
* 只导出有实际业务数据的表,跳过纯缓存表
|
|
419
|
+
*/
|
|
420
|
+
#exportDbToTrash(trashFolder) {
|
|
421
|
+
if (!this.#db) {
|
|
422
|
+
return 0;
|
|
423
|
+
}
|
|
424
|
+
const tablesToExport = [
|
|
425
|
+
'knowledge_entries',
|
|
426
|
+
'knowledge_edges',
|
|
427
|
+
'lifecycle_transition_events',
|
|
428
|
+
'evolution_proposals',
|
|
429
|
+
'recipe_source_refs',
|
|
430
|
+
'guard_violations',
|
|
431
|
+
];
|
|
432
|
+
const snapshotPath = path.join(trashFolder, DB_SNAPSHOT_FILE);
|
|
433
|
+
let totalRows = 0;
|
|
434
|
+
const lines = [];
|
|
435
|
+
for (const table of tablesToExport) {
|
|
436
|
+
try {
|
|
437
|
+
const rows = this.#db.prepare(`SELECT * FROM ${table}`).all(); // @escape-hatch(permanent) — dynamic table name for backup export
|
|
438
|
+
for (const row of rows) {
|
|
439
|
+
lines.push(JSON.stringify({ _table: table, ...row }));
|
|
440
|
+
totalRows++;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
// 表可能不存在,跳过
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (lines.length > 0) {
|
|
448
|
+
fs.writeFileSync(snapshotPath, `${lines.join('\n')}\n`, 'utf-8');
|
|
449
|
+
this.#logger.info(`[CleanupService] DB snapshot: ${totalRows} rows → ${DB_SNAPSHOT_FILE}`);
|
|
450
|
+
}
|
|
451
|
+
return totalRows;
|
|
452
|
+
}
|
|
453
|
+
/** 清除过期垃圾桶文件夹 */
|
|
454
|
+
#purgeExpiredTrash() {
|
|
455
|
+
const trashRoot = this.#getTrashRoot();
|
|
456
|
+
if (!fs.existsSync(trashRoot)) {
|
|
457
|
+
return { count: 0, freedBytes: 0, folders: [] };
|
|
458
|
+
}
|
|
459
|
+
const now = Date.now();
|
|
460
|
+
const maxAge = TRASH_RETENTION_DAYS * 24 * 60 * 60 * 1000;
|
|
461
|
+
const entries = fs.readdirSync(trashRoot);
|
|
462
|
+
let count = 0;
|
|
463
|
+
let freedBytes = 0;
|
|
464
|
+
const folders = [];
|
|
465
|
+
for (const entry of entries) {
|
|
466
|
+
const fullPath = path.join(trashRoot, entry);
|
|
467
|
+
try {
|
|
468
|
+
const stat = fs.statSync(fullPath);
|
|
469
|
+
if (!stat.isDirectory()) {
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
// 从文件夹名解析时间戳(格式: 2026-04-09T14-30-00-000Z)
|
|
473
|
+
const ts = entry.replace(/-(\d{2})-(\d{2})-(\d{3}Z)$/, ':$1:$2.$3');
|
|
474
|
+
const created = new Date(ts).getTime();
|
|
475
|
+
const age = now - (Number.isNaN(created) ? stat.birthtimeMs : created);
|
|
476
|
+
if (age > maxAge) {
|
|
477
|
+
const size = this.#getDirSize(fullPath);
|
|
478
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
479
|
+
freedBytes += size;
|
|
480
|
+
count++;
|
|
481
|
+
folders.push(entry);
|
|
482
|
+
this.#logger.info(`[CleanupService] Purged expired trash: ${entry} (${Math.round(size / 1024)}KB)`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
catch (err) {
|
|
486
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
487
|
+
this.#logger.warn(`[CleanupService] Failed to purge trash ${entry}: ${msg}`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// 如果垃圾桶根目录为空,也删掉
|
|
491
|
+
try {
|
|
492
|
+
const remaining = fs.readdirSync(trashRoot);
|
|
493
|
+
if (remaining.length === 0) {
|
|
494
|
+
fs.rmdirSync(trashRoot);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
/* ignore */
|
|
499
|
+
}
|
|
500
|
+
return { count, freedBytes, folders };
|
|
501
|
+
}
|
|
502
|
+
/** 递归计算目录大小 (bytes) */
|
|
503
|
+
#getDirSize(dirPath) {
|
|
504
|
+
let size = 0;
|
|
505
|
+
try {
|
|
506
|
+
const entries = fs.readdirSync(dirPath);
|
|
507
|
+
for (const entry of entries) {
|
|
508
|
+
const fullPath = path.join(dirPath, entry);
|
|
509
|
+
const stat = fs.statSync(fullPath);
|
|
510
|
+
if (stat.isDirectory()) {
|
|
511
|
+
size += this.#getDirSize(fullPath);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
size += stat.size;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
catch {
|
|
519
|
+
/* ignore */
|
|
520
|
+
}
|
|
521
|
+
return size;
|
|
522
|
+
}
|
|
272
523
|
/**
|
|
273
524
|
* 清空目录内容(保留目录本身)
|
|
274
525
|
* @returns 删除的文件数
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import fs from 'node:fs';
|
|
20
20
|
import path from 'node:path';
|
|
21
|
+
import { RawDbCallGraphAdapter, } from '../../repository/delivery/DeliveryRepoAdapter.js';
|
|
22
|
+
import { unwrapRawDb } from '../../repository/search/SearchRepoAdapter.js';
|
|
21
23
|
import { DELIVERY_RANK, KNOWLEDGE_CONFIDENCE } from '../../shared/constants.js';
|
|
22
24
|
import { DEFAULT_KNOWLEDGE_BASE_DIR } from '../../shared/ProjectMarkers.js';
|
|
23
25
|
import { AgentInstructionsGenerator } from './AgentInstructionsGenerator.js';
|
|
@@ -313,20 +315,16 @@ export class CursorDeliveryPipeline {
|
|
|
313
315
|
return null;
|
|
314
316
|
}
|
|
315
317
|
try {
|
|
316
|
-
const
|
|
318
|
+
const rawDb = unwrapRawDb(this.database);
|
|
319
|
+
const repo = new RawDbCallGraphAdapter(rawDb);
|
|
317
320
|
// 查询调用边中的跨目录调用模式
|
|
318
|
-
const callEdges =
|
|
319
|
-
.prepare(`SELECT from_id, to_id, metadata_json FROM knowledge_edges
|
|
320
|
-
WHERE relation = 'calls' AND metadata_json LIKE '%phase5%'`)
|
|
321
|
-
.all();
|
|
321
|
+
const callEdges = repo.findCallEdges();
|
|
322
322
|
if (!callEdges || callEdges.length < 5) {
|
|
323
323
|
return null;
|
|
324
324
|
}
|
|
325
325
|
// 提取 caller/callee 对应的文件路径
|
|
326
326
|
const entityFiles = new Map();
|
|
327
|
-
const entities =
|
|
328
|
-
.prepare(`SELECT entity_id, file_path FROM code_entities WHERE entity_type = 'method'`)
|
|
329
|
-
.all();
|
|
327
|
+
const entities = repo.findMethodEntities();
|
|
330
328
|
for (const e of entities) {
|
|
331
329
|
entityFiles.set(e.entity_id, e.file_path);
|
|
332
330
|
}
|
|
@@ -14,11 +14,7 @@
|
|
|
14
14
|
* 2. 语义域覆盖 — category + trigger 是否落在已有 Recipe 管辖范围
|
|
15
15
|
* 3. 独立价值 — 内容长度、具体性、是否有独立 coreCode
|
|
16
16
|
*/
|
|
17
|
-
|
|
18
|
-
prepare(sql: string): {
|
|
19
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
20
|
-
};
|
|
21
|
-
}
|
|
17
|
+
import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
22
18
|
/** 提交候选的必要字段 */
|
|
23
19
|
export interface CandidateForConsolidation {
|
|
24
20
|
title: string;
|
|
@@ -92,14 +88,14 @@ export interface BatchConsolidationResult {
|
|
|
92
88
|
}
|
|
93
89
|
export declare class ConsolidationAdvisor {
|
|
94
90
|
#private;
|
|
95
|
-
constructor(
|
|
91
|
+
constructor(knowledgeRepo: KnowledgeRepositoryImpl);
|
|
96
92
|
/**
|
|
97
93
|
* 分析候选知识与现有知识库的关系,返回融合建议。
|
|
98
94
|
*
|
|
99
95
|
* @param candidate - 待提交的候选数据
|
|
100
96
|
* @returns ConsolidationAdvice — 建议 + 理由 + 上下文
|
|
101
97
|
*/
|
|
102
|
-
analyze(candidate: CandidateForConsolidation): ConsolidationAdvice
|
|
98
|
+
analyze(candidate: CandidateForConsolidation): Promise<ConsolidationAdvice>;
|
|
103
99
|
/**
|
|
104
100
|
* 批量分析候选知识与现有知识库的关系。
|
|
105
101
|
*
|
|
@@ -109,6 +105,5 @@ export declare class ConsolidationAdvisor {
|
|
|
109
105
|
* @param candidates - 待提交的候选数组
|
|
110
106
|
* @returns BatchConsolidationResult — 每条分析 + 批次内重叠
|
|
111
107
|
*/
|
|
112
|
-
analyzeBatch(candidates: CandidateForConsolidation[]): BatchConsolidationResult
|
|
108
|
+
analyzeBatch(candidates: CandidateForConsolidation[]): Promise<BatchConsolidationResult>;
|
|
113
109
|
}
|
|
114
|
-
export {};
|