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
|
@@ -39,11 +39,15 @@ const DRIFT_THRESHOLDS = {
|
|
|
39
39
|
};
|
|
40
40
|
/* ────────────────────── Class ────────────────────── */
|
|
41
41
|
export class ReverseGuard {
|
|
42
|
-
#
|
|
42
|
+
#knowledgeRepo;
|
|
43
|
+
#entityRepo;
|
|
44
|
+
#sourceRefRepo;
|
|
43
45
|
#signalBus;
|
|
44
46
|
#logger = Logger.getInstance();
|
|
45
|
-
constructor(
|
|
46
|
-
this.#
|
|
47
|
+
constructor(knowledgeRepo, entityRepo, sourceRefRepo, options = {}) {
|
|
48
|
+
this.#knowledgeRepo = knowledgeRepo;
|
|
49
|
+
this.#entityRepo = entityRepo;
|
|
50
|
+
this.#sourceRefRepo = sourceRefRepo;
|
|
47
51
|
this.#signalBus = options.signalBus ?? null;
|
|
48
52
|
}
|
|
49
53
|
/**
|
|
@@ -107,20 +111,12 @@ export class ReverseGuard {
|
|
|
107
111
|
/* ── 内部方法 ── */
|
|
108
112
|
#loadActiveRuleRecipes() {
|
|
109
113
|
try {
|
|
110
|
-
const rows = this.#
|
|
111
|
-
.prepare(`SELECT id, title,
|
|
112
|
-
json_extract(content, '$.coreCode') AS core_code,
|
|
113
|
-
json_extract(content, '$.pattern') AS guard_pattern,
|
|
114
|
-
stats
|
|
115
|
-
FROM knowledge_entries
|
|
116
|
-
WHERE lifecycle = 'active'
|
|
117
|
-
AND kind = 'rule'`)
|
|
118
|
-
.all();
|
|
114
|
+
const rows = this.#knowledgeRepo.findActiveRulesWithContentSync();
|
|
119
115
|
return rows.map((r) => ({
|
|
120
116
|
id: r.id,
|
|
121
117
|
title: r.title,
|
|
122
|
-
core_code: r.
|
|
123
|
-
guard_pattern: r.
|
|
118
|
+
core_code: r.coreCode ?? null,
|
|
119
|
+
guard_pattern: r.guardPattern ?? null,
|
|
124
120
|
stats: r.stats ?? null,
|
|
125
121
|
}));
|
|
126
122
|
}
|
|
@@ -139,10 +135,8 @@ export class ReverseGuard {
|
|
|
139
135
|
const signals = [];
|
|
140
136
|
for (const symbol of symbols) {
|
|
141
137
|
try {
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
.get(symbol);
|
|
145
|
-
if (!row) {
|
|
138
|
+
const exists = this.#entityRepo.existsByName(symbol);
|
|
139
|
+
if (!exists) {
|
|
146
140
|
signals.push({
|
|
147
141
|
type: 'symbol_missing',
|
|
148
142
|
detail: `Symbol "${symbol}" referenced in recipe coreCode not found in codebase`,
|
|
@@ -212,26 +206,25 @@ export class ReverseGuard {
|
|
|
212
206
|
*/
|
|
213
207
|
#checkSourceRefStaleness(recipeId) {
|
|
214
208
|
try {
|
|
215
|
-
const
|
|
216
|
-
.
|
|
217
|
-
.
|
|
218
|
-
if (
|
|
209
|
+
const staleRefs = this.#sourceRefRepo
|
|
210
|
+
.findByRecipeId(recipeId)
|
|
211
|
+
.filter((r) => r.status === 'stale');
|
|
212
|
+
if (staleRefs.length === 0) {
|
|
219
213
|
return [];
|
|
220
214
|
}
|
|
221
215
|
return [
|
|
222
216
|
{
|
|
223
217
|
type: 'source_ref_stale',
|
|
224
|
-
detail: `${
|
|
218
|
+
detail: `${staleRefs.length} source file(s) no longer exist: ${staleRefs
|
|
225
219
|
.slice(0, 3)
|
|
226
|
-
.map((r) => r.
|
|
227
|
-
.join(', ')}${
|
|
228
|
-
severity:
|
|
220
|
+
.map((r) => r.sourcePath)
|
|
221
|
+
.join(', ')}${staleRefs.length > 3 ? ` (+${staleRefs.length - 3} more)` : ''}`,
|
|
222
|
+
severity: staleRefs.length >= 3 ? 'high' : 'medium',
|
|
229
223
|
evidence: {},
|
|
230
224
|
},
|
|
231
225
|
];
|
|
232
226
|
}
|
|
233
227
|
catch {
|
|
234
|
-
// recipe_source_refs 表可能不存在
|
|
235
228
|
return [];
|
|
236
229
|
}
|
|
237
230
|
}
|
|
@@ -257,10 +250,7 @@ export class ReverseGuard {
|
|
|
257
250
|
}
|
|
258
251
|
#getHistoricalHits(recipeId) {
|
|
259
252
|
try {
|
|
260
|
-
|
|
261
|
-
.prepare(`SELECT json_extract(stats, '$.guardHits') AS hits FROM knowledge_entries WHERE id = ?`)
|
|
262
|
-
.get(recipeId);
|
|
263
|
-
return row?.hits ?? 0;
|
|
253
|
+
return this.#knowledgeRepo.getGuardHitsSync(recipeId);
|
|
264
254
|
}
|
|
265
255
|
catch {
|
|
266
256
|
return 0;
|
|
@@ -2,19 +2,15 @@
|
|
|
2
2
|
* ViolationsStore — Guard 违反记录存储(DB 版)
|
|
3
3
|
* 记录每次 as:audit 运行的审计结果,持久化到 SQLite guard_violations 表。
|
|
4
4
|
* 最多保留 200 条。
|
|
5
|
+
*
|
|
6
|
+
* 所有操作使用 Drizzle 类型安全 API(零 raw SQL)。
|
|
5
7
|
*/
|
|
6
8
|
import { type DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
|
|
7
|
-
interface DatabaseLike {
|
|
8
|
-
prepare(sql: string): {
|
|
9
|
-
run(...params: unknown[]): unknown;
|
|
10
|
-
get(...params: unknown[]): Record<string, unknown>;
|
|
11
|
-
all(...params: unknown[]): Record<string, unknown>[];
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
9
|
interface ViolationRecord {
|
|
15
10
|
ruleId?: string;
|
|
16
11
|
severity?: string;
|
|
17
12
|
message?: string;
|
|
13
|
+
line?: number;
|
|
18
14
|
[key: string]: unknown;
|
|
19
15
|
}
|
|
20
16
|
interface RunInput {
|
|
@@ -32,27 +28,24 @@ interface RunOutput {
|
|
|
32
28
|
}
|
|
33
29
|
export declare class ViolationsStore {
|
|
34
30
|
#private;
|
|
35
|
-
/** @param
|
|
36
|
-
constructor(
|
|
31
|
+
/** @param _db 保留签名兼容 (不再使用) */
|
|
32
|
+
constructor(_db: unknown, drizzle?: DrizzleDB);
|
|
37
33
|
/**
|
|
38
34
|
* 追加一次 Guard 运行记录
|
|
39
35
|
* ★ 去重:同一文件、同一违规集合不重复入库,仅更新时间戳
|
|
40
|
-
* ★ Drizzle 类型安全
|
|
36
|
+
* ★ 全 Drizzle 类型安全
|
|
41
37
|
*/
|
|
42
38
|
appendRun(run: RunInput): string;
|
|
43
39
|
/**
|
|
44
40
|
* 获取所有运行记录(最新在后)
|
|
45
|
-
* ★ Drizzle 类型安全 SELECT
|
|
46
41
|
*/
|
|
47
42
|
getRuns(): RunOutput[];
|
|
48
43
|
/**
|
|
49
44
|
* 按文件路径查询历史
|
|
50
|
-
* ★ Drizzle 类型安全 SELECT WHERE
|
|
51
45
|
*/
|
|
52
46
|
getRunsByFile(filePath: string): RunOutput[];
|
|
53
47
|
/**
|
|
54
48
|
* 获取最近 N 条记录
|
|
55
|
-
* ★ Drizzle 类型安全 SELECT + ORDER + LIMIT
|
|
56
49
|
*/
|
|
57
50
|
getRecentRuns(n?: number): RunOutput[];
|
|
58
51
|
/** 获取统计汇总 */
|
|
@@ -65,12 +58,16 @@ export declare class ViolationsStore {
|
|
|
65
58
|
/**
|
|
66
59
|
* 按规则 ID 聚合统计
|
|
67
60
|
* 利用 SQLite json_each 展开 violations_json 数组
|
|
68
|
-
*
|
|
61
|
+
*
|
|
62
|
+
* json_each 是 SQLite 专有函数,Drizzle 无 typed API (ORM limitation)
|
|
69
63
|
*/
|
|
70
|
-
getStatsByRule():
|
|
64
|
+
getStatsByRule(): {
|
|
65
|
+
ruleId: string | null;
|
|
66
|
+
severity: string | null;
|
|
67
|
+
count: number;
|
|
68
|
+
}[];
|
|
71
69
|
/**
|
|
72
70
|
* 获取趋势数据 — 对比最近两次运行
|
|
73
|
-
* @returns }
|
|
74
71
|
*/
|
|
75
72
|
getTrend(): {
|
|
76
73
|
errorsChange: number;
|
|
@@ -81,10 +78,7 @@ export declare class ViolationsStore {
|
|
|
81
78
|
previousWarnings: number;
|
|
82
79
|
hasHistory: boolean;
|
|
83
80
|
};
|
|
84
|
-
/**
|
|
85
|
-
* 清空所有记录
|
|
86
|
-
* ★ Drizzle 类型安全 DELETE
|
|
87
|
-
*/
|
|
81
|
+
/** 清空所有记录 */
|
|
88
82
|
clearRuns(): void;
|
|
89
83
|
/** 清除指定规则或文件的记录 */
|
|
90
84
|
clearAll(): Promise<void>;
|
|
@@ -92,7 +86,7 @@ export declare class ViolationsStore {
|
|
|
92
86
|
ruleId?: string;
|
|
93
87
|
file?: string;
|
|
94
88
|
}): Promise<void>;
|
|
95
|
-
/**
|
|
89
|
+
/** 分页查询 */
|
|
96
90
|
list(filters?: {
|
|
97
91
|
file?: string;
|
|
98
92
|
}, { page, limit }?: {
|
|
@@ -2,24 +2,24 @@
|
|
|
2
2
|
* ViolationsStore — Guard 违反记录存储(DB 版)
|
|
3
3
|
* 记录每次 as:audit 运行的审计结果,持久化到 SQLite guard_violations 表。
|
|
4
4
|
* 最多保留 200 条。
|
|
5
|
+
*
|
|
6
|
+
* 所有操作使用 Drizzle 类型安全 API(零 raw SQL)。
|
|
5
7
|
*/
|
|
6
|
-
import { asc, desc, eq, sql } from 'drizzle-orm';
|
|
8
|
+
import { asc, count, desc, eq, sql } from 'drizzle-orm';
|
|
7
9
|
import { getDrizzle } from '../../infrastructure/database/drizzle/index.js';
|
|
8
10
|
import { guardViolations } from '../../infrastructure/database/drizzle/schema.js';
|
|
9
11
|
const MAX_RUNS = 200;
|
|
10
12
|
export class ViolationsStore {
|
|
11
|
-
#db;
|
|
12
13
|
#drizzle;
|
|
13
|
-
/** @param
|
|
14
|
-
constructor(
|
|
15
|
-
this.#db = db;
|
|
14
|
+
/** @param _db 保留签名兼容 (不再使用) */
|
|
15
|
+
constructor(_db, drizzle) {
|
|
16
16
|
this.#drizzle = drizzle ?? getDrizzle();
|
|
17
17
|
}
|
|
18
18
|
// ─── 写入 ─────────────────────────────────────────────
|
|
19
19
|
/**
|
|
20
20
|
* 追加一次 Guard 运行记录
|
|
21
21
|
* ★ 去重:同一文件、同一违规集合不重复入库,仅更新时间戳
|
|
22
|
-
* ★ Drizzle 类型安全
|
|
22
|
+
* ★ 全 Drizzle 类型安全
|
|
23
23
|
*/
|
|
24
24
|
appendRun(run) {
|
|
25
25
|
const filePath = run.filePath || '';
|
|
@@ -28,16 +28,28 @@ export class ViolationsStore {
|
|
|
28
28
|
// ── 去重:查最近一条同文件记录,比较违规指纹 ──
|
|
29
29
|
const fingerprint = this.#violationFingerprint(violations);
|
|
30
30
|
if (filePath) {
|
|
31
|
-
const lastRow = this.#
|
|
32
|
-
.
|
|
33
|
-
.
|
|
31
|
+
const lastRow = this.#drizzle
|
|
32
|
+
.select({
|
|
33
|
+
id: guardViolations.id,
|
|
34
|
+
violationsJson: guardViolations.violationsJson,
|
|
35
|
+
})
|
|
36
|
+
.from(guardViolations)
|
|
37
|
+
.where(eq(guardViolations.filePath, filePath))
|
|
38
|
+
.orderBy(desc(guardViolations.createdAt))
|
|
39
|
+
.limit(1)
|
|
40
|
+
.get();
|
|
34
41
|
if (lastRow) {
|
|
35
|
-
const lastFingerprint = this.#violationFingerprint(JSON.parse(lastRow.
|
|
42
|
+
const lastFingerprint = this.#violationFingerprint(JSON.parse(lastRow.violationsJson || '[]'));
|
|
36
43
|
if (fingerprint === lastFingerprint) {
|
|
37
44
|
// 违规未变化:仅刷新时间戳,不新增行
|
|
38
|
-
this.#
|
|
39
|
-
.
|
|
40
|
-
.
|
|
45
|
+
this.#drizzle
|
|
46
|
+
.update(guardViolations)
|
|
47
|
+
.set({
|
|
48
|
+
triggeredAt: new Date().toISOString(),
|
|
49
|
+
createdAt: Math.floor(Date.now() / 1000),
|
|
50
|
+
})
|
|
51
|
+
.where(eq(guardViolations.id, lastRow.id))
|
|
52
|
+
.run();
|
|
41
53
|
return lastRow.id;
|
|
42
54
|
}
|
|
43
55
|
}
|
|
@@ -56,14 +68,15 @@ export class ViolationsStore {
|
|
|
56
68
|
createdAt: now,
|
|
57
69
|
})
|
|
58
70
|
.run();
|
|
59
|
-
// 超限截断:保留最新 MAX_RUNS
|
|
60
|
-
this.#
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
// 超限截断:保留最新 MAX_RUNS 条
|
|
72
|
+
this.#drizzle
|
|
73
|
+
.delete(guardViolations)
|
|
74
|
+
.where(sql `${guardViolations.id} NOT IN (
|
|
75
|
+
SELECT ${guardViolations.id} FROM ${guardViolations}
|
|
76
|
+
ORDER BY ${guardViolations.createdAt} DESC
|
|
77
|
+
LIMIT ${MAX_RUNS}
|
|
78
|
+
)`)
|
|
79
|
+
.run();
|
|
67
80
|
return id;
|
|
68
81
|
}
|
|
69
82
|
/**
|
|
@@ -78,7 +91,6 @@ export class ViolationsStore {
|
|
|
78
91
|
// ─── 查询 ─────────────────────────────────────────────
|
|
79
92
|
/**
|
|
80
93
|
* 获取所有运行记录(最新在后)
|
|
81
|
-
* ★ Drizzle 类型安全 SELECT
|
|
82
94
|
*/
|
|
83
95
|
getRuns() {
|
|
84
96
|
const rows = this.#drizzle
|
|
@@ -90,7 +102,6 @@ export class ViolationsStore {
|
|
|
90
102
|
}
|
|
91
103
|
/**
|
|
92
104
|
* 按文件路径查询历史
|
|
93
|
-
* ★ Drizzle 类型安全 SELECT WHERE
|
|
94
105
|
*/
|
|
95
106
|
getRunsByFile(filePath) {
|
|
96
107
|
const rows = this.#drizzle
|
|
@@ -103,7 +114,6 @@ export class ViolationsStore {
|
|
|
103
114
|
}
|
|
104
115
|
/**
|
|
105
116
|
* 获取最近 N 条记录
|
|
106
|
-
* ★ Drizzle 类型安全 SELECT + ORDER + LIMIT
|
|
107
117
|
*/
|
|
108
118
|
getRecentRuns(n = 20) {
|
|
109
119
|
const rows = this.#drizzle
|
|
@@ -116,41 +126,41 @@ export class ViolationsStore {
|
|
|
116
126
|
}
|
|
117
127
|
/** 获取统计汇总 */
|
|
118
128
|
getStats() {
|
|
119
|
-
const row = this.#
|
|
120
|
-
.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
129
|
+
const [row] = this.#drizzle
|
|
130
|
+
.select({
|
|
131
|
+
totalRuns: count(),
|
|
132
|
+
totalViolations: sql `COALESCE(SUM(${guardViolations.violationCount}), 0)`,
|
|
133
|
+
lastRunAt: sql `MAX(${guardViolations.triggeredAt})`,
|
|
134
|
+
})
|
|
135
|
+
.from(guardViolations)
|
|
136
|
+
.all();
|
|
137
|
+
const totalRuns = row?.totalRuns ?? 0;
|
|
138
|
+
const totalViolations = row?.totalViolations ?? 0;
|
|
128
139
|
return {
|
|
129
|
-
totalRuns
|
|
130
|
-
totalViolations
|
|
131
|
-
averageViolationsPerRun:
|
|
132
|
-
lastRunAt: row
|
|
140
|
+
totalRuns,
|
|
141
|
+
totalViolations,
|
|
142
|
+
averageViolationsPerRun: totalRuns > 0 ? (totalViolations / totalRuns).toFixed(2) : 0,
|
|
143
|
+
lastRunAt: row?.lastRunAt || null,
|
|
133
144
|
};
|
|
134
145
|
}
|
|
135
146
|
/**
|
|
136
147
|
* 按规则 ID 聚合统计
|
|
137
148
|
* 利用 SQLite json_each 展开 violations_json 数组
|
|
138
|
-
*
|
|
149
|
+
*
|
|
150
|
+
* json_each 是 SQLite 专有函数,Drizzle 无 typed API (ORM limitation)
|
|
139
151
|
*/
|
|
140
152
|
getStatsByRule() {
|
|
141
153
|
try {
|
|
142
|
-
return this.#
|
|
143
|
-
.prepare(`
|
|
154
|
+
return this.#drizzle.all(sql `
|
|
144
155
|
SELECT
|
|
145
156
|
json_extract(j.value, '$.ruleId') AS ruleId,
|
|
146
157
|
json_extract(j.value, '$.severity') AS severity,
|
|
147
158
|
COUNT(*) AS count
|
|
148
|
-
FROM
|
|
159
|
+
FROM ${guardViolations} gv, json_each(gv.violations_json) j
|
|
149
160
|
WHERE json_extract(j.value, '$.ruleId') IS NOT NULL
|
|
150
161
|
GROUP BY ruleId, severity
|
|
151
162
|
ORDER BY count DESC
|
|
152
|
-
`)
|
|
153
|
-
.all();
|
|
163
|
+
`);
|
|
154
164
|
}
|
|
155
165
|
catch {
|
|
156
166
|
return [];
|
|
@@ -158,7 +168,6 @@ export class ViolationsStore {
|
|
|
158
168
|
}
|
|
159
169
|
/**
|
|
160
170
|
* 获取趋势数据 — 对比最近两次运行
|
|
161
|
-
* @returns }
|
|
162
171
|
*/
|
|
163
172
|
getTrend() {
|
|
164
173
|
const recent = this.getRecentRuns(2);
|
|
@@ -190,10 +199,7 @@ export class ViolationsStore {
|
|
|
190
199
|
};
|
|
191
200
|
}
|
|
192
201
|
// ─── 清除 ─────────────────────────────────────────────
|
|
193
|
-
/**
|
|
194
|
-
* 清空所有记录
|
|
195
|
-
* ★ Drizzle 类型安全 DELETE
|
|
196
|
-
*/
|
|
202
|
+
/** 清空所有记录 */
|
|
197
203
|
clearRuns() {
|
|
198
204
|
this.#drizzle.delete(guardViolations).run();
|
|
199
205
|
}
|
|
@@ -209,38 +215,38 @@ export class ViolationsStore {
|
|
|
209
215
|
this.clearRuns();
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
|
-
/**
|
|
218
|
+
/** 分页查询 */
|
|
213
219
|
async list(filters = {}, { page = 1, limit = 20 } = {}) {
|
|
214
220
|
const offset = (page - 1) * limit;
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
221
|
+
const condition = filters.file ? eq(guardViolations.filePath, filters.file) : undefined;
|
|
222
|
+
const rows = this.#drizzle
|
|
223
|
+
.select()
|
|
224
|
+
.from(guardViolations)
|
|
225
|
+
.where(condition)
|
|
226
|
+
.orderBy(desc(guardViolations.createdAt))
|
|
227
|
+
.limit(limit)
|
|
228
|
+
.offset(offset)
|
|
229
|
+
.all();
|
|
230
|
+
const [totalRow] = this.#drizzle
|
|
231
|
+
.select({ c: count() })
|
|
232
|
+
.from(guardViolations)
|
|
233
|
+
.where(condition)
|
|
234
|
+
.all();
|
|
235
|
+
const total = totalRow?.c ?? 0;
|
|
229
236
|
return {
|
|
230
237
|
data: rows.map((r) => this.#rowToRun(r)),
|
|
231
238
|
pagination: { page, limit, total, pages: Math.ceil(total / limit) },
|
|
232
239
|
};
|
|
233
240
|
}
|
|
234
241
|
// ─── 内部 ─────────────────────────────────────────────
|
|
235
|
-
/**
|
|
242
|
+
/** Drizzle camelCase 行 → RunOutput */
|
|
236
243
|
#rowToRun(row) {
|
|
237
|
-
const violationsRaw = (row.violationsJson ?? row.violations_json);
|
|
238
244
|
return {
|
|
239
245
|
id: row.id,
|
|
240
|
-
filePath:
|
|
241
|
-
triggeredAt:
|
|
242
|
-
violations:
|
|
243
|
-
violationCount:
|
|
246
|
+
filePath: row.filePath,
|
|
247
|
+
triggeredAt: row.triggeredAt,
|
|
248
|
+
violations: row.violationsJson ? JSON.parse(row.violationsJson) : [],
|
|
249
|
+
violationCount: row.violationCount ?? 0,
|
|
244
250
|
summary: row.summary || '',
|
|
245
251
|
};
|
|
246
252
|
}
|