@skillsmith/core 0.2.0 → 2.0.0
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 +233 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/analysis/__tests__/incremental.test.d.ts +13 -0
- package/dist/src/analysis/__tests__/incremental.test.d.ts.map +1 -0
- package/dist/src/analysis/__tests__/incremental.test.js +515 -0
- package/dist/src/analysis/__tests__/incremental.test.js.map +1 -0
- package/dist/src/analysis/__tests__/integration.test.d.ts +14 -0
- package/dist/src/analysis/__tests__/integration.test.d.ts.map +1 -0
- package/dist/src/analysis/__tests__/integration.test.js +1059 -0
- package/dist/src/analysis/__tests__/integration.test.js.map +1 -0
- package/dist/src/analysis/__tests__/metrics.test.d.ts +9 -0
- package/dist/src/analysis/__tests__/metrics.test.d.ts.map +1 -0
- package/dist/src/analysis/__tests__/metrics.test.js +369 -0
- package/dist/src/analysis/__tests__/metrics.test.js.map +1 -0
- package/dist/src/analysis/__tests__/performance.test.d.ts +15 -0
- package/dist/src/analysis/__tests__/performance.test.d.ts.map +1 -0
- package/dist/src/analysis/__tests__/performance.test.js +402 -0
- package/dist/src/analysis/__tests__/performance.test.js.map +1 -0
- package/dist/src/analysis/adapters/__tests__/go.test.d.ts +12 -0
- package/dist/src/analysis/adapters/__tests__/go.test.d.ts.map +1 -0
- package/dist/src/analysis/adapters/__tests__/go.test.js +561 -0
- package/dist/src/analysis/adapters/__tests__/go.test.js.map +1 -0
- package/dist/src/analysis/adapters/__tests__/python.test.d.ts +11 -0
- package/dist/src/analysis/adapters/__tests__/python.test.d.ts.map +1 -0
- package/dist/src/analysis/adapters/__tests__/python.test.js +669 -0
- package/dist/src/analysis/adapters/__tests__/python.test.js.map +1 -0
- package/dist/src/analysis/adapters/__tests__/rust.test.d.ts +12 -0
- package/dist/src/analysis/adapters/__tests__/rust.test.d.ts.map +1 -0
- package/dist/src/analysis/adapters/__tests__/rust.test.js +676 -0
- package/dist/src/analysis/adapters/__tests__/rust.test.js.map +1 -0
- package/dist/src/analysis/adapters/__tests__/typescript.test.d.ts +14 -0
- package/dist/src/analysis/adapters/__tests__/typescript.test.d.ts.map +1 -0
- package/dist/src/analysis/adapters/__tests__/typescript.test.js +381 -0
- package/dist/src/analysis/adapters/__tests__/typescript.test.js.map +1 -0
- package/dist/src/analysis/adapters/base.d.ts +83 -0
- package/dist/src/analysis/adapters/base.d.ts.map +1 -0
- package/dist/src/analysis/adapters/base.js +40 -0
- package/dist/src/analysis/adapters/base.js.map +1 -0
- package/dist/src/analysis/adapters/factory.d.ts +150 -0
- package/dist/src/analysis/adapters/factory.d.ts.map +1 -0
- package/dist/src/analysis/adapters/factory.js +244 -0
- package/dist/src/analysis/adapters/factory.js.map +1 -0
- package/dist/src/analysis/adapters/go.d.ts +131 -0
- package/dist/src/analysis/adapters/go.d.ts.map +1 -0
- package/dist/src/analysis/adapters/go.js +414 -0
- package/dist/src/analysis/adapters/go.js.map +1 -0
- package/dist/src/analysis/adapters/index.d.ts +20 -0
- package/dist/src/analysis/adapters/index.d.ts.map +1 -0
- package/dist/src/analysis/adapters/index.js +23 -0
- package/dist/src/analysis/adapters/index.js.map +1 -0
- package/dist/src/analysis/adapters/java.d.ts +154 -0
- package/dist/src/analysis/adapters/java.d.ts.map +1 -0
- package/dist/src/analysis/adapters/java.js +407 -0
- package/dist/src/analysis/adapters/java.js.map +1 -0
- package/dist/src/analysis/adapters/python.d.ts +165 -0
- package/dist/src/analysis/adapters/python.d.ts.map +1 -0
- package/dist/src/analysis/adapters/python.js +475 -0
- package/dist/src/analysis/adapters/python.js.map +1 -0
- package/dist/src/analysis/adapters/rust.d.ts +116 -0
- package/dist/src/analysis/adapters/rust.d.ts.map +1 -0
- package/dist/src/analysis/adapters/rust.js +476 -0
- package/dist/src/analysis/adapters/rust.js.map +1 -0
- package/dist/src/analysis/adapters/typescript.d.ts +68 -0
- package/dist/src/analysis/adapters/typescript.d.ts.map +1 -0
- package/dist/src/analysis/adapters/typescript.js +79 -0
- package/dist/src/analysis/adapters/typescript.js.map +1 -0
- package/dist/src/analysis/aggregator.d.ts +193 -0
- package/dist/src/analysis/aggregator.d.ts.map +1 -0
- package/dist/src/analysis/aggregator.js +283 -0
- package/dist/src/analysis/aggregator.js.map +1 -0
- package/dist/src/analysis/cache.d.ts +180 -0
- package/dist/src/analysis/cache.d.ts.map +1 -0
- package/dist/src/analysis/cache.js +279 -0
- package/dist/src/analysis/cache.js.map +1 -0
- package/dist/src/analysis/file-streamer.d.ts +136 -0
- package/dist/src/analysis/file-streamer.d.ts.map +1 -0
- package/dist/src/analysis/file-streamer.js +291 -0
- package/dist/src/analysis/file-streamer.js.map +1 -0
- package/dist/src/analysis/incremental-parser.d.ts +186 -0
- package/dist/src/analysis/incremental-parser.d.ts.map +1 -0
- package/dist/src/analysis/incremental-parser.js +291 -0
- package/dist/src/analysis/incremental-parser.js.map +1 -0
- package/dist/src/analysis/incremental.d.ts +186 -0
- package/dist/src/analysis/incremental.d.ts.map +1 -0
- package/dist/src/analysis/incremental.js +247 -0
- package/dist/src/analysis/incremental.js.map +1 -0
- package/dist/src/analysis/index.d.ts +25 -3
- package/dist/src/analysis/index.d.ts.map +1 -1
- package/dist/src/analysis/index.js +45 -3
- package/dist/src/analysis/index.js.map +1 -1
- package/dist/src/analysis/language-detector.d.ts +92 -0
- package/dist/src/analysis/language-detector.d.ts.map +1 -0
- package/dist/src/analysis/language-detector.js +602 -0
- package/dist/src/analysis/language-detector.js.map +1 -0
- package/dist/src/analysis/memory-monitor.d.ts +199 -0
- package/dist/src/analysis/memory-monitor.d.ts.map +1 -0
- package/dist/src/analysis/memory-monitor.js +271 -0
- package/dist/src/analysis/memory-monitor.js.map +1 -0
- package/dist/src/analysis/metrics.d.ts +300 -0
- package/dist/src/analysis/metrics.d.ts.map +1 -0
- package/dist/src/analysis/metrics.js +537 -0
- package/dist/src/analysis/metrics.js.map +1 -0
- package/dist/src/analysis/router.d.ts +264 -0
- package/dist/src/analysis/router.d.ts.map +1 -0
- package/dist/src/analysis/router.js +398 -0
- package/dist/src/analysis/router.js.map +1 -0
- package/dist/src/analysis/tree-cache.d.ts +208 -0
- package/dist/src/analysis/tree-cache.d.ts.map +1 -0
- package/dist/src/analysis/tree-cache.js +288 -0
- package/dist/src/analysis/tree-cache.js.map +1 -0
- package/dist/src/analysis/tree-sitter/manager.d.ts +141 -0
- package/dist/src/analysis/tree-sitter/manager.d.ts.map +1 -0
- package/dist/src/analysis/tree-sitter/manager.js +239 -0
- package/dist/src/analysis/tree-sitter/manager.js.map +1 -0
- package/dist/src/analysis/types.d.ts +69 -6
- package/dist/src/analysis/types.d.ts.map +1 -1
- package/dist/src/analysis/types.js +23 -2
- package/dist/src/analysis/types.js.map +1 -1
- package/dist/src/analysis/worker-pool.d.ts +141 -0
- package/dist/src/analysis/worker-pool.d.ts.map +1 -0
- package/dist/src/analysis/worker-pool.js +418 -0
- package/dist/src/analysis/worker-pool.js.map +1 -0
- package/dist/src/analytics/schema.d.ts +1 -1
- package/dist/src/analytics/schema.d.ts.map +1 -1
- package/dist/src/analytics/schema.js +72 -0
- package/dist/src/analytics/schema.js.map +1 -1
- package/dist/src/api/cache.d.ts +24 -1
- package/dist/src/api/cache.d.ts.map +1 -1
- package/dist/src/api/cache.js +50 -2
- package/dist/src/api/cache.js.map +1 -1
- package/dist/src/api/client.d.ts +132 -2
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +214 -18
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +7 -0
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/types.d.ts +251 -0
- package/dist/src/api/types.d.ts.map +1 -0
- package/dist/src/api/types.js +9 -0
- package/dist/src/api/types.js.map +1 -0
- package/dist/src/benchmarks/memory/MemoryProfiler.d.ts.map +1 -1
- package/dist/src/benchmarks/memory/MemoryProfiler.js.map +1 -1
- package/dist/src/embeddings/index.d.ts.map +1 -1
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +1 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/repositories/IndexerRepository.d.ts.map +1 -1
- package/dist/src/repositories/IndexerRepository.js +1 -0
- package/dist/src/repositories/IndexerRepository.js.map +1 -1
- package/dist/src/repositories/SkillRepository.d.ts.map +1 -1
- package/dist/src/repositories/SkillRepository.js +1 -0
- package/dist/src/repositories/SkillRepository.js.map +1 -1
- package/dist/src/repositories/quarantine/QuarantineRepository.d.ts.map +1 -1
- package/dist/src/repositories/quarantine/QuarantineRepository.js.map +1 -1
- package/dist/src/repositories/quarantine/query-builder.d.ts.map +1 -1
- package/dist/src/repositories/quarantine/query-builder.js +1 -1
- package/dist/src/repositories/quarantine/query-builder.js.map +1 -1
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js +3 -3
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
- package/dist/src/scripts/github-import/index.js.map +1 -1
- package/dist/src/scripts/import-github-skills.js +1 -1
- package/dist/src/scripts/import-github-skills.js.map +1 -1
- package/dist/src/scripts/skill-scanner/reporter.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/reporter.js.map +1 -1
- package/dist/src/scripts/skill-scanner/scanner.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/scanner.js.map +1 -1
- package/dist/src/scripts/skill-scanner/trust-scorer.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/trust-scorer.js.map +1 -1
- package/dist/src/scripts/validation/index.js +1 -2
- package/dist/src/scripts/validation/index.js.map +1 -1
- package/dist/src/scripts/validation/pipeline.d.ts.map +1 -1
- package/dist/src/scripts/validation/pipeline.js.map +1 -1
- package/dist/src/scripts/validation/types.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.js.map +1 -1
- package/dist/src/services/SearchService.d.ts.map +1 -1
- package/dist/src/services/SearchService.js +1 -0
- package/dist/src/services/SearchService.js.map +1 -1
- package/dist/src/session/SessionHealthMonitor.d.ts +1 -1
- package/dist/src/session/SessionHealthMonitor.d.ts.map +1 -1
- package/dist/src/session/SessionHealthMonitor.js +1 -1
- package/dist/src/session/SessionHealthMonitor.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +1 -1
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +2 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/posthog.d.ts +27 -5
- package/dist/src/telemetry/posthog.d.ts.map +1 -1
- package/dist/src/telemetry/posthog.js +20 -5
- package/dist/src/telemetry/posthog.js.map +1 -1
- package/dist/src/types/skill.d.ts +3 -0
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/types.d.ts +2 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +2 -2
- package/dist/src/types.js.map +1 -1
- package/dist/tests/adapters-factory.test.d.ts +13 -0
- package/dist/tests/adapters-factory.test.d.ts.map +1 -0
- package/dist/tests/adapters-factory.test.js +308 -0
- package/dist/tests/adapters-factory.test.js.map +1 -0
- package/dist/tests/adapters-java.test.d.ts +13 -0
- package/dist/tests/adapters-java.test.d.ts.map +1 -0
- package/dist/tests/adapters-java.test.js +925 -0
- package/dist/tests/adapters-java.test.js.map +1 -0
- package/dist/tests/api/client.validation.test.d.ts +7 -0
- package/dist/tests/api/client.validation.test.d.ts.map +1 -0
- package/dist/tests/api/client.validation.test.js +183 -0
- package/dist/tests/api/client.validation.test.js.map +1 -0
- package/dist/tests/language-detector.test.d.ts +13 -0
- package/dist/tests/language-detector.test.d.ts.map +1 -0
- package/dist/tests/language-detector.test.js +674 -0
- package/dist/tests/language-detector.test.js.map +1 -0
- package/dist/tests/telemetry/posthog.test.d.ts +13 -0
- package/dist/tests/telemetry/posthog.test.d.ts.map +1 -0
- package/dist/tests/telemetry/posthog.test.js +600 -0
- package/dist/tests/telemetry/posthog.test.js.map +1 -0
- package/package.json +5 -6
- package/dist/src/security/RateLimiter.d.ts +0 -337
- package/dist/src/security/RateLimiter.d.ts.map +0 -1
- package/dist/src/security/RateLimiter.js +0 -782
- package/dist/src/security/RateLimiter.js.map +0 -1
- package/dist/src/security/scanner.d.ts +0 -151
- package/dist/src/security/scanner.d.ts.map +0 -1
- package/dist/src/security/scanner.js +0 -599
- package/dist/src/security/scanner.js.map +0 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1303: Result Aggregator
|
|
3
|
+
* SMI-1337: Added metrics integration
|
|
4
|
+
*
|
|
5
|
+
* Aggregates parse results from multiple languages into unified context.
|
|
6
|
+
* Collects imports, exports, and functions across all analyzed files.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/architecture/multi-language-analysis.md
|
|
9
|
+
* @module analysis/aggregator
|
|
10
|
+
*/
|
|
11
|
+
import type { SupportedLanguage, ImportInfo, ExportInfo, FunctionInfo, ParseResult, CodebaseContext, FrameworkInfo, DependencyInfo } from './types.js';
|
|
12
|
+
import { type AnalysisMetrics } from './metrics.js';
|
|
13
|
+
/**
|
|
14
|
+
* Input for adding a parse result to the aggregator
|
|
15
|
+
*/
|
|
16
|
+
export interface AggregatorInput {
|
|
17
|
+
/** Path to the parsed file */
|
|
18
|
+
filePath: string;
|
|
19
|
+
/** Language of the file */
|
|
20
|
+
language: SupportedLanguage;
|
|
21
|
+
/** Parse result from the adapter */
|
|
22
|
+
result: ParseResult;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Metadata for building the final context
|
|
26
|
+
*/
|
|
27
|
+
export interface AggregatorMetadata {
|
|
28
|
+
/** Analysis duration in milliseconds */
|
|
29
|
+
durationMs: number;
|
|
30
|
+
/** Analyzer version string */
|
|
31
|
+
version: string;
|
|
32
|
+
/** Cache hit rate (0-1) */
|
|
33
|
+
cacheHitRate: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Options for ResultAggregator
|
|
37
|
+
*/
|
|
38
|
+
export interface AggregatorOptions {
|
|
39
|
+
/** Custom metrics instance (uses default if not provided) */
|
|
40
|
+
metrics?: AnalysisMetrics;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Aggregates parse results from multiple languages into unified context
|
|
44
|
+
*
|
|
45
|
+
* Collects results from individual file parses and merges them
|
|
46
|
+
* into a single CodebaseContext for skill recommendations.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const aggregator = new ResultAggregator()
|
|
51
|
+
*
|
|
52
|
+
* // Add results as files are parsed
|
|
53
|
+
* aggregator.add({
|
|
54
|
+
* filePath: 'src/main.py',
|
|
55
|
+
* language: 'python',
|
|
56
|
+
* result: pythonAdapter.parseFile(content, 'src/main.py')
|
|
57
|
+
* })
|
|
58
|
+
*
|
|
59
|
+
* aggregator.add({
|
|
60
|
+
* filePath: 'src/index.ts',
|
|
61
|
+
* language: 'typescript',
|
|
62
|
+
* result: tsAdapter.parseFile(content, 'src/index.ts')
|
|
63
|
+
* })
|
|
64
|
+
*
|
|
65
|
+
* // Build final context
|
|
66
|
+
* const context = aggregator.build('/path/to/project', dependencies, frameworks, metadata)
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare class ResultAggregator {
|
|
70
|
+
private imports;
|
|
71
|
+
private exports;
|
|
72
|
+
private functions;
|
|
73
|
+
private filesByExtension;
|
|
74
|
+
private filesByLanguage;
|
|
75
|
+
private totalLines;
|
|
76
|
+
private languages;
|
|
77
|
+
private fileCount;
|
|
78
|
+
private readonly metrics;
|
|
79
|
+
constructor(options?: AggregatorOptions);
|
|
80
|
+
/**
|
|
81
|
+
* Add parse result to aggregation
|
|
82
|
+
*
|
|
83
|
+
* Extracts imports, exports, and functions from the result
|
|
84
|
+
* and annotates them with language information.
|
|
85
|
+
*
|
|
86
|
+
* SMI-1337: Updates aggregator metrics.
|
|
87
|
+
*
|
|
88
|
+
* @param input - File path, language, and parse result
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* aggregator.add({
|
|
93
|
+
* filePath: 'src/utils.py',
|
|
94
|
+
* language: 'python',
|
|
95
|
+
* result: adapter.parseFile(content, 'src/utils.py')
|
|
96
|
+
* })
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
add(input: AggregatorInput): void;
|
|
100
|
+
/**
|
|
101
|
+
* Update aggregator metrics
|
|
102
|
+
* SMI-1337: Helper to keep metrics in sync
|
|
103
|
+
*/
|
|
104
|
+
private updateMetrics;
|
|
105
|
+
/**
|
|
106
|
+
* Add line count for a file
|
|
107
|
+
*
|
|
108
|
+
* Call this separately from add() if line counting is done
|
|
109
|
+
* during file reading rather than parsing.
|
|
110
|
+
*
|
|
111
|
+
* @param count - Number of lines in the file
|
|
112
|
+
*/
|
|
113
|
+
addLines(count: number): void;
|
|
114
|
+
/**
|
|
115
|
+
* Get current imports (read-only)
|
|
116
|
+
*/
|
|
117
|
+
getImports(): readonly ImportInfo[];
|
|
118
|
+
/**
|
|
119
|
+
* Get current exports (read-only)
|
|
120
|
+
*/
|
|
121
|
+
getExports(): readonly ExportInfo[];
|
|
122
|
+
/**
|
|
123
|
+
* Get current functions (read-only)
|
|
124
|
+
*/
|
|
125
|
+
getFunctions(): readonly FunctionInfo[];
|
|
126
|
+
/**
|
|
127
|
+
* Get current file count
|
|
128
|
+
*/
|
|
129
|
+
getFileCount(): number;
|
|
130
|
+
/**
|
|
131
|
+
* Get detected languages
|
|
132
|
+
*/
|
|
133
|
+
getLanguages(): SupportedLanguage[];
|
|
134
|
+
/**
|
|
135
|
+
* Build final CodebaseContext
|
|
136
|
+
*
|
|
137
|
+
* Combines all aggregated data with dependencies, frameworks,
|
|
138
|
+
* and metadata into the final context structure.
|
|
139
|
+
*
|
|
140
|
+
* SMI-1337: Records final aggregation metrics.
|
|
141
|
+
*
|
|
142
|
+
* @param rootPath - Root path of the analyzed codebase
|
|
143
|
+
* @param dependencies - Dependencies from all package managers
|
|
144
|
+
* @param frameworks - Detected frameworks
|
|
145
|
+
* @param metadata - Analysis metadata
|
|
146
|
+
* @returns Complete codebase context
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const context = aggregator.build(
|
|
151
|
+
* '/path/to/project',
|
|
152
|
+
* dependencies,
|
|
153
|
+
* frameworks,
|
|
154
|
+
* { durationMs: 1234, version: '2.0.0', cacheHitRate: 0.85 }
|
|
155
|
+
* )
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
build(rootPath: string, dependencies: DependencyInfo[], frameworks: FrameworkInfo[], metadata: AggregatorMetadata): CodebaseContext;
|
|
159
|
+
/**
|
|
160
|
+
* Build language stats with all languages initialized to 0
|
|
161
|
+
*/
|
|
162
|
+
private buildLanguageStats;
|
|
163
|
+
/**
|
|
164
|
+
* Reset aggregator for new analysis
|
|
165
|
+
*
|
|
166
|
+
* Clears all collected data. Call this before starting
|
|
167
|
+
* a new analysis on a different codebase.
|
|
168
|
+
*
|
|
169
|
+
* SMI-1337: Resets aggregator metrics as well.
|
|
170
|
+
*/
|
|
171
|
+
reset(): void;
|
|
172
|
+
/**
|
|
173
|
+
* Merge another aggregator's results into this one
|
|
174
|
+
*
|
|
175
|
+
* Useful for parallel processing where each worker
|
|
176
|
+
* has its own aggregator.
|
|
177
|
+
*
|
|
178
|
+
* @param other - Aggregator to merge from
|
|
179
|
+
*/
|
|
180
|
+
merge(other: ResultAggregator): void;
|
|
181
|
+
/**
|
|
182
|
+
* Get summary statistics
|
|
183
|
+
*/
|
|
184
|
+
getSummary(): {
|
|
185
|
+
files: number;
|
|
186
|
+
imports: number;
|
|
187
|
+
exports: number;
|
|
188
|
+
functions: number;
|
|
189
|
+
lines: number;
|
|
190
|
+
languages: SupportedLanguage[];
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../../../src/analysis/aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,2BAA2B;IAC3B,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAAiD;IACxE,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAE7B,OAAO,GAAE,iBAAsB;IAI3C;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IA6CjC;;;OAGG;IACH,OAAO,CAAC,aAAa;IASrB;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,UAAU,IAAI,SAAS,UAAU,EAAE;IAInC;;OAEG;IACH,UAAU,IAAI,SAAS,UAAU,EAAE;IAInC;;OAEG;IACH,YAAY,IAAI,SAAS,YAAY,EAAE;IAIvC;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,YAAY,IAAI,iBAAiB,EAAE;IAInC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,cAAc,EAAE,EAC9B,UAAU,EAAE,aAAa,EAAE,EAC3B,QAAQ,EAAE,kBAAkB,GAC3B,eAAe;IA2BlB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IAcb;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAoBpC;;OAEG;IACH,UAAU,IAAI;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,iBAAiB,EAAE,CAAA;KAC/B;CAUF"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1303: Result Aggregator
|
|
3
|
+
* SMI-1337: Added metrics integration
|
|
4
|
+
*
|
|
5
|
+
* Aggregates parse results from multiple languages into unified context.
|
|
6
|
+
* Collects imports, exports, and functions across all analyzed files.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/architecture/multi-language-analysis.md
|
|
9
|
+
* @module analysis/aggregator
|
|
10
|
+
*/
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { getAnalysisMetrics } from './metrics.js';
|
|
13
|
+
/**
|
|
14
|
+
* Aggregates parse results from multiple languages into unified context
|
|
15
|
+
*
|
|
16
|
+
* Collects results from individual file parses and merges them
|
|
17
|
+
* into a single CodebaseContext for skill recommendations.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const aggregator = new ResultAggregator()
|
|
22
|
+
*
|
|
23
|
+
* // Add results as files are parsed
|
|
24
|
+
* aggregator.add({
|
|
25
|
+
* filePath: 'src/main.py',
|
|
26
|
+
* language: 'python',
|
|
27
|
+
* result: pythonAdapter.parseFile(content, 'src/main.py')
|
|
28
|
+
* })
|
|
29
|
+
*
|
|
30
|
+
* aggregator.add({
|
|
31
|
+
* filePath: 'src/index.ts',
|
|
32
|
+
* language: 'typescript',
|
|
33
|
+
* result: tsAdapter.parseFile(content, 'src/index.ts')
|
|
34
|
+
* })
|
|
35
|
+
*
|
|
36
|
+
* // Build final context
|
|
37
|
+
* const context = aggregator.build('/path/to/project', dependencies, frameworks, metadata)
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class ResultAggregator {
|
|
41
|
+
imports = [];
|
|
42
|
+
exports = [];
|
|
43
|
+
functions = [];
|
|
44
|
+
filesByExtension = {};
|
|
45
|
+
filesByLanguage = {};
|
|
46
|
+
totalLines = 0;
|
|
47
|
+
languages = new Set();
|
|
48
|
+
fileCount = 0;
|
|
49
|
+
metrics;
|
|
50
|
+
constructor(options = {}) {
|
|
51
|
+
this.metrics = options.metrics ?? getAnalysisMetrics();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add parse result to aggregation
|
|
55
|
+
*
|
|
56
|
+
* Extracts imports, exports, and functions from the result
|
|
57
|
+
* and annotates them with language information.
|
|
58
|
+
*
|
|
59
|
+
* SMI-1337: Updates aggregator metrics.
|
|
60
|
+
*
|
|
61
|
+
* @param input - File path, language, and parse result
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* aggregator.add({
|
|
66
|
+
* filePath: 'src/utils.py',
|
|
67
|
+
* language: 'python',
|
|
68
|
+
* result: adapter.parseFile(content, 'src/utils.py')
|
|
69
|
+
* })
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
add(input) {
|
|
73
|
+
const { filePath, language, result } = input;
|
|
74
|
+
// Track language
|
|
75
|
+
this.languages.add(language);
|
|
76
|
+
this.filesByLanguage[language] = (this.filesByLanguage[language] ?? 0) + 1;
|
|
77
|
+
this.fileCount++;
|
|
78
|
+
// Track extension
|
|
79
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
80
|
+
if (ext) {
|
|
81
|
+
this.filesByExtension[ext] = (this.filesByExtension[ext] ?? 0) + 1;
|
|
82
|
+
}
|
|
83
|
+
// Add imports with language annotation
|
|
84
|
+
for (const imp of result.imports) {
|
|
85
|
+
this.imports.push({
|
|
86
|
+
...imp,
|
|
87
|
+
language,
|
|
88
|
+
sourceFile: filePath,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Add exports with language annotation
|
|
92
|
+
for (const exp of result.exports) {
|
|
93
|
+
this.exports.push({
|
|
94
|
+
...exp,
|
|
95
|
+
language,
|
|
96
|
+
sourceFile: filePath,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Add functions with language annotation
|
|
100
|
+
for (const func of result.functions) {
|
|
101
|
+
this.functions.push({
|
|
102
|
+
...func,
|
|
103
|
+
language,
|
|
104
|
+
sourceFile: filePath,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// SMI-1337: Update aggregator metrics
|
|
108
|
+
this.updateMetrics();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Update aggregator metrics
|
|
112
|
+
* SMI-1337: Helper to keep metrics in sync
|
|
113
|
+
*/
|
|
114
|
+
updateMetrics() {
|
|
115
|
+
this.metrics.updateAggregatorStats(this.fileCount, this.imports.length, this.exports.length, this.functions.length);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Add line count for a file
|
|
119
|
+
*
|
|
120
|
+
* Call this separately from add() if line counting is done
|
|
121
|
+
* during file reading rather than parsing.
|
|
122
|
+
*
|
|
123
|
+
* @param count - Number of lines in the file
|
|
124
|
+
*/
|
|
125
|
+
addLines(count) {
|
|
126
|
+
this.totalLines += count;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get current imports (read-only)
|
|
130
|
+
*/
|
|
131
|
+
getImports() {
|
|
132
|
+
return this.imports;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get current exports (read-only)
|
|
136
|
+
*/
|
|
137
|
+
getExports() {
|
|
138
|
+
return this.exports;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get current functions (read-only)
|
|
142
|
+
*/
|
|
143
|
+
getFunctions() {
|
|
144
|
+
return this.functions;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get current file count
|
|
148
|
+
*/
|
|
149
|
+
getFileCount() {
|
|
150
|
+
return this.fileCount;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get detected languages
|
|
154
|
+
*/
|
|
155
|
+
getLanguages() {
|
|
156
|
+
return Array.from(this.languages);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Build final CodebaseContext
|
|
160
|
+
*
|
|
161
|
+
* Combines all aggregated data with dependencies, frameworks,
|
|
162
|
+
* and metadata into the final context structure.
|
|
163
|
+
*
|
|
164
|
+
* SMI-1337: Records final aggregation metrics.
|
|
165
|
+
*
|
|
166
|
+
* @param rootPath - Root path of the analyzed codebase
|
|
167
|
+
* @param dependencies - Dependencies from all package managers
|
|
168
|
+
* @param frameworks - Detected frameworks
|
|
169
|
+
* @param metadata - Analysis metadata
|
|
170
|
+
* @returns Complete codebase context
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* const context = aggregator.build(
|
|
175
|
+
* '/path/to/project',
|
|
176
|
+
* dependencies,
|
|
177
|
+
* frameworks,
|
|
178
|
+
* { durationMs: 1234, version: '2.0.0', cacheHitRate: 0.85 }
|
|
179
|
+
* )
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
build(rootPath, dependencies, frameworks, metadata) {
|
|
183
|
+
// SMI-1337: Final metrics update
|
|
184
|
+
this.updateMetrics();
|
|
185
|
+
this.metrics.updateMemoryUsage();
|
|
186
|
+
return {
|
|
187
|
+
rootPath,
|
|
188
|
+
imports: this.imports,
|
|
189
|
+
exports: this.exports,
|
|
190
|
+
functions: this.functions,
|
|
191
|
+
frameworks,
|
|
192
|
+
dependencies,
|
|
193
|
+
stats: {
|
|
194
|
+
totalFiles: this.fileCount,
|
|
195
|
+
filesByExtension: { ...this.filesByExtension },
|
|
196
|
+
filesByLanguage: this.buildLanguageStats(),
|
|
197
|
+
totalLines: this.totalLines,
|
|
198
|
+
},
|
|
199
|
+
metadata: {
|
|
200
|
+
durationMs: metadata.durationMs,
|
|
201
|
+
version: metadata.version,
|
|
202
|
+
languages: Array.from(this.languages),
|
|
203
|
+
cacheHitRate: metadata.cacheHitRate,
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Build language stats with all languages initialized to 0
|
|
209
|
+
*/
|
|
210
|
+
buildLanguageStats() {
|
|
211
|
+
const stats = {
|
|
212
|
+
typescript: 0,
|
|
213
|
+
javascript: 0,
|
|
214
|
+
python: 0,
|
|
215
|
+
go: 0,
|
|
216
|
+
rust: 0,
|
|
217
|
+
java: 0,
|
|
218
|
+
};
|
|
219
|
+
for (const [lang, count] of Object.entries(this.filesByLanguage)) {
|
|
220
|
+
stats[lang] = count;
|
|
221
|
+
}
|
|
222
|
+
return stats;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Reset aggregator for new analysis
|
|
226
|
+
*
|
|
227
|
+
* Clears all collected data. Call this before starting
|
|
228
|
+
* a new analysis on a different codebase.
|
|
229
|
+
*
|
|
230
|
+
* SMI-1337: Resets aggregator metrics as well.
|
|
231
|
+
*/
|
|
232
|
+
reset() {
|
|
233
|
+
this.imports = [];
|
|
234
|
+
this.exports = [];
|
|
235
|
+
this.functions = [];
|
|
236
|
+
this.filesByExtension = {};
|
|
237
|
+
this.filesByLanguage = {};
|
|
238
|
+
this.totalLines = 0;
|
|
239
|
+
this.languages.clear();
|
|
240
|
+
this.fileCount = 0;
|
|
241
|
+
// SMI-1337: Reset metrics
|
|
242
|
+
this.updateMetrics();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Merge another aggregator's results into this one
|
|
246
|
+
*
|
|
247
|
+
* Useful for parallel processing where each worker
|
|
248
|
+
* has its own aggregator.
|
|
249
|
+
*
|
|
250
|
+
* @param other - Aggregator to merge from
|
|
251
|
+
*/
|
|
252
|
+
merge(other) {
|
|
253
|
+
this.imports.push(...other.imports);
|
|
254
|
+
this.exports.push(...other.exports);
|
|
255
|
+
this.functions.push(...other.functions);
|
|
256
|
+
this.totalLines += other.totalLines;
|
|
257
|
+
this.fileCount += other.fileCount;
|
|
258
|
+
// Merge extension counts
|
|
259
|
+
for (const [ext, count] of Object.entries(other.filesByExtension)) {
|
|
260
|
+
this.filesByExtension[ext] = (this.filesByExtension[ext] ?? 0) + count;
|
|
261
|
+
}
|
|
262
|
+
// Merge language counts
|
|
263
|
+
for (const [lang, count] of Object.entries(other.filesByLanguage)) {
|
|
264
|
+
const typedLang = lang;
|
|
265
|
+
this.filesByLanguage[typedLang] = (this.filesByLanguage[typedLang] ?? 0) + count;
|
|
266
|
+
this.languages.add(typedLang);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get summary statistics
|
|
271
|
+
*/
|
|
272
|
+
getSummary() {
|
|
273
|
+
return {
|
|
274
|
+
files: this.fileCount,
|
|
275
|
+
imports: this.imports.length,
|
|
276
|
+
exports: this.exports.length,
|
|
277
|
+
functions: this.functions.length,
|
|
278
|
+
lines: this.totalLines,
|
|
279
|
+
languages: Array.from(this.languages),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.js","sourceRoot":"","sources":["../../../src/analysis/aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1303: Parse Result Cache
|
|
3
|
+
* SMI-1337: Added metrics integration
|
|
4
|
+
*
|
|
5
|
+
* LRU cache for parse results with content hash validation.
|
|
6
|
+
* Provides memory-based eviction to prevent memory exhaustion.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/architecture/multi-language-analysis.md
|
|
9
|
+
* @module analysis/cache
|
|
10
|
+
*/
|
|
11
|
+
import type { ParseResult, CacheStats } from './types.js';
|
|
12
|
+
import { type AnalysisMetrics } from './metrics.js';
|
|
13
|
+
/**
|
|
14
|
+
* Options for ParseCache
|
|
15
|
+
*/
|
|
16
|
+
export interface ParseCacheOptions {
|
|
17
|
+
/** Maximum memory in MB (default: 200) */
|
|
18
|
+
maxMemoryMB?: number;
|
|
19
|
+
/** TTL in milliseconds (default: no TTL) */
|
|
20
|
+
ttlMs?: number;
|
|
21
|
+
/** Custom metrics instance (uses default if not provided) */
|
|
22
|
+
metrics?: AnalysisMetrics;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* LRU cache for parse results with memory-based eviction
|
|
26
|
+
*
|
|
27
|
+
* Caches parse results keyed by file path. Uses content hashing
|
|
28
|
+
* to detect when cached results are stale.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const cache = new ParseCache({ maxMemoryMB: 100 })
|
|
33
|
+
*
|
|
34
|
+
* // Check cache first
|
|
35
|
+
* const cached = cache.get('src/main.py', fileContent)
|
|
36
|
+
* if (cached) {
|
|
37
|
+
* return cached
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* // Parse and cache
|
|
41
|
+
* const result = adapter.parseFile(fileContent, 'src/main.py')
|
|
42
|
+
* cache.set('src/main.py', fileContent, result)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class ParseCache {
|
|
46
|
+
private cache;
|
|
47
|
+
private readonly maxMemory;
|
|
48
|
+
private readonly metrics;
|
|
49
|
+
private hits;
|
|
50
|
+
private misses;
|
|
51
|
+
constructor(options?: ParseCacheOptions);
|
|
52
|
+
/**
|
|
53
|
+
* Get cached result if content unchanged
|
|
54
|
+
*
|
|
55
|
+
* Returns null if:
|
|
56
|
+
* - No entry exists for the path
|
|
57
|
+
* - Content hash doesn't match (file was modified)
|
|
58
|
+
* - Entry was evicted due to memory pressure
|
|
59
|
+
*
|
|
60
|
+
* SMI-1337: Records cache hit/miss metrics.
|
|
61
|
+
*
|
|
62
|
+
* @param filePath - Path to the file
|
|
63
|
+
* @param content - Current file content for hash comparison
|
|
64
|
+
* @returns Cached parse result or null
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const cached = cache.get('src/main.py', fileContent)
|
|
69
|
+
* if (cached) {
|
|
70
|
+
* console.log('Cache hit!')
|
|
71
|
+
* return cached
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
get(filePath: string, content: string): ParseResult | null;
|
|
76
|
+
/**
|
|
77
|
+
* Store parse result in cache
|
|
78
|
+
*
|
|
79
|
+
* The result is stored with a content hash for future validation.
|
|
80
|
+
* If the cache is at capacity, least recently used entries
|
|
81
|
+
* are evicted to make room.
|
|
82
|
+
*
|
|
83
|
+
* SMI-1337: Updates cache size metrics.
|
|
84
|
+
*
|
|
85
|
+
* @param filePath - Path to the file
|
|
86
|
+
* @param content - File content (used for hash)
|
|
87
|
+
* @param result - Parse result to cache
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const result = adapter.parseFile(content, 'src/main.py')
|
|
92
|
+
* cache.set('src/main.py', content, result)
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
set(filePath: string, content: string, result: ParseResult): void;
|
|
96
|
+
/**
|
|
97
|
+
* Check if a file is cached (without counting as hit/miss)
|
|
98
|
+
*
|
|
99
|
+
* @param filePath - Path to check
|
|
100
|
+
* @returns True if entry exists (may be stale)
|
|
101
|
+
*/
|
|
102
|
+
has(filePath: string): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Invalidate cache entries for changed files
|
|
105
|
+
*
|
|
106
|
+
* Call this when files are known to have changed
|
|
107
|
+
* to prevent stale cache hits.
|
|
108
|
+
*
|
|
109
|
+
* @param filePaths - Paths to invalidate
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* // On file system change event
|
|
114
|
+
* cache.invalidate(['src/modified.py', 'src/deleted.py'])
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
invalidate(filePaths: string[]): void;
|
|
118
|
+
/**
|
|
119
|
+
* Invalidate entries matching a pattern
|
|
120
|
+
*
|
|
121
|
+
* @param pattern - Glob-like pattern to match
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // Invalidate all Python files
|
|
126
|
+
* cache.invalidatePattern('*.py')
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
invalidatePattern(pattern: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* Clear entire cache
|
|
132
|
+
*
|
|
133
|
+
* Removes all entries and resets statistics.
|
|
134
|
+
*/
|
|
135
|
+
clear(): void;
|
|
136
|
+
/**
|
|
137
|
+
* Get cache statistics
|
|
138
|
+
*
|
|
139
|
+
* @returns Current cache statistics
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const stats = cache.getStats()
|
|
144
|
+
* console.log(`Hit rate: ${(stats.hitRate * 100).toFixed(1)}%`)
|
|
145
|
+
* console.log(`Size: ${(stats.size / 1024 / 1024).toFixed(1)} MB`)
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
getStats(): CacheStats;
|
|
149
|
+
/**
|
|
150
|
+
* Get number of cached entries
|
|
151
|
+
*/
|
|
152
|
+
get size(): number;
|
|
153
|
+
/**
|
|
154
|
+
* Reset hit/miss counters
|
|
155
|
+
*/
|
|
156
|
+
resetStats(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Hash file content for change detection
|
|
159
|
+
*
|
|
160
|
+
* Uses SHA-256 truncated to 16 characters for efficiency.
|
|
161
|
+
*/
|
|
162
|
+
private hashContent;
|
|
163
|
+
/**
|
|
164
|
+
* Get language from file path extension
|
|
165
|
+
* SMI-1337: Helper for metrics labeling
|
|
166
|
+
*/
|
|
167
|
+
private getLanguageFromPath;
|
|
168
|
+
/**
|
|
169
|
+
* Estimate memory size of a parse result
|
|
170
|
+
*
|
|
171
|
+
* Rough estimate based on array sizes and average item sizes.
|
|
172
|
+
* SMI-1335: Named constants for magic numbers
|
|
173
|
+
*/
|
|
174
|
+
private estimateSize;
|
|
175
|
+
/**
|
|
176
|
+
* Convert glob pattern to regex
|
|
177
|
+
*/
|
|
178
|
+
private patternToRegex;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/analysis/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAgBvE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,eAAe,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,IAAI,CAAI;IAChB,OAAO,CAAC,MAAM,CAAI;gBAEN,OAAO,GAAE,iBAAsB;IAa3C;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAyB1D;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAejE;;;;;OAKG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAMrC;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IASxC;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAMb;;;;;;;;;;;OAWG;IACH,QAAQ,IAAI,UAAU;IAUtB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAInB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,cAAc;CAQvB"}
|