autosnippet 3.3.7 → 3.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +7 -4
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +4 -17
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.js +8 -4
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -1,16 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* QualityScorer — Recipe 质量评分器
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* QualityScorer v2 — Recipe 质量评分器
|
|
3
|
+
*
|
|
4
|
+
* 面向知识管理场景重新设计,采用渐进式评分(非二元判断),
|
|
5
|
+
* 充分利用 KnowledgeEntry 所有可用字段。
|
|
6
|
+
*
|
|
7
|
+
* 5 维度加权:
|
|
8
|
+
* - completeness (0.25): 结构完整性 — 核心字段齐全度
|
|
9
|
+
* - contentDepth (0.30): 内容深度 — markdown 丰富度、推理、溯源
|
|
10
|
+
* - deliveryReady (0.20): 交付就绪 — trigger/language/tags/category
|
|
11
|
+
* - actionability (0.15): 可操作性 — coreCode、do/dont/when 质量
|
|
12
|
+
* - provenance (0.10): 溯源可信 — confidence、sources、authority
|
|
13
|
+
*
|
|
14
|
+
* 设计参考:
|
|
15
|
+
* - RAG Triad (TruLens): Relevance + Groundedness + Answer Relevance
|
|
16
|
+
* - RAGAS: Context Precision + Faithfulness + Factual Correctness
|
|
17
|
+
* - SonarQube: 多维度渐进评级,非二元判断
|
|
5
18
|
*/
|
|
6
|
-
interface RecipeInput {
|
|
19
|
+
export interface RecipeInput {
|
|
7
20
|
title?: string;
|
|
8
21
|
trigger?: string;
|
|
9
|
-
|
|
22
|
+
description?: string;
|
|
10
23
|
language?: string;
|
|
11
24
|
category?: string;
|
|
12
|
-
|
|
25
|
+
doClause?: string;
|
|
26
|
+
dontClause?: string;
|
|
27
|
+
whenClause?: string;
|
|
28
|
+
coreCode?: string;
|
|
13
29
|
usageGuide?: string;
|
|
30
|
+
contentMarkdown?: string;
|
|
31
|
+
contentRationale?: string;
|
|
32
|
+
reasoningWhyStandard?: string;
|
|
33
|
+
reasoningSources?: string[];
|
|
34
|
+
reasoningConfidence?: number;
|
|
35
|
+
source?: string;
|
|
14
36
|
headers?: string[];
|
|
15
37
|
tags?: string[];
|
|
16
38
|
views?: number;
|
|
@@ -18,25 +40,23 @@ interface RecipeInput {
|
|
|
18
40
|
rating?: number;
|
|
19
41
|
[key: string]: unknown;
|
|
20
42
|
}
|
|
21
|
-
interface QualityScorerOptions {
|
|
22
|
-
weights?: Record<string, number>;
|
|
23
|
-
}
|
|
24
43
|
export declare class QualityScorer {
|
|
25
44
|
#private;
|
|
26
|
-
constructor(options?:
|
|
45
|
+
constructor(options?: {
|
|
46
|
+
weights?: Record<string, number>;
|
|
47
|
+
});
|
|
27
48
|
/**
|
|
28
49
|
* 计算综合质量分
|
|
29
|
-
* @
|
|
30
|
-
* @returns }
|
|
50
|
+
* @returns { score: 0-1, dimensions: Record<string,number>, grade: A-F }
|
|
31
51
|
*/
|
|
32
52
|
score(recipe: RecipeInput): {
|
|
33
53
|
score: number;
|
|
34
54
|
dimensions: {
|
|
35
55
|
completeness: number;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
56
|
+
contentDepth: number;
|
|
57
|
+
deliveryReady: number;
|
|
58
|
+
actionability: number;
|
|
59
|
+
provenance: number;
|
|
40
60
|
};
|
|
41
61
|
grade: string;
|
|
42
62
|
};
|
|
@@ -45,21 +65,20 @@ export declare class QualityScorer {
|
|
|
45
65
|
score: number;
|
|
46
66
|
dimensions: {
|
|
47
67
|
completeness: number;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
contentDepth: number;
|
|
69
|
+
deliveryReady: number;
|
|
70
|
+
actionability: number;
|
|
71
|
+
provenance: number;
|
|
52
72
|
};
|
|
53
73
|
grade: string;
|
|
54
74
|
recipe: RecipeInput;
|
|
55
75
|
}[];
|
|
56
76
|
/** 获取维度权重 */
|
|
57
77
|
getWeights(): {
|
|
58
|
-
completeness: 0.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
completeness: 0.25;
|
|
79
|
+
contentDepth: 0.3;
|
|
80
|
+
deliveryReady: 0.2;
|
|
81
|
+
actionability: 0.15;
|
|
82
|
+
provenance: 0.1;
|
|
63
83
|
};
|
|
64
84
|
}
|
|
65
|
-
export {};
|
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* QualityScorer — Recipe 质量评分器
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* QualityScorer v2 — Recipe 质量评分器
|
|
3
|
+
*
|
|
4
|
+
* 面向知识管理场景重新设计,采用渐进式评分(非二元判断),
|
|
5
|
+
* 充分利用 KnowledgeEntry 所有可用字段。
|
|
6
|
+
*
|
|
7
|
+
* 5 维度加权:
|
|
8
|
+
* - completeness (0.25): 结构完整性 — 核心字段齐全度
|
|
9
|
+
* - contentDepth (0.30): 内容深度 — markdown 丰富度、推理、溯源
|
|
10
|
+
* - deliveryReady (0.20): 交付就绪 — trigger/language/tags/category
|
|
11
|
+
* - actionability (0.15): 可操作性 — coreCode、do/dont/when 质量
|
|
12
|
+
* - provenance (0.10): 溯源可信 — confidence、sources、authority
|
|
13
|
+
*
|
|
14
|
+
* 设计参考:
|
|
15
|
+
* - RAG Triad (TruLens): Relevance + Groundedness + Answer Relevance
|
|
16
|
+
* - RAGAS: Context Precision + Faithfulness + Factual Correctness
|
|
17
|
+
* - SonarQube: 多维度渐进评级,非二元判断
|
|
5
18
|
*/
|
|
6
|
-
import {
|
|
19
|
+
import { QUALITY_GRADES, QUALITY_WEIGHTS } from '../../shared/constants.js';
|
|
20
|
+
import { LanguageProfiles } from '../../shared/LanguageProfiles.js';
|
|
7
21
|
const DEFAULT_WEIGHTS = QUALITY_WEIGHTS;
|
|
22
|
+
// ─── 渐进式评分辅助函数 ─────────────────────────────────
|
|
23
|
+
/** 文本长度渐进评分: 低于 minLen 给 20% 基础分,minLen→optimalLen 线性增长到满分 */
|
|
24
|
+
function textScore(text, minLen, optimalLen, weight) {
|
|
25
|
+
if (!text?.trim()) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
const len = text.trim().length;
|
|
29
|
+
if (len < minLen) {
|
|
30
|
+
return weight * 0.2;
|
|
31
|
+
}
|
|
32
|
+
if (len <= optimalLen) {
|
|
33
|
+
return weight * (0.5 + 0.5 * (len / optimalLen));
|
|
34
|
+
}
|
|
35
|
+
return weight;
|
|
36
|
+
}
|
|
37
|
+
/** 存在性检查: 有值给满分 */
|
|
38
|
+
function presenceScore(value, weight) {
|
|
39
|
+
return value?.trim() ? weight : 0;
|
|
40
|
+
}
|
|
8
41
|
export class QualityScorer {
|
|
9
42
|
#weights;
|
|
10
43
|
constructor(options = {}) {
|
|
@@ -12,16 +45,15 @@ export class QualityScorer {
|
|
|
12
45
|
}
|
|
13
46
|
/**
|
|
14
47
|
* 计算综合质量分
|
|
15
|
-
* @
|
|
16
|
-
* @returns }
|
|
48
|
+
* @returns { score: 0-1, dimensions: Record<string,number>, grade: A-F }
|
|
17
49
|
*/
|
|
18
50
|
score(recipe) {
|
|
19
51
|
const dimensions = {
|
|
20
52
|
completeness: this.#scoreCompleteness(recipe),
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
53
|
+
contentDepth: this.#scoreContentDepth(recipe),
|
|
54
|
+
deliveryReady: this.#scoreDeliveryReady(recipe),
|
|
55
|
+
actionability: this.#scoreActionability(recipe),
|
|
56
|
+
provenance: this.#scoreProvenance(recipe),
|
|
25
57
|
};
|
|
26
58
|
let totalScore = 0;
|
|
27
59
|
for (const [dim, weight] of Object.entries(this.#weights)) {
|
|
@@ -44,108 +76,150 @@ export class QualityScorer {
|
|
|
44
76
|
return { ...this.#weights };
|
|
45
77
|
}
|
|
46
78
|
// ─── 维度评分 ─────────────────────────────────────────
|
|
47
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* 结构完整性 (0-1)
|
|
81
|
+
* 渐进式检查核心字段齐全度
|
|
82
|
+
*/
|
|
48
83
|
#scoreCompleteness(r) {
|
|
49
84
|
let s = 0;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
85
|
+
s += textScore(r.title, 3, 40, 0.15);
|
|
86
|
+
s += presenceScore(r.trigger, 0.15);
|
|
87
|
+
s += textScore(r.description, 10, 60, 0.15);
|
|
88
|
+
s += textScore(r.doClause, 10, 50, 0.15);
|
|
89
|
+
s += textScore(r.whenClause, 10, 50, 0.15);
|
|
90
|
+
s += textScore(r.coreCode, 10, 200, 0.15);
|
|
91
|
+
s += presenceScore(r.dontClause, 0.1);
|
|
92
|
+
return Math.min(1, s);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 内容深度 (0-1)
|
|
96
|
+
* markdown 丰富度 + 结构化标记 + 设计原理 + 来源引用
|
|
97
|
+
*/
|
|
98
|
+
#scoreContentDepth(r) {
|
|
99
|
+
let s = 0;
|
|
100
|
+
const md = r.contentMarkdown || r.usageGuide || '';
|
|
101
|
+
// markdown 内容长度 (最优 200-800 字符)
|
|
102
|
+
s += textScore(md || undefined, 50, 800, 0.3);
|
|
103
|
+
// 结构化标记: 标题 / 代码块 / 列表
|
|
104
|
+
if (md) {
|
|
105
|
+
if (/^#{1,4}\s/m.test(md)) {
|
|
106
|
+
s += 0.08;
|
|
107
|
+
}
|
|
108
|
+
if (/```[\s\S]*?```|`[^`]+`/.test(md)) {
|
|
109
|
+
s += 0.08;
|
|
110
|
+
}
|
|
111
|
+
if (/^[\s]*[-*+]\s/m.test(md)) {
|
|
112
|
+
s += 0.04;
|
|
113
|
+
}
|
|
55
114
|
}
|
|
56
|
-
|
|
57
|
-
|
|
115
|
+
// rationale: 设计原理
|
|
116
|
+
s += textScore(r.contentRationale, 10, 100, 0.15);
|
|
117
|
+
// reasoning.whyStandard
|
|
118
|
+
s += textScore(r.reasoningWhyStandard, 10, 100, 0.15);
|
|
119
|
+
// reasoning.sources 来源文件
|
|
120
|
+
if (r.reasoningSources && r.reasoningSources.length > 0) {
|
|
121
|
+
s += Math.min(0.1, r.reasoningSources.length * 0.03);
|
|
58
122
|
}
|
|
59
|
-
|
|
60
|
-
|
|
123
|
+
// usageGuide(如果与 markdown 不同则额外加分)
|
|
124
|
+
if (r.usageGuide && r.usageGuide !== md) {
|
|
125
|
+
s += textScore(r.usageGuide, 20, 200, 0.1);
|
|
61
126
|
}
|
|
62
|
-
return s;
|
|
127
|
+
return Math.min(1, s);
|
|
63
128
|
}
|
|
64
|
-
/**
|
|
65
|
-
|
|
129
|
+
/**
|
|
130
|
+
* 交付就绪度 (0-1)
|
|
131
|
+
* trigger 格式 + language 合法性 + 分类 + 标签
|
|
132
|
+
*/
|
|
133
|
+
#scoreDeliveryReady(r) {
|
|
66
134
|
let s = 0;
|
|
135
|
+
// trigger 格式
|
|
67
136
|
if (r.trigger) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
r.trigger.length <= 64) {
|
|
71
|
-
s += 0.5;
|
|
72
|
-
}
|
|
73
|
-
else if (r.trigger.length >= 2) {
|
|
74
|
-
s += 0.25;
|
|
75
|
-
}
|
|
137
|
+
const valid = /^[a-zA-Z0-9_\-:.@]+$/.test(r.trigger) && r.trigger.length >= 2 && r.trigger.length <= 80;
|
|
138
|
+
s += valid ? 0.25 : r.trigger.length >= 2 ? 0.15 : 0;
|
|
76
139
|
}
|
|
140
|
+
// language 合法性
|
|
77
141
|
if (r.language) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
'c',
|
|
86
|
-
'cpp',
|
|
87
|
-
'shell',
|
|
88
|
-
'markdown',
|
|
89
|
-
]);
|
|
90
|
-
s += valid.has(r.language.toLowerCase()) ? 0.5 : 0.25;
|
|
91
|
-
}
|
|
92
|
-
return s;
|
|
93
|
-
}
|
|
94
|
-
/** 代码质量: 长度适中(0.3) + 无 TODO(0.2) + 有注释(0.3) + 有错误处理(0.2) */
|
|
95
|
-
#scoreCodeQuality(r) {
|
|
96
|
-
if (!r.code) {
|
|
97
|
-
return 0;
|
|
142
|
+
s += LanguageProfiles.validCodeLanguages.has(r.language.toLowerCase()) ? 0.25 : 0.1;
|
|
143
|
+
}
|
|
144
|
+
// category
|
|
145
|
+
s += presenceScore(r.category, 0.2);
|
|
146
|
+
// tags 丰富度
|
|
147
|
+
if (r.tags && r.tags.length > 0) {
|
|
148
|
+
s += Math.min(0.15, r.tags.length * 0.04);
|
|
98
149
|
}
|
|
150
|
+
// headers (语言相关导入声明)
|
|
151
|
+
if (r.headers && r.headers.length > 0) {
|
|
152
|
+
s += Math.min(0.15, r.headers.length * 0.05);
|
|
153
|
+
}
|
|
154
|
+
return Math.min(1, s);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 可操作性 (0-1)
|
|
158
|
+
* AI agent 能否基于此知识有效行动
|
|
159
|
+
*/
|
|
160
|
+
#scoreActionability(r) {
|
|
99
161
|
let s = 0;
|
|
100
|
-
const code = r.
|
|
101
|
-
|
|
102
|
-
|
|
162
|
+
const code = r.coreCode || '';
|
|
163
|
+
const md = r.contentMarkdown || r.usageGuide || '';
|
|
164
|
+
// 具体代码示例
|
|
165
|
+
const codeLen = code.trim().length;
|
|
166
|
+
if (codeLen >= 30 && codeLen <= 500) {
|
|
103
167
|
s += 0.3;
|
|
104
168
|
}
|
|
105
|
-
else if (
|
|
106
|
-
s += 0.
|
|
169
|
+
else if (codeLen >= 10) {
|
|
170
|
+
s += 0.2;
|
|
107
171
|
}
|
|
108
|
-
|
|
109
|
-
if (!/\b(TODO|FIXME|HACK|XXX)\b/.test(code)) {
|
|
172
|
+
else if (/```[\s\S]{10,}?```/.test(md)) {
|
|
110
173
|
s += 0.2;
|
|
111
174
|
}
|
|
112
|
-
//
|
|
113
|
-
if (
|
|
114
|
-
|
|
175
|
+
// doClause 具体度
|
|
176
|
+
if (r.doClause) {
|
|
177
|
+
const len = r.doClause.trim().length;
|
|
178
|
+
s += len >= 15 && len <= 200 ? 0.25 : len >= 5 ? 0.1 : 0;
|
|
115
179
|
}
|
|
116
|
-
//
|
|
117
|
-
if (
|
|
180
|
+
// 正反约束(do + don't → 引导更精确)
|
|
181
|
+
if (r.doClause?.trim() && r.dontClause?.trim()) {
|
|
118
182
|
s += 0.2;
|
|
119
183
|
}
|
|
120
|
-
|
|
184
|
+
else if (r.doClause?.trim()) {
|
|
185
|
+
s += 0.1;
|
|
186
|
+
}
|
|
187
|
+
// whenClause 具体度
|
|
188
|
+
if (r.whenClause) {
|
|
189
|
+
const len = r.whenClause.trim().length;
|
|
190
|
+
s += len >= 15 ? 0.25 : len >= 5 ? 0.1 : 0;
|
|
191
|
+
}
|
|
192
|
+
return Math.min(1, s);
|
|
121
193
|
}
|
|
122
|
-
/**
|
|
123
|
-
|
|
194
|
+
/**
|
|
195
|
+
* 溯源可信度 (0-1)
|
|
196
|
+
* 知识的可追溯性和可信度
|
|
197
|
+
*/
|
|
198
|
+
#scoreProvenance(r) {
|
|
124
199
|
let s = 0;
|
|
125
|
-
|
|
126
|
-
|
|
200
|
+
// AI confidence (0-1 → 0-0.30)
|
|
201
|
+
if (r.reasoningConfidence != null && r.reasoningConfidence > 0) {
|
|
202
|
+
s += r.reasoningConfidence * 0.3;
|
|
127
203
|
}
|
|
128
|
-
|
|
129
|
-
|
|
204
|
+
// 来源文件引用
|
|
205
|
+
if (r.reasoningSources && r.reasoningSources.length > 0) {
|
|
206
|
+
s += Math.min(0.3, r.reasoningSources.length * 0.1);
|
|
130
207
|
}
|
|
131
|
-
|
|
132
|
-
|
|
208
|
+
// 来源类型 (manual > mcp > bootstrap)
|
|
209
|
+
if (r.source === 'manual') {
|
|
210
|
+
s += 0.2;
|
|
133
211
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
/** 互动: views(0.3) + clicks(0.3) + rating(0.4) */
|
|
137
|
-
#scoreEngagement(r) {
|
|
138
|
-
let s = 0;
|
|
139
|
-
if (r.views && r.views > 0) {
|
|
140
|
-
s += Math.min(0.3, (r.views / 100) * 0.3);
|
|
212
|
+
else if (r.source === 'mcp') {
|
|
213
|
+
s += 0.15;
|
|
141
214
|
}
|
|
142
|
-
if (r.
|
|
143
|
-
s +=
|
|
215
|
+
else if (r.source === 'bootstrap' || r.source === 'cursor-scan') {
|
|
216
|
+
s += 0.1;
|
|
144
217
|
}
|
|
218
|
+
// usage authority (0-5 → 0-0.20)
|
|
145
219
|
if (r.rating && r.rating > 0) {
|
|
146
|
-
s += (r.rating / 5) * 0.
|
|
220
|
+
s += (r.rating / 5) * 0.2;
|
|
147
221
|
}
|
|
148
|
-
return s;
|
|
222
|
+
return Math.min(1, s);
|
|
149
223
|
}
|
|
150
224
|
/** 分数转等级 */
|
|
151
225
|
#toGrade(score) {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* 从 V1 SearchServiceV2 迁移,适配 V2 架构
|
|
6
6
|
*/
|
|
7
7
|
import Logger from '../../infrastructure/logging/Logger.js';
|
|
8
|
+
import { RawDbKnowledgeAdapter, RawDbSourceRefAdapter, unwrapSearchDb, } from '../../repository/search/SearchRepoAdapter.js';
|
|
8
9
|
import { CoarseRanker } from './CoarseRanker.js';
|
|
9
10
|
import { contextBoost } from './contextBoost.js';
|
|
10
11
|
import { FieldWeightedScorer } from './FieldWeightedScorer.js';
|
|
@@ -32,12 +33,19 @@ export class SearchEngine {
|
|
|
32
33
|
aiProvider;
|
|
33
34
|
db;
|
|
34
35
|
hybridRetriever;
|
|
36
|
+
#knowledgeRepo;
|
|
37
|
+
#sourceRefRepo;
|
|
35
38
|
logger;
|
|
36
39
|
scorer;
|
|
37
40
|
vectorService;
|
|
38
41
|
vectorStore;
|
|
39
42
|
constructor(db, options = {}) {
|
|
40
|
-
this.db = (
|
|
43
|
+
this.db = unwrapSearchDb(db);
|
|
44
|
+
const opts = options;
|
|
45
|
+
this.#knowledgeRepo =
|
|
46
|
+
opts.knowledgeRepo ?? new RawDbKnowledgeAdapter(this.db);
|
|
47
|
+
this.#sourceRefRepo =
|
|
48
|
+
opts.sourceRefRepo ?? new RawDbSourceRefAdapter(this.db);
|
|
41
49
|
this.logger = Logger.getInstance();
|
|
42
50
|
this.aiProvider = options.aiProvider || null;
|
|
43
51
|
this.vectorStore = options.vectorStore || null;
|
|
@@ -62,13 +70,8 @@ export class SearchEngine {
|
|
|
62
70
|
try {
|
|
63
71
|
let entries = [];
|
|
64
72
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
content, lifecycle, tags, trigger, difficulty, quality, stats,
|
|
68
|
-
updatedAt, createdAt
|
|
69
|
-
FROM knowledge_entries WHERE lifecycle != 'deprecated'`)
|
|
70
|
-
.all();
|
|
71
|
-
entries = entries.map((e) => ({
|
|
73
|
+
const rawEntries = this.#knowledgeRepo.findNonDeprecatedSync();
|
|
74
|
+
entries = rawEntries.map((e) => ({
|
|
72
75
|
...e,
|
|
73
76
|
status: e.lifecycle,
|
|
74
77
|
}));
|
|
@@ -316,12 +319,12 @@ export class SearchEngine {
|
|
|
316
319
|
try {
|
|
317
320
|
let rows = [];
|
|
318
321
|
try {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
322
|
+
const rawRows = this.#knowledgeRepo.keywordSearchSync(pattern, limit);
|
|
323
|
+
rows = rawRows.map((r) => ({
|
|
324
|
+
...r,
|
|
325
|
+
status: r.lifecycle ?? r.status,
|
|
326
|
+
type: 'knowledge',
|
|
327
|
+
}));
|
|
325
328
|
}
|
|
326
329
|
catch {
|
|
327
330
|
/* table may not exist */
|
|
@@ -549,15 +552,9 @@ export class SearchEngine {
|
|
|
549
552
|
}
|
|
550
553
|
try {
|
|
551
554
|
const ids = items.map((it) => it.id);
|
|
552
|
-
const placeholders = ids.map(() => '?').join(',');
|
|
553
555
|
let rows = [];
|
|
554
556
|
try {
|
|
555
|
-
rows = this.
|
|
556
|
-
.prepare(`SELECT id, content, description, trigger, headers, moduleName,
|
|
557
|
-
tags, language, category, updatedAt, createdAt, quality, stats, difficulty,
|
|
558
|
-
whenClause, doClause
|
|
559
|
-
FROM knowledge_entries WHERE id IN (${placeholders})`)
|
|
560
|
-
.all(...ids);
|
|
557
|
+
rows = this.#knowledgeRepo.findByIdsDetailSync(ids);
|
|
561
558
|
}
|
|
562
559
|
catch {
|
|
563
560
|
/* table may not exist */
|
|
@@ -642,23 +639,26 @@ export class SearchEngine {
|
|
|
642
639
|
if (ids.length === 0) {
|
|
643
640
|
return;
|
|
644
641
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
.prepare(`SELECT recipe_id, source_path, status, new_path
|
|
648
|
-
FROM recipe_source_refs
|
|
649
|
-
WHERE recipe_id IN (${placeholders}) AND status != 'stale'`)
|
|
650
|
-
.all(...ids);
|
|
642
|
+
let refsRows;
|
|
643
|
+
refsRows = this.#sourceRefRepo.findActiveByRecipeIds(ids);
|
|
651
644
|
this.logger.debug('recipe_source_refs query', {
|
|
652
645
|
idCount: ids.length,
|
|
653
646
|
rowCount: refsRows.length,
|
|
654
647
|
});
|
|
655
648
|
const refsMap = new Map();
|
|
656
649
|
for (const row of refsRows) {
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
|
|
650
|
+
const recipeId = row.recipeId ??
|
|
651
|
+
row.recipe_id;
|
|
652
|
+
const sourcePath = row.sourcePath ??
|
|
653
|
+
row.source_path;
|
|
654
|
+
const status = row.status;
|
|
655
|
+
const newPath = row.newPath ??
|
|
656
|
+
row.new_path;
|
|
657
|
+
const refPath = status === 'renamed' && newPath ? newPath : sourcePath;
|
|
658
|
+
if (!refsMap.has(recipeId)) {
|
|
659
|
+
refsMap.set(recipeId, []);
|
|
660
660
|
}
|
|
661
|
-
refsMap.get(
|
|
661
|
+
refsMap.get(recipeId)?.push(refPath);
|
|
662
662
|
}
|
|
663
663
|
for (const item of items) {
|
|
664
664
|
const refs = refsMap.get(item.id);
|
|
@@ -692,12 +692,7 @@ export class SearchEngine {
|
|
|
692
692
|
this._cache.clear();
|
|
693
693
|
try {
|
|
694
694
|
// 查找自上次索引后更新的条目
|
|
695
|
-
const changed = this.
|
|
696
|
-
.prepare(`SELECT id, title, description, language, category, knowledgeType, kind,
|
|
697
|
-
content, lifecycle, tags, trigger, difficulty, quality, stats,
|
|
698
|
-
updatedAt, createdAt
|
|
699
|
-
FROM knowledge_entries WHERE updatedAt > ?`)
|
|
700
|
-
.all(this._lastIndexTime);
|
|
695
|
+
const changed = this.#knowledgeRepo.findUpdatedSinceSync(this._lastIndexTime);
|
|
701
696
|
let added = 0;
|
|
702
697
|
let removed = 0;
|
|
703
698
|
for (const r of changed) {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @module service/signal/HitRecorder
|
|
13
13
|
*/
|
|
14
|
+
import { unwrapRawDb } from '../../repository/search/SearchRepoAdapter.js';
|
|
14
15
|
/** 事件类型 → Stats JSON 字段 映射 */
|
|
15
16
|
const EVENT_TO_STATS_FIELD = {
|
|
16
17
|
guardHit: 'guardHits',
|
|
@@ -39,10 +40,7 @@ export class HitRecorder {
|
|
|
39
40
|
#totalFlushed = 0;
|
|
40
41
|
constructor(bus, db, config = {}) {
|
|
41
42
|
this.#bus = bus;
|
|
42
|
-
this.#db =
|
|
43
|
-
'getDb' in db && typeof db.getDb === 'function'
|
|
44
|
-
? db.getDb()
|
|
45
|
-
: db;
|
|
43
|
+
this.#db = unwrapRawDb(db);
|
|
46
44
|
this.#flushIntervalMs = config.flushIntervalMs ?? 30_000;
|
|
47
45
|
this.#maxBufferSize = config.maxBufferSize ?? 100;
|
|
48
46
|
}
|
|
@@ -123,7 +121,9 @@ export class HitRecorder {
|
|
|
123
121
|
let flushed = 0;
|
|
124
122
|
const now = Math.floor(Date.now() / 1000);
|
|
125
123
|
try {
|
|
126
|
-
const stmt = this.#db.prepare(
|
|
124
|
+
const stmt = this.#db.prepare(
|
|
125
|
+
// @escape-hatch(permanent) — json_set() not expressible in Drizzle
|
|
126
|
+
`UPDATE knowledge_entries
|
|
127
127
|
SET stats = json_set(
|
|
128
128
|
COALESCE(stats, '{}'),
|
|
129
129
|
'$.' || ?,
|
|
@@ -10,11 +10,15 @@ export class RuleRecallStrategy {
|
|
|
10
10
|
name = 'rule';
|
|
11
11
|
type = 'rule';
|
|
12
12
|
async recall(context) {
|
|
13
|
-
const
|
|
13
|
+
const ct = context.container;
|
|
14
|
+
const knowledgeRepo = (ct?.get?.('knowledgeRepository') ||
|
|
15
|
+
null);
|
|
16
|
+
const auditRepo = (ct?.get?.('auditRepository') || null);
|
|
14
17
|
const advisor = new SkillAdvisor(context.projectRoot, {
|
|
15
|
-
|
|
18
|
+
knowledgeRepo,
|
|
19
|
+
auditRepo,
|
|
16
20
|
});
|
|
17
|
-
const result = advisor.suggest();
|
|
21
|
+
const result = await advisor.suggest();
|
|
18
22
|
// 过滤已有 Skill
|
|
19
23
|
const existingSet = context.existingSkills ?? new Set();
|
|
20
24
|
return result.suggestions
|
|
@@ -36,9 +36,12 @@
|
|
|
36
36
|
* 生命周期:
|
|
37
37
|
* new SignalCollector(opts) → instance.start() → ... → instance.stop()
|
|
38
38
|
*/
|
|
39
|
+
import type { AuditRepositoryImpl } from '../../repository/audit/AuditRepository.js';
|
|
40
|
+
import type { KnowledgeRepositoryImpl } from '../../repository/knowledge/KnowledgeRepository.impl.js';
|
|
39
41
|
interface SignalCollectorOpts {
|
|
40
42
|
projectRoot: string;
|
|
41
|
-
|
|
43
|
+
knowledgeRepo?: KnowledgeRepositoryImpl | null;
|
|
44
|
+
auditRepo?: AuditRepositoryImpl | null;
|
|
42
45
|
agentFactory?: AgentFactoryLike | null;
|
|
43
46
|
container?: ContainerLike | null;
|
|
44
47
|
signalBus?: import('../../infrastructure/signal/SignalBus.js').SignalBus | null;
|
|
@@ -46,12 +49,6 @@ interface SignalCollectorOpts {
|
|
|
46
49
|
intervalMs?: number;
|
|
47
50
|
onSuggestions?: ((suggestions: Record<string, unknown>[]) => void) | null;
|
|
48
51
|
}
|
|
49
|
-
interface DatabaseLike {
|
|
50
|
-
prepare(sql: string): {
|
|
51
|
-
all(...args: unknown[]): Record<string, unknown>[];
|
|
52
|
-
get(...args: unknown[]): Record<string, unknown> | undefined;
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
52
|
interface AgentResult {
|
|
56
53
|
reply?: string;
|
|
57
54
|
text?: string;
|
|
@@ -87,7 +84,7 @@ export declare class SignalCollector {
|
|
|
87
84
|
* @param [opts.intervalMs] 初始收集间隔(毫秒),后续由 AI 动态调整
|
|
88
85
|
* @param [opts.onSuggestions] 新建议回调 (suggestions[]) => void
|
|
89
86
|
*/
|
|
90
|
-
constructor({ projectRoot,
|
|
87
|
+
constructor({ projectRoot, knowledgeRepo, auditRepo, agentFactory, container, signalBus, mode, intervalMs, onSuggestions, }: SignalCollectorOpts);
|
|
91
88
|
start(): void;
|
|
92
89
|
stop(): void;
|
|
93
90
|
/**
|