@skillsmith/core 0.1.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/dist/.tsbuildinfo +1 -0
- package/dist/src/__tests__/errors.test.d.ts +5 -0
- package/dist/src/__tests__/errors.test.d.ts.map +1 -0
- package/dist/src/__tests__/errors.test.js +115 -0
- package/dist/src/__tests__/errors.test.js.map +1 -0
- package/dist/src/activation/ActivationManager.d.ts +141 -0
- package/dist/src/activation/ActivationManager.d.ts.map +1 -0
- package/dist/src/activation/ActivationManager.js +282 -0
- package/dist/src/activation/ActivationManager.js.map +1 -0
- package/dist/src/activation/ZeroConfigActivator.d.ts +126 -0
- package/dist/src/activation/ZeroConfigActivator.d.ts.map +1 -0
- package/dist/src/activation/ZeroConfigActivator.js +259 -0
- package/dist/src/activation/ZeroConfigActivator.js.map +1 -0
- package/dist/src/activation/index.d.ts +8 -0
- package/dist/src/activation/index.d.ts.map +1 -0
- package/dist/src/activation/index.js +8 -0
- package/dist/src/activation/index.js.map +1 -0
- package/dist/src/analysis/CodebaseAnalyzer.d.ts +175 -0
- package/dist/src/analysis/CodebaseAnalyzer.d.ts.map +1 -0
- package/dist/src/analysis/CodebaseAnalyzer.js +495 -0
- package/dist/src/analysis/CodebaseAnalyzer.js.map +1 -0
- package/dist/src/analysis/index.d.ts +10 -0
- package/dist/src/analysis/index.d.ts.map +1 -0
- package/dist/src/analysis/index.js +10 -0
- package/dist/src/analysis/index.js.map +1 -0
- package/dist/src/analytics/AnalyticsRepository.d.ts +97 -0
- package/dist/src/analytics/AnalyticsRepository.d.ts.map +1 -0
- package/dist/src/analytics/AnalyticsRepository.js +376 -0
- package/dist/src/analytics/AnalyticsRepository.js.map +1 -0
- package/dist/src/analytics/ExperimentService.d.ts +70 -0
- package/dist/src/analytics/ExperimentService.d.ts.map +1 -0
- package/dist/src/analytics/ExperimentService.js +251 -0
- package/dist/src/analytics/ExperimentService.js.map +1 -0
- package/dist/src/analytics/ROIDashboardService.d.ts +55 -0
- package/dist/src/analytics/ROIDashboardService.d.ts.map +1 -0
- package/dist/src/analytics/ROIDashboardService.js +304 -0
- package/dist/src/analytics/ROIDashboardService.js.map +1 -0
- package/dist/src/analytics/UsageAnalyticsService.d.ts +55 -0
- package/dist/src/analytics/UsageAnalyticsService.d.ts.map +1 -0
- package/dist/src/analytics/UsageAnalyticsService.js +180 -0
- package/dist/src/analytics/UsageAnalyticsService.js.map +1 -0
- package/dist/src/analytics/anonymizer.d.ts +53 -0
- package/dist/src/analytics/anonymizer.d.ts.map +1 -0
- package/dist/src/analytics/anonymizer.js +107 -0
- package/dist/src/analytics/anonymizer.js.map +1 -0
- package/dist/src/analytics/constants.d.ts +19 -0
- package/dist/src/analytics/constants.d.ts.map +1 -0
- package/dist/src/analytics/constants.js +19 -0
- package/dist/src/analytics/constants.js.map +1 -0
- package/dist/src/analytics/index.d.ts +23 -0
- package/dist/src/analytics/index.d.ts.map +1 -0
- package/dist/src/analytics/index.js +23 -0
- package/dist/src/analytics/index.js.map +1 -0
- package/dist/src/analytics/metrics-aggregator.d.ts +98 -0
- package/dist/src/analytics/metrics-aggregator.d.ts.map +1 -0
- package/dist/src/analytics/metrics-aggregator.js +176 -0
- package/dist/src/analytics/metrics-aggregator.js.map +1 -0
- package/dist/src/analytics/metrics-exporter.d.ts +148 -0
- package/dist/src/analytics/metrics-exporter.d.ts.map +1 -0
- package/dist/src/analytics/metrics-exporter.js +244 -0
- package/dist/src/analytics/metrics-exporter.js.map +1 -0
- package/dist/src/analytics/schema.d.ts +20 -0
- package/dist/src/analytics/schema.d.ts.map +1 -0
- package/dist/src/analytics/schema.js +125 -0
- package/dist/src/analytics/schema.js.map +1 -0
- package/dist/src/analytics/storage.d.ts +76 -0
- package/dist/src/analytics/storage.d.ts.map +1 -0
- package/dist/src/analytics/storage.js +180 -0
- package/dist/src/analytics/storage.js.map +1 -0
- package/dist/src/analytics/types.d.ts +277 -0
- package/dist/src/analytics/types.d.ts.map +1 -0
- package/dist/src/analytics/types.js +10 -0
- package/dist/src/analytics/types.js.map +1 -0
- package/dist/src/analytics/usage-tracker.d.ts +132 -0
- package/dist/src/analytics/usage-tracker.d.ts.map +1 -0
- package/dist/src/analytics/usage-tracker.js +213 -0
- package/dist/src/analytics/usage-tracker.js.map +1 -0
- package/dist/src/benchmarks/BenchmarkRunner.d.ts +258 -0
- package/dist/src/benchmarks/BenchmarkRunner.d.ts.map +1 -0
- package/dist/src/benchmarks/BenchmarkRunner.js +453 -0
- package/dist/src/benchmarks/BenchmarkRunner.js.map +1 -0
- package/dist/src/benchmarks/IndexBenchmark.d.ts +101 -0
- package/dist/src/benchmarks/IndexBenchmark.d.ts.map +1 -0
- package/dist/src/benchmarks/IndexBenchmark.js +314 -0
- package/dist/src/benchmarks/IndexBenchmark.js.map +1 -0
- package/dist/src/benchmarks/MemoryProfiler.d.ts +266 -0
- package/dist/src/benchmarks/MemoryProfiler.d.ts.map +1 -0
- package/dist/src/benchmarks/MemoryProfiler.js +404 -0
- package/dist/src/benchmarks/MemoryProfiler.js.map +1 -0
- package/dist/src/benchmarks/SearchBenchmark.d.ts +71 -0
- package/dist/src/benchmarks/SearchBenchmark.d.ts.map +1 -0
- package/dist/src/benchmarks/SearchBenchmark.js +321 -0
- package/dist/src/benchmarks/SearchBenchmark.js.map +1 -0
- package/dist/src/benchmarks/cacheBenchmark.d.ts +75 -0
- package/dist/src/benchmarks/cacheBenchmark.d.ts.map +1 -0
- package/dist/src/benchmarks/cacheBenchmark.js +325 -0
- package/dist/src/benchmarks/cacheBenchmark.js.map +1 -0
- package/dist/src/benchmarks/cli.d.ts +17 -0
- package/dist/src/benchmarks/cli.d.ts.map +1 -0
- package/dist/src/benchmarks/cli.js +140 -0
- package/dist/src/benchmarks/cli.js.map +1 -0
- package/dist/src/benchmarks/embeddingBenchmark.d.ts +86 -0
- package/dist/src/benchmarks/embeddingBenchmark.d.ts.map +1 -0
- package/dist/src/benchmarks/embeddingBenchmark.js +329 -0
- package/dist/src/benchmarks/embeddingBenchmark.js.map +1 -0
- package/dist/src/benchmarks/index.d.ts +51 -0
- package/dist/src/benchmarks/index.d.ts.map +1 -0
- package/dist/src/benchmarks/index.js +201 -0
- package/dist/src/benchmarks/index.js.map +1 -0
- package/dist/src/benchmarks/stats.d.ts +56 -0
- package/dist/src/benchmarks/stats.d.ts.map +1 -0
- package/dist/src/benchmarks/stats.js +86 -0
- package/dist/src/benchmarks/stats.js.map +1 -0
- package/dist/src/cache/CacheEntry.d.ts +101 -0
- package/dist/src/cache/CacheEntry.d.ts.map +1 -0
- package/dist/src/cache/CacheEntry.js +238 -0
- package/dist/src/cache/CacheEntry.js.map +1 -0
- package/dist/src/cache/CacheManager.d.ts +167 -0
- package/dist/src/cache/CacheManager.d.ts.map +1 -0
- package/dist/src/cache/CacheManager.js +346 -0
- package/dist/src/cache/CacheManager.js.map +1 -0
- package/dist/src/cache/TieredCache.d.ts +97 -0
- package/dist/src/cache/TieredCache.d.ts.map +1 -0
- package/dist/src/cache/TieredCache.js +352 -0
- package/dist/src/cache/TieredCache.js.map +1 -0
- package/dist/src/cache/index.d.ts +63 -0
- package/dist/src/cache/index.d.ts.map +1 -0
- package/dist/src/cache/index.js +91 -0
- package/dist/src/cache/index.js.map +1 -0
- package/dist/src/cache/lru.d.ts +68 -0
- package/dist/src/cache/lru.d.ts.map +1 -0
- package/dist/src/cache/lru.js +105 -0
- package/dist/src/cache/lru.js.map +1 -0
- package/dist/src/cache/sqlite.d.ts +59 -0
- package/dist/src/cache/sqlite.d.ts.map +1 -0
- package/dist/src/cache/sqlite.js +159 -0
- package/dist/src/cache/sqlite.js.map +1 -0
- package/dist/src/db/quarantine-schema.d.ts +81 -0
- package/dist/src/db/quarantine-schema.d.ts.map +1 -0
- package/dist/src/db/quarantine-schema.js +110 -0
- package/dist/src/db/quarantine-schema.js.map +1 -0
- package/dist/src/db/schema.d.ts +65 -0
- package/dist/src/db/schema.d.ts.map +1 -0
- package/dist/src/db/schema.js +318 -0
- package/dist/src/db/schema.js.map +1 -0
- package/dist/src/embeddings/index.d.ts +158 -0
- package/dist/src/embeddings/index.d.ts.map +1 -0
- package/dist/src/embeddings/index.js +397 -0
- package/dist/src/embeddings/index.js.map +1 -0
- package/dist/src/errors/SkillsmithError.d.ts +118 -0
- package/dist/src/errors/SkillsmithError.d.ts.map +1 -0
- package/dist/src/errors/SkillsmithError.js +194 -0
- package/dist/src/errors/SkillsmithError.js.map +1 -0
- package/dist/src/errors/index.d.ts +36 -0
- package/dist/src/errors/index.d.ts.map +1 -0
- package/dist/src/errors/index.js +36 -0
- package/dist/src/errors/index.js.map +1 -0
- package/dist/src/errors.d.ts +72 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +123 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +56 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +73 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +2 -0
- package/dist/src/index.test.d.ts.map +1 -0
- package/dist/src/index.test.js +35 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/indexer/GitHubIndexer.d.ts +107 -0
- package/dist/src/indexer/GitHubIndexer.d.ts.map +1 -0
- package/dist/src/indexer/GitHubIndexer.js +202 -0
- package/dist/src/indexer/GitHubIndexer.js.map +1 -0
- package/dist/src/indexer/PartitionStrategy.d.ts +115 -0
- package/dist/src/indexer/PartitionStrategy.d.ts.map +1 -0
- package/dist/src/indexer/PartitionStrategy.js +207 -0
- package/dist/src/indexer/PartitionStrategy.js.map +1 -0
- package/dist/src/indexer/SkillParser.d.ts +112 -0
- package/dist/src/indexer/SkillParser.d.ts.map +1 -0
- package/dist/src/indexer/SkillParser.js +281 -0
- package/dist/src/indexer/SkillParser.js.map +1 -0
- package/dist/src/indexer/SwarmIndexer.d.ts +163 -0
- package/dist/src/indexer/SwarmIndexer.d.ts.map +1 -0
- package/dist/src/indexer/SwarmIndexer.js +300 -0
- package/dist/src/indexer/SwarmIndexer.js.map +1 -0
- package/dist/src/indexer/index.d.ts +12 -0
- package/dist/src/indexer/index.d.ts.map +1 -0
- package/dist/src/indexer/index.js +16 -0
- package/dist/src/indexer/index.js.map +1 -0
- package/dist/src/learning/interfaces.d.ts +338 -0
- package/dist/src/learning/interfaces.d.ts.map +1 -0
- package/dist/src/learning/interfaces.js +13 -0
- package/dist/src/learning/interfaces.js.map +1 -0
- package/dist/src/learning/types.d.ts +284 -0
- package/dist/src/learning/types.d.ts.map +1 -0
- package/dist/src/learning/types.js +112 -0
- package/dist/src/learning/types.js.map +1 -0
- package/dist/src/matching/OverlapDetector.d.ts +152 -0
- package/dist/src/matching/OverlapDetector.d.ts.map +1 -0
- package/dist/src/matching/OverlapDetector.js +218 -0
- package/dist/src/matching/OverlapDetector.js.map +1 -0
- package/dist/src/matching/SkillMatcher.d.ts +125 -0
- package/dist/src/matching/SkillMatcher.d.ts.map +1 -0
- package/dist/src/matching/SkillMatcher.js +206 -0
- package/dist/src/matching/SkillMatcher.js.map +1 -0
- package/dist/src/matching/index.d.ts +14 -0
- package/dist/src/matching/index.d.ts.map +1 -0
- package/dist/src/matching/index.js +12 -0
- package/dist/src/matching/index.js.map +1 -0
- package/dist/src/pipeline/DailyIndexPipeline.d.ts +220 -0
- package/dist/src/pipeline/DailyIndexPipeline.d.ts.map +1 -0
- package/dist/src/pipeline/DailyIndexPipeline.js +320 -0
- package/dist/src/pipeline/DailyIndexPipeline.js.map +1 -0
- package/dist/src/pipeline/index.d.ts +9 -0
- package/dist/src/pipeline/index.d.ts.map +1 -0
- package/dist/src/pipeline/index.js +9 -0
- package/dist/src/pipeline/index.js.map +1 -0
- package/dist/src/repositories/CacheRepository.d.ts +60 -0
- package/dist/src/repositories/CacheRepository.d.ts.map +1 -0
- package/dist/src/repositories/CacheRepository.js +148 -0
- package/dist/src/repositories/CacheRepository.js.map +1 -0
- package/dist/src/repositories/IndexerRepository.d.ts +126 -0
- package/dist/src/repositories/IndexerRepository.d.ts.map +1 -0
- package/dist/src/repositories/IndexerRepository.js +270 -0
- package/dist/src/repositories/IndexerRepository.js.map +1 -0
- package/dist/src/repositories/QuarantineRepository.d.ts +255 -0
- package/dist/src/repositories/QuarantineRepository.d.ts.map +1 -0
- package/dist/src/repositories/QuarantineRepository.js +445 -0
- package/dist/src/repositories/QuarantineRepository.js.map +1 -0
- package/dist/src/repositories/SkillRepository.d.ts +78 -0
- package/dist/src/repositories/SkillRepository.d.ts.map +1 -0
- package/dist/src/repositories/SkillRepository.js +208 -0
- package/dist/src/repositories/SkillRepository.js.map +1 -0
- package/dist/src/scoring/QualityScorer.d.ts +188 -0
- package/dist/src/scoring/QualityScorer.d.ts.map +1 -0
- package/dist/src/scoring/QualityScorer.js +342 -0
- package/dist/src/scoring/QualityScorer.js.map +1 -0
- package/dist/src/scoring/index.d.ts +9 -0
- package/dist/src/scoring/index.d.ts.map +1 -0
- package/dist/src/scoring/index.js +9 -0
- package/dist/src/scoring/index.js.map +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.d.ts +5 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.d.ts.map +1 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js +365 -0
- package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -0
- package/dist/src/scripts/import-github-skills.d.ts +24 -0
- package/dist/src/scripts/import-github-skills.d.ts.map +1 -0
- package/dist/src/scripts/import-github-skills.js +545 -0
- package/dist/src/scripts/import-github-skills.js.map +1 -0
- package/dist/src/scripts/import-to-database.d.ts +60 -0
- package/dist/src/scripts/import-to-database.d.ts.map +1 -0
- package/dist/src/scripts/import-to-database.js +307 -0
- package/dist/src/scripts/import-to-database.js.map +1 -0
- package/dist/src/scripts/scan-imported-skills.d.ts +15 -0
- package/dist/src/scripts/scan-imported-skills.d.ts.map +1 -0
- package/dist/src/scripts/scan-imported-skills.js +405 -0
- package/dist/src/scripts/scan-imported-skills.js.map +1 -0
- package/dist/src/scripts/validate-skills.d.ts +180 -0
- package/dist/src/scripts/validate-skills.d.ts.map +1 -0
- package/dist/src/scripts/validate-skills.js +572 -0
- package/dist/src/scripts/validate-skills.js.map +1 -0
- package/dist/src/search/hybrid.d.ts +85 -0
- package/dist/src/search/hybrid.d.ts.map +1 -0
- package/dist/src/search/hybrid.js +291 -0
- package/dist/src/search/hybrid.js.map +1 -0
- package/dist/src/search/index.d.ts +6 -0
- package/dist/src/search/index.d.ts.map +1 -0
- package/dist/src/search/index.js +5 -0
- package/dist/src/search/index.js.map +1 -0
- package/dist/src/security/AuditLogger.d.ts +197 -0
- package/dist/src/security/AuditLogger.d.ts.map +1 -0
- package/dist/src/security/AuditLogger.js +398 -0
- package/dist/src/security/AuditLogger.js.map +1 -0
- package/dist/src/security/RateLimiter.d.ts +337 -0
- package/dist/src/security/RateLimiter.d.ts.map +1 -0
- package/dist/src/security/RateLimiter.js +782 -0
- package/dist/src/security/RateLimiter.js.map +1 -0
- package/dist/src/security/__tests__/pathValidation.test.d.ts +8 -0
- package/dist/src/security/__tests__/pathValidation.test.d.ts.map +1 -0
- package/dist/src/security/__tests__/pathValidation.test.js +249 -0
- package/dist/src/security/__tests__/pathValidation.test.js.map +1 -0
- package/dist/src/security/index.d.ts +18 -0
- package/dist/src/security/index.d.ts.map +1 -0
- package/dist/src/security/index.js +14 -0
- package/dist/src/security/index.js.map +1 -0
- package/dist/src/security/pathValidation.d.ts +95 -0
- package/dist/src/security/pathValidation.d.ts.map +1 -0
- package/dist/src/security/pathValidation.js +216 -0
- package/dist/src/security/pathValidation.js.map +1 -0
- package/dist/src/security/sanitization.d.ts +123 -0
- package/dist/src/security/sanitization.d.ts.map +1 -0
- package/dist/src/security/sanitization.js +378 -0
- package/dist/src/security/sanitization.js.map +1 -0
- package/dist/src/security/scanner.d.ts +151 -0
- package/dist/src/security/scanner.d.ts.map +1 -0
- package/dist/src/security/scanner.js +599 -0
- package/dist/src/security/scanner.js.map +1 -0
- package/dist/src/services/SearchService.d.ts +88 -0
- package/dist/src/services/SearchService.d.ts.map +1 -0
- package/dist/src/services/SearchService.js +305 -0
- package/dist/src/services/SearchService.js.map +1 -0
- package/dist/src/session/SessionContext.d.ts +116 -0
- package/dist/src/session/SessionContext.d.ts.map +1 -0
- package/dist/src/session/SessionContext.js +134 -0
- package/dist/src/session/SessionContext.js.map +1 -0
- package/dist/src/session/SessionHealthMonitor.d.ts +249 -0
- package/dist/src/session/SessionHealthMonitor.d.ts.map +1 -0
- package/dist/src/session/SessionHealthMonitor.js +302 -0
- package/dist/src/session/SessionHealthMonitor.js.map +1 -0
- package/dist/src/session/SessionManager.d.ts +179 -0
- package/dist/src/session/SessionManager.d.ts.map +1 -0
- package/dist/src/session/SessionManager.js +451 -0
- package/dist/src/session/SessionManager.js.map +1 -0
- package/dist/src/session/SessionRecovery.d.ts +84 -0
- package/dist/src/session/SessionRecovery.d.ts.map +1 -0
- package/dist/src/session/SessionRecovery.js +257 -0
- package/dist/src/session/SessionRecovery.js.map +1 -0
- package/dist/src/session/index.d.ts +40 -0
- package/dist/src/session/index.d.ts.map +1 -0
- package/dist/src/session/index.js +44 -0
- package/dist/src/session/index.js.map +1 -0
- package/dist/src/sources/BaseSourceAdapter.d.ts +144 -0
- package/dist/src/sources/BaseSourceAdapter.d.ts.map +1 -0
- package/dist/src/sources/BaseSourceAdapter.js +287 -0
- package/dist/src/sources/BaseSourceAdapter.js.map +1 -0
- package/dist/src/sources/GitHubSourceAdapter.d.ts +98 -0
- package/dist/src/sources/GitHubSourceAdapter.d.ts.map +1 -0
- package/dist/src/sources/GitHubSourceAdapter.js +269 -0
- package/dist/src/sources/GitHubSourceAdapter.js.map +1 -0
- package/dist/src/sources/GitLabSourceAdapter.d.ts +102 -0
- package/dist/src/sources/GitLabSourceAdapter.d.ts.map +1 -0
- package/dist/src/sources/GitLabSourceAdapter.js +310 -0
- package/dist/src/sources/GitLabSourceAdapter.js.map +1 -0
- package/dist/src/sources/ISourceAdapter.d.ts +110 -0
- package/dist/src/sources/ISourceAdapter.d.ts.map +1 -0
- package/dist/src/sources/ISourceAdapter.js +19 -0
- package/dist/src/sources/ISourceAdapter.js.map +1 -0
- package/dist/src/sources/LocalFilesystemAdapter.d.ts +112 -0
- package/dist/src/sources/LocalFilesystemAdapter.d.ts.map +1 -0
- package/dist/src/sources/LocalFilesystemAdapter.js +340 -0
- package/dist/src/sources/LocalFilesystemAdapter.js.map +1 -0
- package/dist/src/sources/RawUrlSourceAdapter.d.ts +128 -0
- package/dist/src/sources/RawUrlSourceAdapter.d.ts.map +1 -0
- package/dist/src/sources/RawUrlSourceAdapter.js +282 -0
- package/dist/src/sources/RawUrlSourceAdapter.js.map +1 -0
- package/dist/src/sources/SourceAdapterRegistry.d.ts +156 -0
- package/dist/src/sources/SourceAdapterRegistry.d.ts.map +1 -0
- package/dist/src/sources/SourceAdapterRegistry.js +242 -0
- package/dist/src/sources/SourceAdapterRegistry.js.map +1 -0
- package/dist/src/sources/SourceIndexer.d.ts +119 -0
- package/dist/src/sources/SourceIndexer.d.ts.map +1 -0
- package/dist/src/sources/SourceIndexer.js +285 -0
- package/dist/src/sources/SourceIndexer.js.map +1 -0
- package/dist/src/sources/index.d.ts +45 -0
- package/dist/src/sources/index.d.ts.map +1 -0
- package/dist/src/sources/index.js +51 -0
- package/dist/src/sources/index.js.map +1 -0
- package/dist/src/sources/shared.d.ts +125 -0
- package/dist/src/sources/shared.d.ts.map +1 -0
- package/dist/src/sources/shared.js +191 -0
- package/dist/src/sources/shared.js.map +1 -0
- package/dist/src/sources/types.d.ts +204 -0
- package/dist/src/sources/types.d.ts.map +1 -0
- package/dist/src/sources/types.js +6 -0
- package/dist/src/sources/types.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +25 -0
- package/dist/src/telemetry/index.d.ts.map +1 -0
- package/dist/src/telemetry/index.js +32 -0
- package/dist/src/telemetry/index.js.map +1 -0
- package/dist/src/telemetry/metrics.d.ts +171 -0
- package/dist/src/telemetry/metrics.d.ts.map +1 -0
- package/dist/src/telemetry/metrics.js +401 -0
- package/dist/src/telemetry/metrics.js.map +1 -0
- package/dist/src/telemetry/prometheus.d.ts +81 -0
- package/dist/src/telemetry/prometheus.d.ts.map +1 -0
- package/dist/src/telemetry/prometheus.js +252 -0
- package/dist/src/telemetry/prometheus.js.map +1 -0
- package/dist/src/telemetry/tracer.d.ts +151 -0
- package/dist/src/telemetry/tracer.d.ts.map +1 -0
- package/dist/src/telemetry/tracer.js +391 -0
- package/dist/src/telemetry/tracer.js.map +1 -0
- package/dist/src/triggers/ContextScorer.d.ts +118 -0
- package/dist/src/triggers/ContextScorer.d.ts.map +1 -0
- package/dist/src/triggers/ContextScorer.js +265 -0
- package/dist/src/triggers/ContextScorer.js.map +1 -0
- package/dist/src/triggers/TriggerDetector.d.ts +178 -0
- package/dist/src/triggers/TriggerDetector.d.ts.map +1 -0
- package/dist/src/triggers/TriggerDetector.js +390 -0
- package/dist/src/triggers/TriggerDetector.js.map +1 -0
- package/dist/src/triggers/__tests__/ContextScorer.test.d.ts +6 -0
- package/dist/src/triggers/__tests__/ContextScorer.test.d.ts.map +1 -0
- package/dist/src/triggers/__tests__/ContextScorer.test.js +307 -0
- package/dist/src/triggers/__tests__/ContextScorer.test.js.map +1 -0
- package/dist/src/triggers/__tests__/TriggerDetector.test.d.ts +6 -0
- package/dist/src/triggers/__tests__/TriggerDetector.test.d.ts.map +1 -0
- package/dist/src/triggers/__tests__/TriggerDetector.test.js +249 -0
- package/dist/src/triggers/__tests__/TriggerDetector.test.js.map +1 -0
- package/dist/src/triggers/index.d.ts +8 -0
- package/dist/src/triggers/index.d.ts.map +1 -0
- package/dist/src/triggers/index.js +8 -0
- package/dist/src/triggers/index.js.map +1 -0
- package/dist/src/types/skill.d.ts +80 -0
- package/dist/src/types/skill.d.ts.map +1 -0
- package/dist/src/types/skill.js +5 -0
- package/dist/src/types/skill.js.map +1 -0
- package/dist/src/types.d.ts +88 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +13 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/index.d.ts +6 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +6 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +172 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +291 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/retry.d.ts +97 -0
- package/dist/src/utils/retry.d.ts.map +1 -0
- package/dist/src/utils/retry.js +267 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/validation/index.d.ts +118 -0
- package/dist/src/validation/index.d.ts.map +1 -0
- package/dist/src/validation/index.js +434 -0
- package/dist/src/validation/index.js.map +1 -0
- package/dist/src/webhooks/WebhookHandler.d.ts +117 -0
- package/dist/src/webhooks/WebhookHandler.d.ts.map +1 -0
- package/dist/src/webhooks/WebhookHandler.js +349 -0
- package/dist/src/webhooks/WebhookHandler.js.map +1 -0
- package/dist/src/webhooks/WebhookPayload.d.ts +238 -0
- package/dist/src/webhooks/WebhookPayload.d.ts.map +1 -0
- package/dist/src/webhooks/WebhookPayload.js +244 -0
- package/dist/src/webhooks/WebhookPayload.js.map +1 -0
- package/dist/src/webhooks/WebhookQueue.d.ts +227 -0
- package/dist/src/webhooks/WebhookQueue.d.ts.map +1 -0
- package/dist/src/webhooks/WebhookQueue.js +328 -0
- package/dist/src/webhooks/WebhookQueue.js.map +1 -0
- package/dist/src/webhooks/index.d.ts +12 -0
- package/dist/src/webhooks/index.d.ts.map +1 -0
- package/dist/src/webhooks/index.js +15 -0
- package/dist/src/webhooks/index.js.map +1 -0
- package/dist/tests/Analytics.integration.test.d.ts +7 -0
- package/dist/tests/Analytics.integration.test.d.ts.map +1 -0
- package/dist/tests/Analytics.integration.test.js +367 -0
- package/dist/tests/Analytics.integration.test.js.map +1 -0
- package/dist/tests/AnalyticsRepository.test.d.ts +8 -0
- package/dist/tests/AnalyticsRepository.test.d.ts.map +1 -0
- package/dist/tests/AnalyticsRepository.test.js +399 -0
- package/dist/tests/AnalyticsRepository.test.js.map +1 -0
- package/dist/tests/AnalyticsStorage.test.d.ts +8 -0
- package/dist/tests/AnalyticsStorage.test.d.ts.map +1 -0
- package/dist/tests/AnalyticsStorage.test.js +271 -0
- package/dist/tests/AnalyticsStorage.test.js.map +1 -0
- package/dist/tests/AuditLogger.test.d.ts +8 -0
- package/dist/tests/AuditLogger.test.d.ts.map +1 -0
- package/dist/tests/AuditLogger.test.js +699 -0
- package/dist/tests/AuditLogger.test.js.map +1 -0
- package/dist/tests/BenchmarkRunner.test.d.ts +11 -0
- package/dist/tests/BenchmarkRunner.test.d.ts.map +1 -0
- package/dist/tests/BenchmarkRunner.test.js +641 -0
- package/dist/tests/BenchmarkRunner.test.js.map +1 -0
- package/dist/tests/CacheRepository.test.d.ts +5 -0
- package/dist/tests/CacheRepository.test.d.ts.map +1 -0
- package/dist/tests/CacheRepository.test.js +184 -0
- package/dist/tests/CacheRepository.test.js.map +1 -0
- package/dist/tests/CacheSecurity.test.d.ts +8 -0
- package/dist/tests/CacheSecurity.test.d.ts.map +1 -0
- package/dist/tests/CacheSecurity.test.js +273 -0
- package/dist/tests/CacheSecurity.test.js.map +1 -0
- package/dist/tests/CodebaseAnalyzer.test.d.ts +2 -0
- package/dist/tests/CodebaseAnalyzer.test.d.ts.map +1 -0
- package/dist/tests/CodebaseAnalyzer.test.js +347 -0
- package/dist/tests/CodebaseAnalyzer.test.js.map +1 -0
- package/dist/tests/DailyIndexPipeline.test.d.ts +7 -0
- package/dist/tests/DailyIndexPipeline.test.d.ts.map +1 -0
- package/dist/tests/DailyIndexPipeline.test.js +539 -0
- package/dist/tests/DailyIndexPipeline.test.js.map +1 -0
- package/dist/tests/EmbeddingService.test.d.ts +2 -0
- package/dist/tests/EmbeddingService.test.d.ts.map +1 -0
- package/dist/tests/EmbeddingService.test.js +252 -0
- package/dist/tests/EmbeddingService.test.js.map +1 -0
- package/dist/tests/ExperimentService.test.d.ts +7 -0
- package/dist/tests/ExperimentService.test.d.ts.map +1 -0
- package/dist/tests/ExperimentService.test.js +293 -0
- package/dist/tests/ExperimentService.test.js.map +1 -0
- package/dist/tests/GitHubIndexer.test.d.ts +10 -0
- package/dist/tests/GitHubIndexer.test.d.ts.map +1 -0
- package/dist/tests/GitHubIndexer.test.js +524 -0
- package/dist/tests/GitHubIndexer.test.js.map +1 -0
- package/dist/tests/GitHubSourceAdapter.test.d.ts +5 -0
- package/dist/tests/GitHubSourceAdapter.test.d.ts.map +1 -0
- package/dist/tests/GitHubSourceAdapter.test.js +385 -0
- package/dist/tests/GitHubSourceAdapter.test.js.map +1 -0
- package/dist/tests/MemoryProfiler.test.d.ts +12 -0
- package/dist/tests/MemoryProfiler.test.d.ts.map +1 -0
- package/dist/tests/MemoryProfiler.test.js +402 -0
- package/dist/tests/MemoryProfiler.test.js.map +1 -0
- package/dist/tests/OverlapDetector.test.d.ts +2 -0
- package/dist/tests/OverlapDetector.test.d.ts.map +1 -0
- package/dist/tests/OverlapDetector.test.js +340 -0
- package/dist/tests/OverlapDetector.test.js.map +1 -0
- package/dist/tests/QualityScorer.test.d.ts +7 -0
- package/dist/tests/QualityScorer.test.d.ts.map +1 -0
- package/dist/tests/QualityScorer.test.js +340 -0
- package/dist/tests/QualityScorer.test.js.map +1 -0
- package/dist/tests/QuarantineRepository.test.d.ts +7 -0
- package/dist/tests/QuarantineRepository.test.d.ts.map +1 -0
- package/dist/tests/QuarantineRepository.test.js +582 -0
- package/dist/tests/QuarantineRepository.test.js.map +1 -0
- package/dist/tests/ROIDashboardService.test.d.ts +7 -0
- package/dist/tests/ROIDashboardService.test.d.ts.map +1 -0
- package/dist/tests/ROIDashboardService.test.js +324 -0
- package/dist/tests/ROIDashboardService.test.js.map +1 -0
- package/dist/tests/RateLimiter.test.d.ts +7 -0
- package/dist/tests/RateLimiter.test.d.ts.map +1 -0
- package/dist/tests/RateLimiter.test.js +1017 -0
- package/dist/tests/RateLimiter.test.js.map +1 -0
- package/dist/tests/RawUrlSourceAdapter.security.test.d.ts +7 -0
- package/dist/tests/RawUrlSourceAdapter.security.test.d.ts.map +1 -0
- package/dist/tests/RawUrlSourceAdapter.security.test.js +455 -0
- package/dist/tests/RawUrlSourceAdapter.security.test.js.map +1 -0
- package/dist/tests/ScraperAdapters.test.d.ts +7 -0
- package/dist/tests/ScraperAdapters.test.d.ts.map +1 -0
- package/dist/tests/ScraperAdapters.test.js +748 -0
- package/dist/tests/ScraperAdapters.test.js.map +1 -0
- package/dist/tests/SearchQuality.test.d.ts +8 -0
- package/dist/tests/SearchQuality.test.d.ts.map +1 -0
- package/dist/tests/SearchQuality.test.js +397 -0
- package/dist/tests/SearchQuality.test.js.map +1 -0
- package/dist/tests/SearchService.test.d.ts +5 -0
- package/dist/tests/SearchService.test.d.ts.map +1 -0
- package/dist/tests/SearchService.test.js +218 -0
- package/dist/tests/SearchService.test.js.map +1 -0
- package/dist/tests/SecurityScanner.test.d.ts +6 -0
- package/dist/tests/SecurityScanner.test.d.ts.map +1 -0
- package/dist/tests/SecurityScanner.test.js +449 -0
- package/dist/tests/SecurityScanner.test.js.map +1 -0
- package/dist/tests/SessionHealthMonitor.test.d.ts +5 -0
- package/dist/tests/SessionHealthMonitor.test.d.ts.map +1 -0
- package/dist/tests/SessionHealthMonitor.test.js +449 -0
- package/dist/tests/SessionHealthMonitor.test.js.map +1 -0
- package/dist/tests/SessionManager.security.test.d.ts +10 -0
- package/dist/tests/SessionManager.security.test.d.ts.map +1 -0
- package/dist/tests/SessionManager.security.test.js +395 -0
- package/dist/tests/SessionManager.security.test.js.map +1 -0
- package/dist/tests/SessionManager.test.d.ts +8 -0
- package/dist/tests/SessionManager.test.d.ts.map +1 -0
- package/dist/tests/SessionManager.test.js +446 -0
- package/dist/tests/SessionManager.test.js.map +1 -0
- package/dist/tests/SkillMatcher.test.d.ts +2 -0
- package/dist/tests/SkillMatcher.test.d.ts.map +1 -0
- package/dist/tests/SkillMatcher.test.js +253 -0
- package/dist/tests/SkillMatcher.test.js.map +1 -0
- package/dist/tests/SkillRepository.test.d.ts +5 -0
- package/dist/tests/SkillRepository.test.d.ts.map +1 -0
- package/dist/tests/SkillRepository.test.js +237 -0
- package/dist/tests/SkillRepository.test.js.map +1 -0
- package/dist/tests/SwarmIndexer.test.d.ts +11 -0
- package/dist/tests/SwarmIndexer.test.d.ts.map +1 -0
- package/dist/tests/SwarmIndexer.test.js +374 -0
- package/dist/tests/SwarmIndexer.test.js.map +1 -0
- package/dist/tests/TieredCache.test.d.ts +7 -0
- package/dist/tests/TieredCache.test.d.ts.map +1 -0
- package/dist/tests/TieredCache.test.js +529 -0
- package/dist/tests/TieredCache.test.js.map +1 -0
- package/dist/tests/UsageAnalyticsService.test.d.ts +7 -0
- package/dist/tests/UsageAnalyticsService.test.d.ts.map +1 -0
- package/dist/tests/UsageAnalyticsService.test.js +238 -0
- package/dist/tests/UsageAnalyticsService.test.js.map +1 -0
- package/dist/tests/UsageTracker.test.d.ts +7 -0
- package/dist/tests/UsageTracker.test.d.ts.map +1 -0
- package/dist/tests/UsageTracker.test.js +196 -0
- package/dist/tests/UsageTracker.test.js.map +1 -0
- package/dist/tests/WebhookHandler.test.d.ts +10 -0
- package/dist/tests/WebhookHandler.test.d.ts.map +1 -0
- package/dist/tests/WebhookHandler.test.js +592 -0
- package/dist/tests/WebhookHandler.test.js.map +1 -0
- package/dist/tests/analytics/metrics-aggregator.test.d.ts +11 -0
- package/dist/tests/analytics/metrics-aggregator.test.d.ts.map +1 -0
- package/dist/tests/analytics/metrics-aggregator.test.js +273 -0
- package/dist/tests/analytics/metrics-aggregator.test.js.map +1 -0
- package/dist/tests/analytics/metrics-exporter.test.d.ts +11 -0
- package/dist/tests/analytics/metrics-exporter.test.d.ts.map +1 -0
- package/dist/tests/analytics/metrics-exporter.test.js +371 -0
- package/dist/tests/analytics/metrics-exporter.test.js.map +1 -0
- package/dist/tests/analytics/usage-tracker.test.d.ts +10 -0
- package/dist/tests/analytics/usage-tracker.test.d.ts.map +1 -0
- package/dist/tests/analytics/usage-tracker.test.js +151 -0
- package/dist/tests/analytics/usage-tracker.test.js.map +1 -0
- package/dist/tests/anonymizer.test.d.ts +8 -0
- package/dist/tests/anonymizer.test.d.ts.map +1 -0
- package/dist/tests/anonymizer.test.js +153 -0
- package/dist/tests/anonymizer.test.js.map +1 -0
- package/dist/tests/cache.test.d.ts +6 -0
- package/dist/tests/cache.test.d.ts.map +1 -0
- package/dist/tests/cache.test.js +170 -0
- package/dist/tests/cache.test.js.map +1 -0
- package/dist/tests/e2e/security/security.e2e.test.d.ts +8 -0
- package/dist/tests/e2e/security/security.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/security/security.e2e.test.js +448 -0
- package/dist/tests/e2e/security/security.e2e.test.js.map +1 -0
- package/dist/tests/edge-cases/EdgeCases.test.d.ts +13 -0
- package/dist/tests/edge-cases/EdgeCases.test.d.ts.map +1 -0
- package/dist/tests/edge-cases/EdgeCases.test.js +844 -0
- package/dist/tests/edge-cases/EdgeCases.test.js.map +1 -0
- package/dist/tests/import-github-skills.test.d.ts +8 -0
- package/dist/tests/import-github-skills.test.d.ts.map +1 -0
- package/dist/tests/import-github-skills.test.js +390 -0
- package/dist/tests/import-github-skills.test.js.map +1 -0
- package/dist/tests/logger.test.d.ts +2 -0
- package/dist/tests/logger.test.d.ts.map +1 -0
- package/dist/tests/logger.test.js +417 -0
- package/dist/tests/logger.test.js.map +1 -0
- package/dist/tests/performance/LargeScalePerformance.test.d.ts +14 -0
- package/dist/tests/performance/LargeScalePerformance.test.d.ts.map +1 -0
- package/dist/tests/performance/LargeScalePerformance.test.js +558 -0
- package/dist/tests/performance/LargeScalePerformance.test.js.map +1 -0
- package/dist/tests/retry.test.d.ts +7 -0
- package/dist/tests/retry.test.d.ts.map +1 -0
- package/dist/tests/retry.test.js +302 -0
- package/dist/tests/retry.test.js.map +1 -0
- package/dist/tests/sanitization.test.d.ts +8 -0
- package/dist/tests/sanitization.test.d.ts.map +1 -0
- package/dist/tests/sanitization.test.js +413 -0
- package/dist/tests/sanitization.test.js.map +1 -0
- package/dist/tests/schema.test.d.ts +5 -0
- package/dist/tests/schema.test.d.ts.map +1 -0
- package/dist/tests/schema.test.js +167 -0
- package/dist/tests/schema.test.js.map +1 -0
- package/dist/tests/scripts/import-to-database.test.d.ts +11 -0
- package/dist/tests/scripts/import-to-database.test.d.ts.map +1 -0
- package/dist/tests/scripts/import-to-database.test.js +325 -0
- package/dist/tests/scripts/import-to-database.test.js.map +1 -0
- package/dist/tests/security/ContinuousSecurity.test.d.ts +6 -0
- package/dist/tests/security/ContinuousSecurity.test.d.ts.map +1 -0
- package/dist/tests/security/ContinuousSecurity.test.js +595 -0
- package/dist/tests/security/ContinuousSecurity.test.js.map +1 -0
- package/dist/tests/security/ReDoS.test.d.ts +8 -0
- package/dist/tests/security/ReDoS.test.d.ts.map +1 -0
- package/dist/tests/security/ReDoS.test.js +213 -0
- package/dist/tests/security/ReDoS.test.js.map +1 -0
- package/dist/tests/security.test.d.ts +5 -0
- package/dist/tests/security.test.d.ts.map +1 -0
- package/dist/tests/security.test.js +134 -0
- package/dist/tests/security.test.js.map +1 -0
- package/dist/tests/shared.test.d.ts +7 -0
- package/dist/tests/shared.test.d.ts.map +1 -0
- package/dist/tests/shared.test.js +480 -0
- package/dist/tests/shared.test.js.map +1 -0
- package/dist/tests/sources.test.d.ts +5 -0
- package/dist/tests/sources.test.d.ts.map +1 -0
- package/dist/tests/sources.test.js +369 -0
- package/dist/tests/sources.test.js.map +1 -0
- package/dist/tests/stats.test.d.ts +11 -0
- package/dist/tests/stats.test.d.ts.map +1 -0
- package/dist/tests/stats.test.js +124 -0
- package/dist/tests/stats.test.js.map +1 -0
- package/dist/tests/telemetry.test.d.ts +11 -0
- package/dist/tests/telemetry.test.d.ts.map +1 -0
- package/dist/tests/telemetry.test.js +424 -0
- package/dist/tests/telemetry.test.js.map +1 -0
- package/dist/tests/test-utils.d.ts +74 -0
- package/dist/tests/test-utils.d.ts.map +1 -0
- package/dist/tests/test-utils.js +98 -0
- package/dist/tests/test-utils.js.map +1 -0
- package/dist/tests/validate-skills.test.d.ts +5 -0
- package/dist/tests/validate-skills.test.d.ts.map +1 -0
- package/dist/tests/validate-skills.test.js +649 -0
- package/dist/tests/validate-skills.test.js.map +1 -0
- package/dist/tests/validation.test.d.ts +7 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +495 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/dist/tests/webhooks/WebhookHandler.idempotency.test.d.ts +8 -0
- package/dist/tests/webhooks/WebhookHandler.idempotency.test.d.ts.map +1 -0
- package/dist/tests/webhooks/WebhookHandler.idempotency.test.js +190 -0
- package/dist/tests/webhooks/WebhookHandler.idempotency.test.js.map +1 -0
- package/dist/tests/webhooks/WebhookPayload.security.test.d.ts +8 -0
- package/dist/tests/webhooks/WebhookPayload.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/WebhookPayload.security.test.js +204 -0
- package/dist/tests/webhooks/WebhookPayload.security.test.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-915: Metrics Aggregator
|
|
3
|
+
*
|
|
4
|
+
* Aggregates skill usage events into actionable metrics for value measurement.
|
|
5
|
+
* Provides:
|
|
6
|
+
* - Per-skill metrics aggregation
|
|
7
|
+
* - Global metrics across all skills
|
|
8
|
+
* - Retention rate calculation
|
|
9
|
+
* - Time-period filtering
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Aggregates skill usage metrics from the database
|
|
13
|
+
*/
|
|
14
|
+
export class MetricsAggregator {
|
|
15
|
+
db;
|
|
16
|
+
/**
|
|
17
|
+
* Create a metrics aggregator
|
|
18
|
+
*
|
|
19
|
+
* @param db - SQLite database instance
|
|
20
|
+
*/
|
|
21
|
+
constructor(db) {
|
|
22
|
+
this.db = db;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get metrics for a specific skill
|
|
26
|
+
*
|
|
27
|
+
* @param skillId - The skill identifier
|
|
28
|
+
* @param period - Optional time period filter
|
|
29
|
+
* @returns Aggregated metrics for the skill
|
|
30
|
+
*/
|
|
31
|
+
getSkillMetrics(skillId, period) {
|
|
32
|
+
const whereClause = period
|
|
33
|
+
? 'WHERE skill_id = ? AND timestamp >= ? AND timestamp <= ?'
|
|
34
|
+
: 'WHERE skill_id = ?';
|
|
35
|
+
const params = period ? [skillId, period.start, period.end] : [skillId];
|
|
36
|
+
const stats = this.db
|
|
37
|
+
.prepare(`
|
|
38
|
+
SELECT
|
|
39
|
+
COUNT(*) as total,
|
|
40
|
+
SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) as successes,
|
|
41
|
+
AVG(task_duration) as avg_duration,
|
|
42
|
+
COUNT(DISTINCT user_id) as unique_users,
|
|
43
|
+
MAX(timestamp) as last_used
|
|
44
|
+
FROM usage_events
|
|
45
|
+
${whereClause}
|
|
46
|
+
`)
|
|
47
|
+
.get(...params);
|
|
48
|
+
return {
|
|
49
|
+
skillId,
|
|
50
|
+
totalInvocations: stats?.total || 0,
|
|
51
|
+
successRate: stats && stats.total > 0 ? stats.successes / stats.total : 0,
|
|
52
|
+
avgTaskDuration: Math.round(stats?.avg_duration || 0),
|
|
53
|
+
uniqueUsers: stats?.unique_users || 0,
|
|
54
|
+
lastUsed: stats?.last_used || 0,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get metrics for all skills
|
|
59
|
+
*
|
|
60
|
+
* @param period - Optional time period filter
|
|
61
|
+
* @returns Array of metrics for each skill
|
|
62
|
+
*/
|
|
63
|
+
getAllSkillMetrics(period) {
|
|
64
|
+
const whereClause = period ? 'WHERE timestamp >= ? AND timestamp <= ?' : '';
|
|
65
|
+
const params = period ? [period.start, period.end] : [];
|
|
66
|
+
const skillIds = this.db
|
|
67
|
+
.prepare(`SELECT DISTINCT skill_id FROM usage_events ${whereClause}`)
|
|
68
|
+
.all(...params);
|
|
69
|
+
return skillIds.map(({ skill_id }) => this.getSkillMetrics(skill_id, period));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get global metrics across all skills
|
|
73
|
+
*
|
|
74
|
+
* @param period - Optional time period filter
|
|
75
|
+
* @returns Aggregated metrics for all skills
|
|
76
|
+
*/
|
|
77
|
+
getGlobalMetrics(period) {
|
|
78
|
+
const whereClause = period ? 'WHERE timestamp >= ? AND timestamp <= ?' : '';
|
|
79
|
+
const params = period ? [period.start, period.end] : [];
|
|
80
|
+
const stats = this.db
|
|
81
|
+
.prepare(`
|
|
82
|
+
SELECT
|
|
83
|
+
COUNT(*) as total,
|
|
84
|
+
SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) as successes,
|
|
85
|
+
AVG(task_duration) as avg_duration,
|
|
86
|
+
COUNT(DISTINCT user_id) as unique_users
|
|
87
|
+
FROM usage_events
|
|
88
|
+
${whereClause}
|
|
89
|
+
`)
|
|
90
|
+
.get(...params);
|
|
91
|
+
const topSkills = this.db
|
|
92
|
+
.prepare(`
|
|
93
|
+
SELECT skill_id, COUNT(*) as invocations
|
|
94
|
+
FROM usage_events
|
|
95
|
+
${whereClause}
|
|
96
|
+
GROUP BY skill_id
|
|
97
|
+
ORDER BY invocations DESC
|
|
98
|
+
LIMIT 10
|
|
99
|
+
`)
|
|
100
|
+
.all(...params);
|
|
101
|
+
return {
|
|
102
|
+
totalInvocations: stats?.total || 0,
|
|
103
|
+
uniqueUsers: stats?.unique_users || 0,
|
|
104
|
+
overallSuccessRate: stats && stats.total > 0 ? stats.successes / stats.total : 0,
|
|
105
|
+
avgTaskDuration: Math.round(stats?.avg_duration || 0),
|
|
106
|
+
topSkills: topSkills.map((s) => ({ skillId: s.skill_id, invocations: s.invocations })),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Calculate retention rate (users who used skill again within N days)
|
|
111
|
+
*
|
|
112
|
+
* @param skillId - The skill identifier
|
|
113
|
+
* @param days - Retention window in days (default: 7)
|
|
114
|
+
* @returns Retention rate (0-1)
|
|
115
|
+
*/
|
|
116
|
+
getRetentionRate(skillId, days = 7) {
|
|
117
|
+
const cutoff = Date.now() - days * 24 * 60 * 60 * 1000;
|
|
118
|
+
// Get users who used the skill before cutoff
|
|
119
|
+
const earlyUsers = this.db
|
|
120
|
+
.prepare(`
|
|
121
|
+
SELECT DISTINCT user_id FROM usage_events
|
|
122
|
+
WHERE skill_id = ? AND timestamp < ?
|
|
123
|
+
`)
|
|
124
|
+
.all(skillId, cutoff);
|
|
125
|
+
if (earlyUsers.length === 0)
|
|
126
|
+
return 0;
|
|
127
|
+
// Build parameterized query for returned users
|
|
128
|
+
const placeholders = earlyUsers.map(() => '?').join(',');
|
|
129
|
+
const userIds = earlyUsers.map((u) => u.user_id);
|
|
130
|
+
// Count how many returned after cutoff
|
|
131
|
+
const returnedUsers = this.db
|
|
132
|
+
.prepare(`
|
|
133
|
+
SELECT COUNT(DISTINCT user_id) as count FROM usage_events
|
|
134
|
+
WHERE skill_id = ? AND timestamp >= ? AND user_id IN (${placeholders})
|
|
135
|
+
`)
|
|
136
|
+
.get(skillId, cutoff, ...userIds);
|
|
137
|
+
return returnedUsers.count / earlyUsers.length;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get skills with usage in the specified period
|
|
141
|
+
*
|
|
142
|
+
* @param period - Time period filter
|
|
143
|
+
* @returns Array of skill IDs with usage
|
|
144
|
+
*/
|
|
145
|
+
getActiveSkills(period) {
|
|
146
|
+
const skillIds = this.db
|
|
147
|
+
.prepare(`
|
|
148
|
+
SELECT DISTINCT skill_id FROM usage_events
|
|
149
|
+
WHERE timestamp >= ? AND timestamp <= ?
|
|
150
|
+
ORDER BY skill_id
|
|
151
|
+
`)
|
|
152
|
+
.all(period.start, period.end);
|
|
153
|
+
return skillIds.map((row) => row.skill_id);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get the date range of available data
|
|
157
|
+
*
|
|
158
|
+
* @returns Object with min and max timestamps, or null if no data
|
|
159
|
+
*/
|
|
160
|
+
getDataRange() {
|
|
161
|
+
const result = this.db
|
|
162
|
+
.prepare(`
|
|
163
|
+
SELECT MIN(timestamp) as min_ts, MAX(timestamp) as max_ts
|
|
164
|
+
FROM usage_events
|
|
165
|
+
`)
|
|
166
|
+
.get();
|
|
167
|
+
if (result.min_ts === null || result.max_ts === null) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
minTimestamp: result.min_ts,
|
|
172
|
+
maxTimestamp: result.max_ts,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=metrics-aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-aggregator.js","sourceRoot":"","sources":["../../../src/analytics/metrics-aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-915: Metrics Exporter
|
|
3
|
+
*
|
|
4
|
+
* Exports aggregated metrics to various formats for analysis and reporting.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - JSON export with full metrics data
|
|
7
|
+
* - CSV export for spreadsheet analysis
|
|
8
|
+
* - Weekly/daily/custom period exports
|
|
9
|
+
* - Retention metrics (optional)
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Validates that a path does not escape the allowed base directory.
|
|
13
|
+
* Prevents path traversal attacks using sequences like '../'.
|
|
14
|
+
*
|
|
15
|
+
* @param inputPath - The path to validate (can be relative or absolute)
|
|
16
|
+
* @param baseDir - The allowed base directory
|
|
17
|
+
* @returns The resolved, sanitized absolute path
|
|
18
|
+
* @throws Error if the path attempts to escape the base directory
|
|
19
|
+
*/
|
|
20
|
+
export declare function validatePath(inputPath: string, baseDir: string): string;
|
|
21
|
+
import type { MetricsAggregator, GlobalMetrics, AggregationPeriod } from './metrics-aggregator.js';
|
|
22
|
+
import type { SkillMetrics } from './types.js';
|
|
23
|
+
/**
|
|
24
|
+
* Exported metrics structure
|
|
25
|
+
*/
|
|
26
|
+
export interface MetricsExport {
|
|
27
|
+
/** ISO timestamp when export was generated */
|
|
28
|
+
exportedAt: string;
|
|
29
|
+
/** Period information */
|
|
30
|
+
period: {
|
|
31
|
+
/** ISO timestamp of period start */
|
|
32
|
+
start: string;
|
|
33
|
+
/** ISO timestamp of period end */
|
|
34
|
+
end: string;
|
|
35
|
+
/** Human-readable label (e.g., "2026-W01") */
|
|
36
|
+
label: string;
|
|
37
|
+
};
|
|
38
|
+
/** Global metrics across all skills */
|
|
39
|
+
global: GlobalMetrics;
|
|
40
|
+
/** Per-skill metrics keyed by skill ID */
|
|
41
|
+
skills: Record<string, SkillMetrics>;
|
|
42
|
+
/** Optional retention data by skill */
|
|
43
|
+
retention?: Record<string, number>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Export configuration options
|
|
47
|
+
*/
|
|
48
|
+
export interface ExportOptions {
|
|
49
|
+
/** Directory for output files (defaults to ~/.skillsmith/exports) */
|
|
50
|
+
outputDir?: string;
|
|
51
|
+
/** Output format (defaults to 'json') */
|
|
52
|
+
format?: 'json' | 'csv';
|
|
53
|
+
/** Include retention rate calculations (defaults to false) */
|
|
54
|
+
includeRetention?: boolean;
|
|
55
|
+
/** Retention period in days for calculation (defaults to 7) */
|
|
56
|
+
retentionDays?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Exports metrics to files in various formats
|
|
60
|
+
*/
|
|
61
|
+
export declare class MetricsExporter {
|
|
62
|
+
private aggregator;
|
|
63
|
+
/**
|
|
64
|
+
* Create a metrics exporter
|
|
65
|
+
*
|
|
66
|
+
* @param aggregator - MetricsAggregator instance
|
|
67
|
+
*/
|
|
68
|
+
constructor(aggregator: MetricsAggregator);
|
|
69
|
+
/**
|
|
70
|
+
* Get ISO week label (e.g., "2026-W01")
|
|
71
|
+
*
|
|
72
|
+
* @param date - Date to get week label for
|
|
73
|
+
* @returns ISO week label string
|
|
74
|
+
*/
|
|
75
|
+
private getWeekLabel;
|
|
76
|
+
/**
|
|
77
|
+
* Get day label (e.g., "2026-01-01")
|
|
78
|
+
*
|
|
79
|
+
* @param date - Date to get label for
|
|
80
|
+
* @returns ISO date string (YYYY-MM-DD)
|
|
81
|
+
*/
|
|
82
|
+
private getDayLabel;
|
|
83
|
+
/**
|
|
84
|
+
* Export metrics for the last N days
|
|
85
|
+
*
|
|
86
|
+
* @param days - Number of days to include
|
|
87
|
+
* @param options - Export options
|
|
88
|
+
* @returns Exported metrics data
|
|
89
|
+
*/
|
|
90
|
+
exportLastNDays(days: number, options?: ExportOptions): MetricsExport;
|
|
91
|
+
/**
|
|
92
|
+
* Export metrics for a specific week
|
|
93
|
+
*
|
|
94
|
+
* @param date - Any date within the desired week (defaults to current week)
|
|
95
|
+
* @param options - Export options
|
|
96
|
+
* @returns Exported metrics data
|
|
97
|
+
*/
|
|
98
|
+
exportWeek(date?: Date, options?: ExportOptions): MetricsExport;
|
|
99
|
+
/**
|
|
100
|
+
* Export metrics for a specific day
|
|
101
|
+
*
|
|
102
|
+
* @param date - The date to export (defaults to today)
|
|
103
|
+
* @param options - Export options
|
|
104
|
+
* @returns Exported metrics data
|
|
105
|
+
*/
|
|
106
|
+
exportDay(date?: Date, options?: ExportOptions): MetricsExport;
|
|
107
|
+
/**
|
|
108
|
+
* Export metrics for a time period
|
|
109
|
+
*
|
|
110
|
+
* @param period - Aggregation period
|
|
111
|
+
* @param options - Export options
|
|
112
|
+
* @returns Exported metrics data
|
|
113
|
+
*/
|
|
114
|
+
export(period: AggregationPeriod, options?: ExportOptions): MetricsExport;
|
|
115
|
+
/**
|
|
116
|
+
* Save export data to a file
|
|
117
|
+
*
|
|
118
|
+
* @param data - Metrics export data
|
|
119
|
+
* @param options - Export options
|
|
120
|
+
* @param allowedBaseDir - Optional base directory to restrict path access (defaults to DEFAULT_EXPORT_DIR)
|
|
121
|
+
* @returns Path to the saved file
|
|
122
|
+
* @throws Error if outputDir attempts to escape the allowedBaseDir
|
|
123
|
+
*/
|
|
124
|
+
saveToFile(data: MetricsExport, options?: ExportOptions, allowedBaseDir?: string): string;
|
|
125
|
+
/**
|
|
126
|
+
* Convert export data to CSV format
|
|
127
|
+
*
|
|
128
|
+
* @param data - Metrics export data
|
|
129
|
+
* @returns CSV string
|
|
130
|
+
*/
|
|
131
|
+
private toCSV;
|
|
132
|
+
/**
|
|
133
|
+
* Escape a string for CSV output
|
|
134
|
+
*
|
|
135
|
+
* @param value - String to escape
|
|
136
|
+
* @returns Escaped string
|
|
137
|
+
*/
|
|
138
|
+
private escapeCSV;
|
|
139
|
+
/**
|
|
140
|
+
* Export to JSON string (for programmatic use)
|
|
141
|
+
*
|
|
142
|
+
* @param data - Metrics export data
|
|
143
|
+
* @param pretty - Whether to format with indentation (defaults to true)
|
|
144
|
+
* @returns JSON string
|
|
145
|
+
*/
|
|
146
|
+
toJSON(data: MetricsExport, pretty?: boolean): string;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=metrics-exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-exporter.d.ts","sourceRoot":"","sources":["../../../src/analytics/metrics-exporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAWvE;AACD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,yBAAyB;IACzB,MAAM,EAAE;QACN,oCAAoC;QACpC,KAAK,EAAE,MAAM,CAAA;QACb,kCAAkC;QAClC,GAAG,EAAE,MAAM,CAAA;QACX,8CAA8C;QAC9C,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,uCAAuC;IACvC,MAAM,EAAE,aAAa,CAAA;IACrB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACpC,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACvB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAOD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAmB;IAErC;;;;OAIG;gBACS,UAAU,EAAE,iBAAiB;IAIzC;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAQpB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,aAAa;IAQzE;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,GAAE,IAAiB,EAAE,OAAO,GAAE,aAAkB,GAAG,aAAa;IAe/E;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,GAAE,IAAiB,EAAE,OAAO,GAAE,aAAkB,GAAG,aAAa;IAU9E;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAE,aAAkB,GAAG,aAAa;IAmC7E;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,GAAE,aAAkB,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IAyB7F;;;;;OAKG;IACH,OAAO,CAAC,KAAK;IAsCb;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAOjB;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,GAAE,OAAc,GAAG,MAAM;CAG5D"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-915: Metrics Exporter
|
|
3
|
+
*
|
|
4
|
+
* Exports aggregated metrics to various formats for analysis and reporting.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - JSON export with full metrics data
|
|
7
|
+
* - CSV export for spreadsheet analysis
|
|
8
|
+
* - Weekly/daily/custom period exports
|
|
9
|
+
* - Retention metrics (optional)
|
|
10
|
+
*/
|
|
11
|
+
import { writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
12
|
+
import { join, resolve, isAbsolute } from 'path';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
/**
|
|
15
|
+
* Validates that a path does not escape the allowed base directory.
|
|
16
|
+
* Prevents path traversal attacks using sequences like '../'.
|
|
17
|
+
*
|
|
18
|
+
* @param inputPath - The path to validate (can be relative or absolute)
|
|
19
|
+
* @param baseDir - The allowed base directory
|
|
20
|
+
* @returns The resolved, sanitized absolute path
|
|
21
|
+
* @throws Error if the path attempts to escape the base directory
|
|
22
|
+
*/
|
|
23
|
+
export function validatePath(inputPath, baseDir) {
|
|
24
|
+
const resolvedBase = resolve(baseDir);
|
|
25
|
+
const resolvedPath = isAbsolute(inputPath) ? resolve(inputPath) : resolve(baseDir, inputPath);
|
|
26
|
+
// Ensure the resolved path starts with the base directory
|
|
27
|
+
// Add path separator to prevent partial matches (e.g., /base vs /base-other)
|
|
28
|
+
if (!resolvedPath.startsWith(resolvedBase + '/') && resolvedPath !== resolvedBase) {
|
|
29
|
+
throw new Error(`Path traversal attempt detected: ${inputPath}`);
|
|
30
|
+
}
|
|
31
|
+
return resolvedPath;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Default export directory
|
|
35
|
+
*/
|
|
36
|
+
const DEFAULT_EXPORT_DIR = join(homedir(), '.skillsmith', 'exports');
|
|
37
|
+
/**
|
|
38
|
+
* Exports metrics to files in various formats
|
|
39
|
+
*/
|
|
40
|
+
export class MetricsExporter {
|
|
41
|
+
aggregator;
|
|
42
|
+
/**
|
|
43
|
+
* Create a metrics exporter
|
|
44
|
+
*
|
|
45
|
+
* @param aggregator - MetricsAggregator instance
|
|
46
|
+
*/
|
|
47
|
+
constructor(aggregator) {
|
|
48
|
+
this.aggregator = aggregator;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get ISO week label (e.g., "2026-W01")
|
|
52
|
+
*
|
|
53
|
+
* @param date - Date to get week label for
|
|
54
|
+
* @returns ISO week label string
|
|
55
|
+
*/
|
|
56
|
+
getWeekLabel(date) {
|
|
57
|
+
const year = date.getFullYear();
|
|
58
|
+
const oneJan = new Date(year, 0, 1);
|
|
59
|
+
const days = Math.floor((date.getTime() - oneJan.getTime()) / (24 * 60 * 60 * 1000));
|
|
60
|
+
const weekNum = Math.ceil((days + oneJan.getDay() + 1) / 7);
|
|
61
|
+
return `${year}-W${weekNum.toString().padStart(2, '0')}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get day label (e.g., "2026-01-01")
|
|
65
|
+
*
|
|
66
|
+
* @param date - Date to get label for
|
|
67
|
+
* @returns ISO date string (YYYY-MM-DD)
|
|
68
|
+
*/
|
|
69
|
+
getDayLabel(date) {
|
|
70
|
+
return date.toISOString().split('T')[0];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Export metrics for the last N days
|
|
74
|
+
*
|
|
75
|
+
* @param days - Number of days to include
|
|
76
|
+
* @param options - Export options
|
|
77
|
+
* @returns Exported metrics data
|
|
78
|
+
*/
|
|
79
|
+
exportLastNDays(days, options = {}) {
|
|
80
|
+
const end = Date.now();
|
|
81
|
+
const start = end - days * 24 * 60 * 60 * 1000;
|
|
82
|
+
const period = { start, end };
|
|
83
|
+
return this.export(period, options);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Export metrics for a specific week
|
|
87
|
+
*
|
|
88
|
+
* @param date - Any date within the desired week (defaults to current week)
|
|
89
|
+
* @param options - Export options
|
|
90
|
+
* @returns Exported metrics data
|
|
91
|
+
*/
|
|
92
|
+
exportWeek(date = new Date(), options = {}) {
|
|
93
|
+
// Get start of week (Monday)
|
|
94
|
+
const d = new Date(date);
|
|
95
|
+
const day = d.getDay();
|
|
96
|
+
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
|
|
97
|
+
const start = new Date(d.setDate(diff));
|
|
98
|
+
start.setHours(0, 0, 0, 0);
|
|
99
|
+
const end = new Date(start);
|
|
100
|
+
end.setDate(end.getDate() + 7);
|
|
101
|
+
const period = { start: start.getTime(), end: end.getTime() };
|
|
102
|
+
return this.export(period, options);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Export metrics for a specific day
|
|
106
|
+
*
|
|
107
|
+
* @param date - The date to export (defaults to today)
|
|
108
|
+
* @param options - Export options
|
|
109
|
+
* @returns Exported metrics data
|
|
110
|
+
*/
|
|
111
|
+
exportDay(date = new Date(), options = {}) {
|
|
112
|
+
const d = new Date(date);
|
|
113
|
+
d.setHours(0, 0, 0, 0);
|
|
114
|
+
const start = d.getTime();
|
|
115
|
+
const end = start + 24 * 60 * 60 * 1000;
|
|
116
|
+
const period = { start, end };
|
|
117
|
+
return this.export(period, options);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Export metrics for a time period
|
|
121
|
+
*
|
|
122
|
+
* @param period - Aggregation period
|
|
123
|
+
* @param options - Export options
|
|
124
|
+
* @returns Exported metrics data
|
|
125
|
+
*/
|
|
126
|
+
export(period, options = {}) {
|
|
127
|
+
const global = this.aggregator.getGlobalMetrics(period);
|
|
128
|
+
const skillMetrics = this.aggregator.getAllSkillMetrics(period);
|
|
129
|
+
const skills = {};
|
|
130
|
+
for (const metric of skillMetrics) {
|
|
131
|
+
skills[metric.skillId] = metric;
|
|
132
|
+
}
|
|
133
|
+
const exportData = {
|
|
134
|
+
exportedAt: new Date().toISOString(),
|
|
135
|
+
period: {
|
|
136
|
+
start: new Date(period.start).toISOString(),
|
|
137
|
+
end: new Date(period.end).toISOString(),
|
|
138
|
+
label: this.getWeekLabel(new Date(period.start)),
|
|
139
|
+
},
|
|
140
|
+
global,
|
|
141
|
+
skills,
|
|
142
|
+
};
|
|
143
|
+
// Optionally include retention data
|
|
144
|
+
if (options.includeRetention) {
|
|
145
|
+
const retentionDays = options.retentionDays ?? 7;
|
|
146
|
+
const retention = {};
|
|
147
|
+
for (const skillId of Object.keys(skills)) {
|
|
148
|
+
retention[skillId] = this.aggregator.getRetentionRate(skillId, retentionDays);
|
|
149
|
+
}
|
|
150
|
+
exportData.retention = retention;
|
|
151
|
+
}
|
|
152
|
+
return exportData;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Save export data to a file
|
|
156
|
+
*
|
|
157
|
+
* @param data - Metrics export data
|
|
158
|
+
* @param options - Export options
|
|
159
|
+
* @param allowedBaseDir - Optional base directory to restrict path access (defaults to DEFAULT_EXPORT_DIR)
|
|
160
|
+
* @returns Path to the saved file
|
|
161
|
+
* @throws Error if outputDir attempts to escape the allowedBaseDir
|
|
162
|
+
*/
|
|
163
|
+
saveToFile(data, options = {}, allowedBaseDir) {
|
|
164
|
+
const outputDir = options.outputDir || DEFAULT_EXPORT_DIR;
|
|
165
|
+
const format = options.format || 'json';
|
|
166
|
+
// Validate output directory to prevent path traversal attacks
|
|
167
|
+
const baseDir = allowedBaseDir ?? DEFAULT_EXPORT_DIR;
|
|
168
|
+
const validatedOutputDir = validatePath(outputDir, baseDir);
|
|
169
|
+
if (!existsSync(validatedOutputDir)) {
|
|
170
|
+
mkdirSync(validatedOutputDir, { recursive: true });
|
|
171
|
+
}
|
|
172
|
+
const filename = `metrics-${data.period.label}.${format}`;
|
|
173
|
+
const filepath = join(validatedOutputDir, filename);
|
|
174
|
+
if (format === 'json') {
|
|
175
|
+
writeFileSync(filepath, JSON.stringify(data, null, 2));
|
|
176
|
+
}
|
|
177
|
+
else if (format === 'csv') {
|
|
178
|
+
const csv = this.toCSV(data);
|
|
179
|
+
writeFileSync(filepath, csv);
|
|
180
|
+
}
|
|
181
|
+
return filepath;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Convert export data to CSV format
|
|
185
|
+
*
|
|
186
|
+
* @param data - Metrics export data
|
|
187
|
+
* @returns CSV string
|
|
188
|
+
*/
|
|
189
|
+
toCSV(data) {
|
|
190
|
+
const lines = [];
|
|
191
|
+
// Header with optional retention column
|
|
192
|
+
const headers = [
|
|
193
|
+
'skill_id',
|
|
194
|
+
'total_invocations',
|
|
195
|
+
'success_rate',
|
|
196
|
+
'avg_duration_ms',
|
|
197
|
+
'unique_users',
|
|
198
|
+
'last_used',
|
|
199
|
+
];
|
|
200
|
+
if (data.retention) {
|
|
201
|
+
headers.push('retention_rate');
|
|
202
|
+
}
|
|
203
|
+
lines.push(headers.join(','));
|
|
204
|
+
// Data rows
|
|
205
|
+
for (const [skillId, metrics] of Object.entries(data.skills)) {
|
|
206
|
+
const row = [
|
|
207
|
+
this.escapeCSV(skillId),
|
|
208
|
+
metrics.totalInvocations.toString(),
|
|
209
|
+
metrics.successRate.toFixed(3),
|
|
210
|
+
metrics.avgTaskDuration.toString(),
|
|
211
|
+
metrics.uniqueUsers.toString(),
|
|
212
|
+
metrics.lastUsed > 0 ? new Date(metrics.lastUsed).toISOString() : '',
|
|
213
|
+
];
|
|
214
|
+
if (data.retention) {
|
|
215
|
+
row.push((data.retention[skillId] ?? 0).toFixed(3));
|
|
216
|
+
}
|
|
217
|
+
lines.push(row.join(','));
|
|
218
|
+
}
|
|
219
|
+
return lines.join('\n');
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Escape a string for CSV output
|
|
223
|
+
*
|
|
224
|
+
* @param value - String to escape
|
|
225
|
+
* @returns Escaped string
|
|
226
|
+
*/
|
|
227
|
+
escapeCSV(value) {
|
|
228
|
+
if (value.includes(',') || value.includes('"') || value.includes('\n')) {
|
|
229
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
230
|
+
}
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Export to JSON string (for programmatic use)
|
|
235
|
+
*
|
|
236
|
+
* @param data - Metrics export data
|
|
237
|
+
* @param pretty - Whether to format with indentation (defaults to true)
|
|
238
|
+
* @returns JSON string
|
|
239
|
+
*/
|
|
240
|
+
toJSON(data, pretty = true) {
|
|
241
|
+
return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=metrics-exporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-exporter.js","sourceRoot":"","sources":["../../../src/analytics/metrics-exporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Database Schema
|
|
3
|
+
*
|
|
4
|
+
* Implements Phase 4 Product Strategy analytics infrastructure:
|
|
5
|
+
* - Epic 3: Skill usage tracking with 30-day rolling window
|
|
6
|
+
* - Epic 4: A/B testing experiment management
|
|
7
|
+
* - Epic 4: ROI metrics and dashboard data
|
|
8
|
+
*
|
|
9
|
+
* SMI-XXX: Analytics infrastructure for product strategy
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Analytics schema SQL for skill usage, A/B testing, and ROI tracking
|
|
13
|
+
*/
|
|
14
|
+
export declare const ANALYTICS_SCHEMA = "\n-- Skill usage events for attribution and value tracking\nCREATE TABLE IF NOT EXISTS skill_usage_events (\n id TEXT PRIMARY KEY,\n skill_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n session_id TEXT NOT NULL,\n event_type TEXT NOT NULL CHECK(event_type IN ('activation', 'invocation', 'success', 'failure')),\n context TEXT, -- JSON metadata about the usage context\n value_score REAL, -- Estimated value contribution (0-1)\n timestamp TEXT NOT NULL DEFAULT (datetime('now')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for usage queries\nCREATE INDEX IF NOT EXISTS idx_usage_skill_id ON skill_usage_events(skill_id);\nCREATE INDEX IF NOT EXISTS idx_usage_user_id ON skill_usage_events(user_id);\nCREATE INDEX IF NOT EXISTS idx_usage_session_id ON skill_usage_events(session_id);\nCREATE INDEX IF NOT EXISTS idx_usage_timestamp ON skill_usage_events(timestamp);\nCREATE INDEX IF NOT EXISTS idx_usage_event_type ON skill_usage_events(event_type);\n\n-- A/B testing experiments\nCREATE TABLE IF NOT EXISTS experiments (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n description TEXT,\n hypothesis TEXT,\n status TEXT NOT NULL CHECK(status IN ('draft', 'active', 'paused', 'completed')) DEFAULT 'draft',\n variant_a TEXT NOT NULL, -- JSON config for control group\n variant_b TEXT NOT NULL, -- JSON config for treatment group\n start_date TEXT,\n end_date TEXT,\n target_sample_size INTEGER DEFAULT 100,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- User assignments to experiment variants\nCREATE TABLE IF NOT EXISTS experiment_assignments (\n id TEXT PRIMARY KEY,\n experiment_id TEXT NOT NULL REFERENCES experiments(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL,\n variant TEXT NOT NULL CHECK(variant IN ('control', 'treatment')),\n assigned_at TEXT NOT NULL DEFAULT (datetime('now')),\n UNIQUE(experiment_id, user_id)\n);\n\n-- Experiment outcome tracking\nCREATE TABLE IF NOT EXISTS experiment_outcomes (\n id TEXT PRIMARY KEY,\n experiment_id TEXT NOT NULL REFERENCES experiments(id) ON DELETE CASCADE,\n assignment_id TEXT NOT NULL REFERENCES experiment_assignments(id) ON DELETE CASCADE,\n outcome_type TEXT NOT NULL, -- e.g., 'activation', 'usage_count', 'value_score'\n outcome_value REAL NOT NULL,\n metadata TEXT, -- JSON additional data\n measured_at TEXT NOT NULL DEFAULT (datetime('now')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for experiment queries\nCREATE INDEX IF NOT EXISTS idx_assignments_experiment ON experiment_assignments(experiment_id);\nCREATE INDEX IF NOT EXISTS idx_assignments_user ON experiment_assignments(user_id);\nCREATE INDEX IF NOT EXISTS idx_outcomes_experiment ON experiment_outcomes(experiment_id);\nCREATE INDEX IF NOT EXISTS idx_outcomes_assignment ON experiment_outcomes(assignment_id);\n\n-- ROI metrics aggregation (materialized view equivalent)\nCREATE TABLE IF NOT EXISTS roi_metrics (\n id TEXT PRIMARY KEY,\n metric_type TEXT NOT NULL, -- 'daily', 'weekly', 'monthly', 'user', 'skill'\n entity_id TEXT, -- user_id or skill_id for entity-level metrics\n period_start TEXT NOT NULL,\n period_end TEXT NOT NULL,\n total_activations INTEGER DEFAULT 0,\n total_invocations INTEGER DEFAULT 0,\n total_successes INTEGER DEFAULT 0,\n total_failures INTEGER DEFAULT 0,\n avg_value_score REAL DEFAULT 0.0,\n estimated_time_saved REAL DEFAULT 0.0, -- in minutes\n estimated_value_usd REAL DEFAULT 0.0, -- rough ROI estimate\n metadata TEXT, -- JSON for additional metrics\n computed_at TEXT NOT NULL DEFAULT (datetime('now')),\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for ROI queries\nCREATE INDEX IF NOT EXISTS idx_roi_type ON roi_metrics(metric_type);\nCREATE INDEX IF NOT EXISTS idx_roi_entity ON roi_metrics(entity_id);\nCREATE INDEX IF NOT EXISTS idx_roi_period ON roi_metrics(period_start, period_end);\nCREATE INDEX IF NOT EXISTS idx_roi_computed ON roi_metrics(computed_at);\n\n-- Value attribution mappings\nCREATE TABLE IF NOT EXISTS value_attributions (\n id TEXT PRIMARY KEY,\n usage_event_id TEXT NOT NULL REFERENCES skill_usage_events(id) ON DELETE CASCADE,\n skill_id TEXT NOT NULL,\n attribution_type TEXT NOT NULL, -- 'inline', 'metadata', 'session'\n value_dimension TEXT NOT NULL, -- 'time_saved', 'quality_improved', 'error_prevented'\n value_amount REAL NOT NULL,\n confidence REAL NOT NULL CHECK(confidence >= 0 AND confidence <= 1),\n metadata TEXT, -- JSON additional context\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes for attribution queries\nCREATE INDEX IF NOT EXISTS idx_attributions_event ON value_attributions(usage_event_id);\nCREATE INDEX IF NOT EXISTS idx_attributions_skill ON value_attributions(skill_id);\nCREATE INDEX IF NOT EXISTS idx_attributions_type ON value_attributions(attribution_type);\n";
|
|
15
|
+
/**
|
|
16
|
+
* Apply analytics schema to a database
|
|
17
|
+
*/
|
|
18
|
+
import type { Database as DatabaseType } from 'better-sqlite3';
|
|
19
|
+
export declare function initializeAnalyticsSchema(db: DatabaseType): void;
|
|
20
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/analytics/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,o0JA2G5B,CAAA;AAED;;GAEG;AACH,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE9D,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAEhE"}
|