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
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RepositoryBase — Drizzle-first 仓储基类
|
|
3
|
+
*
|
|
4
|
+
* 与旧 BaseRepository 的区别:
|
|
5
|
+
* - 构造器接收 DrizzleDB 而非 raw Database
|
|
6
|
+
* - 子类应使用 Drizzle 类型安全 API 实现 CRUD
|
|
7
|
+
* - 保留 rawQuery() 作为复杂查询逃生舱
|
|
8
|
+
* - 无 _assertSafeColumn() —— Drizzle 自带列类型约束
|
|
9
|
+
*/
|
|
10
|
+
import type { SQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
11
|
+
import type { Logger as WinstonLogger } from 'winston';
|
|
12
|
+
import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
|
|
13
|
+
/** Drizzle 事务类型 */
|
|
14
|
+
export type DrizzleTx = Parameters<Parameters<DrizzleDB['transaction']>[0]>[0];
|
|
15
|
+
export interface PaginationOptions {
|
|
16
|
+
page?: number;
|
|
17
|
+
pageSize?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PaginatedResult<T> {
|
|
20
|
+
data: T[];
|
|
21
|
+
pagination: {
|
|
22
|
+
page: number;
|
|
23
|
+
pageSize: number;
|
|
24
|
+
total: number;
|
|
25
|
+
pages: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 新基类:以 Drizzle typed API 为主,raw SQL 为逃生舱。
|
|
30
|
+
*
|
|
31
|
+
* @typeParam TTable Drizzle 表定义(如 typeof knowledgeEdges)
|
|
32
|
+
* @typeParam TEntity 领域实体类型
|
|
33
|
+
*/
|
|
34
|
+
export declare abstract class RepositoryBase<TTable extends SQLiteTable, TEntity> {
|
|
35
|
+
protected readonly drizzle: DrizzleDB;
|
|
36
|
+
protected readonly table: TTable;
|
|
37
|
+
protected readonly logger: WinstonLogger;
|
|
38
|
+
constructor(drizzle: DrizzleDB, table: TTable);
|
|
39
|
+
/**
|
|
40
|
+
* Drizzle 事务包装 — 所有 DB 变更意图应在事务内执行
|
|
41
|
+
*/
|
|
42
|
+
protected transaction<R>(fn: (tx: DrizzleTx) => R): R;
|
|
43
|
+
abstract findById(id: string | number): Promise<TEntity | null>;
|
|
44
|
+
abstract create(data: unknown): Promise<TEntity>;
|
|
45
|
+
abstract delete(id: string | number): Promise<boolean>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RepositoryBase — Drizzle-first 仓储基类
|
|
3
|
+
*
|
|
4
|
+
* 与旧 BaseRepository 的区别:
|
|
5
|
+
* - 构造器接收 DrizzleDB 而非 raw Database
|
|
6
|
+
* - 子类应使用 Drizzle 类型安全 API 实现 CRUD
|
|
7
|
+
* - 保留 rawQuery() 作为复杂查询逃生舱
|
|
8
|
+
* - 无 _assertSafeColumn() —— Drizzle 自带列类型约束
|
|
9
|
+
*/
|
|
10
|
+
import Logger from '../../infrastructure/logging/Logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* 新基类:以 Drizzle typed API 为主,raw SQL 为逃生舱。
|
|
13
|
+
*
|
|
14
|
+
* @typeParam TTable Drizzle 表定义(如 typeof knowledgeEdges)
|
|
15
|
+
* @typeParam TEntity 领域实体类型
|
|
16
|
+
*/
|
|
17
|
+
export class RepositoryBase {
|
|
18
|
+
drizzle;
|
|
19
|
+
table;
|
|
20
|
+
logger;
|
|
21
|
+
constructor(drizzle, table) {
|
|
22
|
+
this.drizzle = drizzle;
|
|
23
|
+
this.table = table;
|
|
24
|
+
this.logger = Logger.getInstance();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Drizzle 事务包装 — 所有 DB 变更意图应在事务内执行
|
|
28
|
+
*/
|
|
29
|
+
transaction(fn) {
|
|
30
|
+
return this.drizzle.transaction(fn);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BootstrapRepository — Bootstrap 快照的仓储实现
|
|
3
|
+
*
|
|
4
|
+
* 从 BootstrapSnapshot 提取的数据操作,
|
|
5
|
+
* 使用 Drizzle 类型安全 API 操作 bootstrap_snapshots + bootstrap_dim_files 表。
|
|
6
|
+
*/
|
|
7
|
+
import { bootstrapSnapshots } from '../../infrastructure/database/drizzle/schema.js';
|
|
8
|
+
import { RepositoryBase } from '../base/RepositoryBase.js';
|
|
9
|
+
export interface BootstrapSnapshotEntity {
|
|
10
|
+
id: string;
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
projectRoot: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
durationMs: number;
|
|
15
|
+
fileCount: number;
|
|
16
|
+
dimensionCount: number;
|
|
17
|
+
candidateCount: number;
|
|
18
|
+
primaryLang: string | null;
|
|
19
|
+
fileHashes: Record<string, string>;
|
|
20
|
+
dimensionMeta: Record<string, DimensionStatMeta>;
|
|
21
|
+
episodicData: Record<string, unknown> | null;
|
|
22
|
+
isIncremental: boolean;
|
|
23
|
+
parentId: string | null;
|
|
24
|
+
changedFiles: string[];
|
|
25
|
+
affectedDims: string[];
|
|
26
|
+
status: string;
|
|
27
|
+
}
|
|
28
|
+
export interface DimensionStatMeta {
|
|
29
|
+
candidateCount: number;
|
|
30
|
+
analysisChars: number;
|
|
31
|
+
referencedFiles: number;
|
|
32
|
+
durationMs: number;
|
|
33
|
+
}
|
|
34
|
+
export interface BootstrapSnapshotInsert {
|
|
35
|
+
id: string;
|
|
36
|
+
sessionId?: string | null;
|
|
37
|
+
projectRoot: string;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
durationMs?: number;
|
|
40
|
+
fileCount?: number;
|
|
41
|
+
dimensionCount?: number;
|
|
42
|
+
candidateCount?: number;
|
|
43
|
+
primaryLang?: string | null;
|
|
44
|
+
fileHashes: Record<string, string>;
|
|
45
|
+
dimensionMeta: Record<string, DimensionStatMeta>;
|
|
46
|
+
episodicData?: unknown | null;
|
|
47
|
+
isIncremental?: boolean;
|
|
48
|
+
parentId?: string | null;
|
|
49
|
+
changedFiles?: string[];
|
|
50
|
+
affectedDims?: string[];
|
|
51
|
+
status?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface DimFileInsert {
|
|
54
|
+
snapshotId: string;
|
|
55
|
+
dimId: string;
|
|
56
|
+
filePath: string;
|
|
57
|
+
role?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface DimFileEntry {
|
|
60
|
+
dimId: string;
|
|
61
|
+
filePath: string;
|
|
62
|
+
}
|
|
63
|
+
export declare class BootstrapRepositoryImpl extends RepositoryBase<typeof bootstrapSnapshots, BootstrapSnapshotEntity> {
|
|
64
|
+
#private;
|
|
65
|
+
/** 默认快照保留数量 */
|
|
66
|
+
static readonly MAX_SNAPSHOTS = 5;
|
|
67
|
+
constructor(drizzle: ConstructorParameters<typeof RepositoryBase<typeof bootstrapSnapshots, BootstrapSnapshotEntity>>[0]);
|
|
68
|
+
findById(id: string): Promise<BootstrapSnapshotEntity | null>;
|
|
69
|
+
create(data: BootstrapSnapshotInsert): Promise<BootstrapSnapshotEntity>;
|
|
70
|
+
delete(id: string): Promise<boolean>;
|
|
71
|
+
/** 获取项目最新完成的快照 */
|
|
72
|
+
getLatest(projectRoot: string): Promise<BootstrapSnapshotEntity | null>;
|
|
73
|
+
/** 获取项目的快照列表 (按时间降序) */
|
|
74
|
+
listByProject(projectRoot: string, limit?: number): Promise<BootstrapSnapshotEntity[]>;
|
|
75
|
+
/** 批量插入维度-文件关联 (INSERT OR IGNORE) */
|
|
76
|
+
saveDimFiles(entries: DimFileInsert[]): Promise<number>;
|
|
77
|
+
/** 获取快照的维度-文件关联 */
|
|
78
|
+
getDimFiles(snapshotId: string): Promise<DimFileEntry[]>;
|
|
79
|
+
/** 获取快照中每个维度引用的文件集合 */
|
|
80
|
+
getDimFileMap(snapshotId: string): Promise<Record<string, Set<string>>>;
|
|
81
|
+
/** 保留项目最新 N 个快照,删除旧的 */
|
|
82
|
+
enforceCapacity(projectRoot: string, maxSnapshots?: number): Promise<number>;
|
|
83
|
+
/** 清除项目的所有快照 */
|
|
84
|
+
clearProject(projectRoot: string): Promise<number>;
|
|
85
|
+
/**
|
|
86
|
+
* 事务保存快照 + 维度-文件关联 + 容量控制
|
|
87
|
+
* 替代 BootstrapSnapshot.save() 中的事务逻辑
|
|
88
|
+
*/
|
|
89
|
+
saveWithDimFiles(snapshot: BootstrapSnapshotInsert, dimFiles: DimFileInsert[]): Promise<BootstrapSnapshotEntity>;
|
|
90
|
+
/** 获取项目最新的主语言 (Panorama 域用于维度/角色检测) */
|
|
91
|
+
getLatestPrimaryLang(projectRoot: string): Promise<string | null>;
|
|
92
|
+
/** 获取快照总数 */
|
|
93
|
+
getSnapshotCount(projectRoot?: string): Promise<number>;
|
|
94
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BootstrapRepository — Bootstrap 快照的仓储实现
|
|
3
|
+
*
|
|
4
|
+
* 从 BootstrapSnapshot 提取的数据操作,
|
|
5
|
+
* 使用 Drizzle 类型安全 API 操作 bootstrap_snapshots + bootstrap_dim_files 表。
|
|
6
|
+
*/
|
|
7
|
+
import { and, count, desc, eq, sql } from 'drizzle-orm';
|
|
8
|
+
import { bootstrapDimFiles, bootstrapSnapshots, } from '../../infrastructure/database/drizzle/schema.js';
|
|
9
|
+
import { RepositoryBase } from '../base/RepositoryBase.js';
|
|
10
|
+
/* ═══ Repository 实现 ═══ */
|
|
11
|
+
export class BootstrapRepositoryImpl extends RepositoryBase {
|
|
12
|
+
/** 默认快照保留数量 */
|
|
13
|
+
static MAX_SNAPSHOTS = 5;
|
|
14
|
+
constructor(drizzle) {
|
|
15
|
+
super(drizzle, bootstrapSnapshots);
|
|
16
|
+
}
|
|
17
|
+
/* ─── CRUD ─── */
|
|
18
|
+
async findById(id) {
|
|
19
|
+
const rows = this.drizzle.select().from(this.table).where(eq(this.table.id, id)).limit(1).all();
|
|
20
|
+
return rows.length > 0 ? this.#mapRow(rows[0]) : null;
|
|
21
|
+
}
|
|
22
|
+
async create(data) {
|
|
23
|
+
this.drizzle
|
|
24
|
+
.insert(this.table)
|
|
25
|
+
.values({
|
|
26
|
+
id: data.id,
|
|
27
|
+
sessionId: data.sessionId ?? null,
|
|
28
|
+
projectRoot: data.projectRoot,
|
|
29
|
+
createdAt: data.createdAt,
|
|
30
|
+
durationMs: data.durationMs ?? 0,
|
|
31
|
+
fileCount: data.fileCount ?? 0,
|
|
32
|
+
dimensionCount: data.dimensionCount ?? 0,
|
|
33
|
+
candidateCount: data.candidateCount ?? 0,
|
|
34
|
+
primaryLang: data.primaryLang ?? null,
|
|
35
|
+
fileHashes: JSON.stringify(data.fileHashes),
|
|
36
|
+
dimensionMeta: JSON.stringify(data.dimensionMeta),
|
|
37
|
+
episodicData: data.episodicData ? JSON.stringify(data.episodicData) : null,
|
|
38
|
+
isIncremental: data.isIncremental ? 1 : 0,
|
|
39
|
+
parentId: data.parentId ?? null,
|
|
40
|
+
changedFiles: JSON.stringify(data.changedFiles ?? []),
|
|
41
|
+
affectedDims: JSON.stringify(data.affectedDims ?? []),
|
|
42
|
+
status: data.status ?? 'complete',
|
|
43
|
+
})
|
|
44
|
+
.run();
|
|
45
|
+
return (await this.findById(data.id));
|
|
46
|
+
}
|
|
47
|
+
async delete(id) {
|
|
48
|
+
const result = this.drizzle.delete(this.table).where(eq(this.table.id, id)).run();
|
|
49
|
+
return result.changes > 0;
|
|
50
|
+
}
|
|
51
|
+
/* ─── 快照查询 ─── */
|
|
52
|
+
/** 获取项目最新完成的快照 */
|
|
53
|
+
async getLatest(projectRoot) {
|
|
54
|
+
const rows = this.drizzle
|
|
55
|
+
.select()
|
|
56
|
+
.from(this.table)
|
|
57
|
+
.where(and(eq(this.table.projectRoot, projectRoot), eq(this.table.status, 'complete')))
|
|
58
|
+
.orderBy(desc(this.table.createdAt))
|
|
59
|
+
.limit(1)
|
|
60
|
+
.all();
|
|
61
|
+
return rows.length > 0 ? this.#mapRow(rows[0]) : null;
|
|
62
|
+
}
|
|
63
|
+
/** 获取项目的快照列表 (按时间降序) */
|
|
64
|
+
async listByProject(projectRoot, limit = 10) {
|
|
65
|
+
const rows = this.drizzle
|
|
66
|
+
.select()
|
|
67
|
+
.from(this.table)
|
|
68
|
+
.where(eq(this.table.projectRoot, projectRoot))
|
|
69
|
+
.orderBy(desc(this.table.createdAt))
|
|
70
|
+
.limit(limit)
|
|
71
|
+
.all();
|
|
72
|
+
return rows.map((r) => this.#mapRow(r));
|
|
73
|
+
}
|
|
74
|
+
/* ─── 维度-文件关联 ─── */
|
|
75
|
+
/** 批量插入维度-文件关联 (INSERT OR IGNORE) */
|
|
76
|
+
async saveDimFiles(entries) {
|
|
77
|
+
if (entries.length === 0) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
let inserted = 0;
|
|
81
|
+
this.transaction((tx) => {
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
tx.insert(bootstrapDimFiles)
|
|
84
|
+
.values({
|
|
85
|
+
snapshotId: entry.snapshotId,
|
|
86
|
+
dimId: entry.dimId,
|
|
87
|
+
filePath: entry.filePath,
|
|
88
|
+
role: entry.role ?? 'referenced',
|
|
89
|
+
})
|
|
90
|
+
.onConflictDoNothing()
|
|
91
|
+
.run();
|
|
92
|
+
inserted++;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return inserted;
|
|
96
|
+
}
|
|
97
|
+
/** 获取快照的维度-文件关联 */
|
|
98
|
+
async getDimFiles(snapshotId) {
|
|
99
|
+
const rows = this.drizzle
|
|
100
|
+
.select({
|
|
101
|
+
dimId: bootstrapDimFiles.dimId,
|
|
102
|
+
filePath: bootstrapDimFiles.filePath,
|
|
103
|
+
})
|
|
104
|
+
.from(bootstrapDimFiles)
|
|
105
|
+
.where(eq(bootstrapDimFiles.snapshotId, snapshotId))
|
|
106
|
+
.all();
|
|
107
|
+
return rows;
|
|
108
|
+
}
|
|
109
|
+
/** 获取快照中每个维度引用的文件集合 */
|
|
110
|
+
async getDimFileMap(snapshotId) {
|
|
111
|
+
const entries = await this.getDimFiles(snapshotId);
|
|
112
|
+
const map = {};
|
|
113
|
+
for (const row of entries) {
|
|
114
|
+
if (!map[row.dimId]) {
|
|
115
|
+
map[row.dimId] = new Set();
|
|
116
|
+
}
|
|
117
|
+
map[row.dimId].add(row.filePath);
|
|
118
|
+
}
|
|
119
|
+
return map;
|
|
120
|
+
}
|
|
121
|
+
/* ─── 容量控制 ─── */
|
|
122
|
+
/** 保留项目最新 N 个快照,删除旧的 */
|
|
123
|
+
async enforceCapacity(projectRoot, maxSnapshots = BootstrapRepositoryImpl.MAX_SNAPSHOTS) {
|
|
124
|
+
const result = this.drizzle
|
|
125
|
+
.delete(this.table)
|
|
126
|
+
.where(and(eq(this.table.projectRoot, projectRoot), sql `${this.table.id} NOT IN (
|
|
127
|
+
SELECT ${this.table.id} FROM ${this.table}
|
|
128
|
+
WHERE ${this.table.projectRoot} = ${projectRoot}
|
|
129
|
+
ORDER BY ${this.table.createdAt} DESC
|
|
130
|
+
LIMIT ${maxSnapshots}
|
|
131
|
+
)`))
|
|
132
|
+
.run();
|
|
133
|
+
return result.changes;
|
|
134
|
+
}
|
|
135
|
+
/** 清除项目的所有快照 */
|
|
136
|
+
async clearProject(projectRoot) {
|
|
137
|
+
const snapshots = await this.listByProject(projectRoot, 9999);
|
|
138
|
+
let deleted = 0;
|
|
139
|
+
for (const snap of snapshots) {
|
|
140
|
+
if (await this.delete(snap.id)) {
|
|
141
|
+
deleted++;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return deleted;
|
|
145
|
+
}
|
|
146
|
+
/* ─── 事务保存 ─── */
|
|
147
|
+
/**
|
|
148
|
+
* 事务保存快照 + 维度-文件关联 + 容量控制
|
|
149
|
+
* 替代 BootstrapSnapshot.save() 中的事务逻辑
|
|
150
|
+
*/
|
|
151
|
+
async saveWithDimFiles(snapshot, dimFiles) {
|
|
152
|
+
this.transaction((tx) => {
|
|
153
|
+
// 主记录
|
|
154
|
+
tx.insert(this.table)
|
|
155
|
+
.values({
|
|
156
|
+
id: snapshot.id,
|
|
157
|
+
sessionId: snapshot.sessionId ?? null,
|
|
158
|
+
projectRoot: snapshot.projectRoot,
|
|
159
|
+
createdAt: snapshot.createdAt,
|
|
160
|
+
durationMs: snapshot.durationMs ?? 0,
|
|
161
|
+
fileCount: snapshot.fileCount ?? 0,
|
|
162
|
+
dimensionCount: snapshot.dimensionCount ?? 0,
|
|
163
|
+
candidateCount: snapshot.candidateCount ?? 0,
|
|
164
|
+
primaryLang: snapshot.primaryLang ?? null,
|
|
165
|
+
fileHashes: JSON.stringify(snapshot.fileHashes),
|
|
166
|
+
dimensionMeta: JSON.stringify(snapshot.dimensionMeta),
|
|
167
|
+
episodicData: snapshot.episodicData ? JSON.stringify(snapshot.episodicData) : null,
|
|
168
|
+
isIncremental: snapshot.isIncremental ? 1 : 0,
|
|
169
|
+
parentId: snapshot.parentId ?? null,
|
|
170
|
+
changedFiles: JSON.stringify(snapshot.changedFiles ?? []),
|
|
171
|
+
affectedDims: JSON.stringify(snapshot.affectedDims ?? []),
|
|
172
|
+
status: snapshot.status ?? 'complete',
|
|
173
|
+
})
|
|
174
|
+
.run();
|
|
175
|
+
// 维度-文件关联
|
|
176
|
+
for (const df of dimFiles) {
|
|
177
|
+
tx.insert(bootstrapDimFiles)
|
|
178
|
+
.values({
|
|
179
|
+
snapshotId: df.snapshotId,
|
|
180
|
+
dimId: df.dimId,
|
|
181
|
+
filePath: df.filePath,
|
|
182
|
+
role: df.role ?? 'referenced',
|
|
183
|
+
})
|
|
184
|
+
.onConflictDoNothing()
|
|
185
|
+
.run();
|
|
186
|
+
}
|
|
187
|
+
// 容量控制
|
|
188
|
+
tx.delete(this.table)
|
|
189
|
+
.where(and(eq(this.table.projectRoot, snapshot.projectRoot), sql `${this.table.id} NOT IN (
|
|
190
|
+
SELECT ${this.table.id} FROM ${this.table}
|
|
191
|
+
WHERE ${this.table.projectRoot} = ${snapshot.projectRoot}
|
|
192
|
+
ORDER BY ${this.table.createdAt} DESC
|
|
193
|
+
LIMIT ${BootstrapRepositoryImpl.MAX_SNAPSHOTS}
|
|
194
|
+
)`))
|
|
195
|
+
.run();
|
|
196
|
+
});
|
|
197
|
+
return (await this.findById(snapshot.id));
|
|
198
|
+
}
|
|
199
|
+
/** 获取项目最新的主语言 (Panorama 域用于维度/角色检测) */
|
|
200
|
+
async getLatestPrimaryLang(projectRoot) {
|
|
201
|
+
const rows = this.drizzle
|
|
202
|
+
.select({ primaryLang: this.table.primaryLang })
|
|
203
|
+
.from(this.table)
|
|
204
|
+
.where(eq(this.table.projectRoot, projectRoot))
|
|
205
|
+
.orderBy(desc(this.table.createdAt))
|
|
206
|
+
.limit(1)
|
|
207
|
+
.all();
|
|
208
|
+
return rows.length > 0 ? (rows[0].primaryLang ?? null) : null;
|
|
209
|
+
}
|
|
210
|
+
/** 获取快照总数 */
|
|
211
|
+
async getSnapshotCount(projectRoot) {
|
|
212
|
+
const condition = projectRoot ? eq(this.table.projectRoot, projectRoot) : undefined;
|
|
213
|
+
const [row] = this.drizzle.select({ cnt: count() }).from(this.table).where(condition).all();
|
|
214
|
+
return row?.cnt ?? 0;
|
|
215
|
+
}
|
|
216
|
+
/* ─── 内部辅助 ─── */
|
|
217
|
+
#mapRow(row) {
|
|
218
|
+
return {
|
|
219
|
+
id: row.id,
|
|
220
|
+
sessionId: row.sessionId ?? null,
|
|
221
|
+
projectRoot: row.projectRoot,
|
|
222
|
+
createdAt: row.createdAt,
|
|
223
|
+
durationMs: row.durationMs ?? 0,
|
|
224
|
+
fileCount: row.fileCount ?? 0,
|
|
225
|
+
dimensionCount: row.dimensionCount ?? 0,
|
|
226
|
+
candidateCount: row.candidateCount ?? 0,
|
|
227
|
+
primaryLang: row.primaryLang ?? null,
|
|
228
|
+
fileHashes: safeParseJSON(row.fileHashes, {}),
|
|
229
|
+
dimensionMeta: safeParseJSON(row.dimensionMeta, {}),
|
|
230
|
+
episodicData: safeParseJSON(row.episodicData, null),
|
|
231
|
+
isIncremental: !!row.isIncremental,
|
|
232
|
+
parentId: row.parentId ?? null,
|
|
233
|
+
changedFiles: safeParseJSON(row.changedFiles, []),
|
|
234
|
+
affectedDims: safeParseJSON(row.affectedDims, []),
|
|
235
|
+
status: row.status ?? 'complete',
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function safeParseJSON(str, fallback) {
|
|
240
|
+
try {
|
|
241
|
+
return str ? JSON.parse(str) : fallback;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return fallback;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeEntityRepository — AST 代码实体的仓储实现
|
|
3
|
+
*
|
|
4
|
+
* 从 CodeEntityGraph 和 PanoramaScanner 提取的数据操作,
|
|
5
|
+
* 使用 Drizzle 类型安全 API。
|
|
6
|
+
*/
|
|
7
|
+
import { codeEntities } from '../../infrastructure/database/drizzle/schema.js';
|
|
8
|
+
import { RepositoryBase } from '../base/RepositoryBase.js';
|
|
9
|
+
export interface CodeEntity {
|
|
10
|
+
id: number;
|
|
11
|
+
entityId: string;
|
|
12
|
+
entityType: string;
|
|
13
|
+
projectRoot: string;
|
|
14
|
+
name: string;
|
|
15
|
+
filePath: string | null;
|
|
16
|
+
lineNumber: number | null;
|
|
17
|
+
superclass: string | null;
|
|
18
|
+
protocols: string[];
|
|
19
|
+
metadata: Record<string, unknown>;
|
|
20
|
+
createdAt: number;
|
|
21
|
+
updatedAt: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CodeEntityInsert {
|
|
24
|
+
entityId: string;
|
|
25
|
+
entityType: string;
|
|
26
|
+
projectRoot: string;
|
|
27
|
+
name: string;
|
|
28
|
+
filePath?: string | null;
|
|
29
|
+
lineNumber?: number | null;
|
|
30
|
+
superclass?: string | null;
|
|
31
|
+
protocols?: string[];
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
export declare class CodeEntityRepositoryImpl extends RepositoryBase<typeof codeEntities, CodeEntity> {
|
|
35
|
+
#private;
|
|
36
|
+
constructor(drizzle: ConstructorParameters<typeof RepositoryBase<typeof codeEntities, CodeEntity>>[0]);
|
|
37
|
+
findById(id: number): Promise<CodeEntity | null>;
|
|
38
|
+
create(data: CodeEntityInsert): Promise<CodeEntity>;
|
|
39
|
+
delete(id: number): Promise<boolean>;
|
|
40
|
+
/** UPSERT — 按 (entityId, entityType, projectRoot) 唯一约束 */
|
|
41
|
+
upsert(entity: CodeEntityInsert): Promise<CodeEntity>;
|
|
42
|
+
/** 批量 UPSERT */
|
|
43
|
+
batchUpsert(entities: CodeEntityInsert[]): Promise<number>;
|
|
44
|
+
/** 按文件路径查询 */
|
|
45
|
+
findByFile(filePath: string, projectRoot: string): Promise<CodeEntity[]>;
|
|
46
|
+
/** 按实体类型列表 */
|
|
47
|
+
listByType(entityType: string, projectRoot: string, limit?: number): Promise<CodeEntity[]>;
|
|
48
|
+
/** 按名称搜索 */
|
|
49
|
+
searchByName(query: string, projectRoot: string, options?: {
|
|
50
|
+
entityType?: string;
|
|
51
|
+
limit?: number;
|
|
52
|
+
}): Promise<CodeEntity[]>;
|
|
53
|
+
/** 按 entityId + entityType + projectRoot 精确查找 */
|
|
54
|
+
findByEntityId(entityId: string, entityType: string, projectRoot: string): Promise<CodeEntity | null>;
|
|
55
|
+
/** 删除指定项目的所有实体 */
|
|
56
|
+
clearProject(projectRoot: string): Promise<number>;
|
|
57
|
+
/** 删除指定文件的实体(用于增量更新调用图) */
|
|
58
|
+
deleteByFile(filePath: string, projectRoot: string): Promise<number>;
|
|
59
|
+
/** 获取实体总数 */
|
|
60
|
+
getEntityCount(projectRoot?: string): Promise<number>;
|
|
61
|
+
/** 按类型统计实体数 */
|
|
62
|
+
countByType(projectRoot: string): Promise<Record<string, number>>;
|
|
63
|
+
/** 按文件路径和实体类型删除 */
|
|
64
|
+
deleteByFileAndType(filePath: string, entityType: string, projectRoot: string): Promise<number>;
|
|
65
|
+
/** 按 entityId + projectRoot 查找(不限 entityType) */
|
|
66
|
+
findByEntityIdOnly(entityId: string, projectRoot: string): Promise<CodeEntity | null>;
|
|
67
|
+
/** 查询非 module 实体的 (entityId, filePath) 去重列表 */
|
|
68
|
+
findDistinctEntityIdsWithFilePath(projectRoot: string): Promise<Array<{
|
|
69
|
+
entityId: string;
|
|
70
|
+
filePath: string;
|
|
71
|
+
}>>;
|
|
72
|
+
/** 查询本地模块 (排除 external/host nodeType) */
|
|
73
|
+
findLocalModules(projectRoot: string): Promise<Array<{
|
|
74
|
+
entityId: string;
|
|
75
|
+
name: string;
|
|
76
|
+
}>>;
|
|
77
|
+
/** 查询指定 nodeType 的模块实体 */
|
|
78
|
+
findModulesByNodeTypes(projectRoot: string, nodeTypes: string[]): Promise<CodeEntity[]>;
|
|
79
|
+
/** 统计指定 nodeType 的模块数量 */
|
|
80
|
+
countModulesByNodeType(projectRoot: string, nodeType: string): Promise<number>;
|
|
81
|
+
/** 按 projectRoot + filePaths 批量查询实体 */
|
|
82
|
+
findByProjectAndFilePaths(projectRoot: string, filePaths: string[]): Promise<CodeEntity[]>;
|
|
83
|
+
/** 查询非 module 实体的去重文件路径列表 */
|
|
84
|
+
findDistinctFilePaths(projectRoot: string, limit?: number): Promise<string[]>;
|
|
85
|
+
/** 批量 INSERT OR IGNORE (不更新已存在的行) */
|
|
86
|
+
batchInsertIgnore(entities: CodeEntityInsert[]): Promise<number>;
|
|
87
|
+
/**
|
|
88
|
+
* 符号名是否存在 (ReverseGuard.#symbolExists)
|
|
89
|
+
*/
|
|
90
|
+
existsByName(name: string): boolean;
|
|
91
|
+
}
|