@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,748 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scraper Adapters Tests (SMI-591)
|
|
3
|
+
*
|
|
4
|
+
* Tests for RawUrlSourceAdapter, LocalFilesystemAdapter, and GitLabSourceAdapter
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
|
7
|
+
import { RawUrlSourceAdapter } from '../src/sources/RawUrlSourceAdapter.js';
|
|
8
|
+
import { LocalFilesystemAdapter } from '../src/sources/LocalFilesystemAdapter.js';
|
|
9
|
+
import { GitLabSourceAdapter } from '../src/sources/GitLabSourceAdapter.js';
|
|
10
|
+
import { promises as fs } from 'fs';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { tmpdir } from 'os';
|
|
13
|
+
// Mock fetch for network adapters
|
|
14
|
+
const mockFetch = vi.fn();
|
|
15
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
16
|
+
describe('RawUrlSourceAdapter (SMI-591)', () => {
|
|
17
|
+
let adapter;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
mockFetch.mockReset();
|
|
20
|
+
adapter = new RawUrlSourceAdapter({
|
|
21
|
+
id: 'test-raw-url',
|
|
22
|
+
name: 'Test Raw URL',
|
|
23
|
+
type: 'raw-url',
|
|
24
|
+
baseUrl: 'https://example.com',
|
|
25
|
+
enabled: true,
|
|
26
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
27
|
+
skillUrls: [
|
|
28
|
+
{
|
|
29
|
+
id: '1',
|
|
30
|
+
name: 'Test Skill 1',
|
|
31
|
+
url: 'https://example.com/skills/skill1.md',
|
|
32
|
+
description: 'First test skill',
|
|
33
|
+
tags: ['test', 'example'],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: '2',
|
|
37
|
+
name: 'Test Skill 2',
|
|
38
|
+
url: 'https://example.com/skills/skill2.md',
|
|
39
|
+
tags: ['test'],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('Initialization', () => {
|
|
45
|
+
it('should initialize with predefined skill URLs', async () => {
|
|
46
|
+
const urls = adapter.getSkillUrls();
|
|
47
|
+
expect(urls).toHaveLength(2);
|
|
48
|
+
expect(urls[0].name).toBe('Test Skill 1');
|
|
49
|
+
});
|
|
50
|
+
it('should have correct type', () => {
|
|
51
|
+
expect(adapter.type).toBe('raw-url');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('Health Check', () => {
|
|
55
|
+
it('should return healthy when base URL is reachable', async () => {
|
|
56
|
+
mockFetch.mockResolvedValueOnce({
|
|
57
|
+
ok: true,
|
|
58
|
+
status: 200,
|
|
59
|
+
headers: new Headers(),
|
|
60
|
+
});
|
|
61
|
+
const health = await adapter.checkHealth();
|
|
62
|
+
expect(health.healthy).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
it('should return unhealthy when base URL is unreachable', async () => {
|
|
65
|
+
mockFetch.mockRejectedValueOnce(new Error('Network error'));
|
|
66
|
+
const health = await adapter.checkHealth();
|
|
67
|
+
expect(health.healthy).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('Search', () => {
|
|
71
|
+
it('should return all skills when no filters', async () => {
|
|
72
|
+
const result = await adapter.search({});
|
|
73
|
+
expect(result.repositories).toHaveLength(2);
|
|
74
|
+
expect(result.totalCount).toBe(2);
|
|
75
|
+
});
|
|
76
|
+
it('should filter by query', async () => {
|
|
77
|
+
const result = await adapter.search({ query: 'First' });
|
|
78
|
+
expect(result.repositories).toHaveLength(1);
|
|
79
|
+
expect(result.repositories[0].name).toBe('Test Skill 1');
|
|
80
|
+
});
|
|
81
|
+
it('should filter by topics', async () => {
|
|
82
|
+
const result = await adapter.search({ topics: ['example'] });
|
|
83
|
+
expect(result.repositories).toHaveLength(1);
|
|
84
|
+
expect(result.repositories[0].name).toBe('Test Skill 1');
|
|
85
|
+
});
|
|
86
|
+
it('should apply limit', async () => {
|
|
87
|
+
const result = await adapter.search({ limit: 1 });
|
|
88
|
+
expect(result.repositories).toHaveLength(1);
|
|
89
|
+
expect(result.hasMore).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('Fetch Skill Content', () => {
|
|
93
|
+
it('should fetch skill content from URL', async () => {
|
|
94
|
+
mockFetch.mockResolvedValueOnce({
|
|
95
|
+
ok: true,
|
|
96
|
+
headers: new Headers(),
|
|
97
|
+
text: async () => '---\nname: Test\n---\n# Test Skill',
|
|
98
|
+
});
|
|
99
|
+
const content = await adapter.fetchSkillContent({
|
|
100
|
+
repo: '1',
|
|
101
|
+
path: 'https://example.com/skills/skill1.md',
|
|
102
|
+
});
|
|
103
|
+
expect(content.rawContent).toContain('# Test Skill');
|
|
104
|
+
expect(content.sha).toBeDefined();
|
|
105
|
+
});
|
|
106
|
+
it('should throw error when fetch fails', async () => {
|
|
107
|
+
mockFetch.mockResolvedValueOnce({
|
|
108
|
+
ok: false,
|
|
109
|
+
status: 404,
|
|
110
|
+
headers: new Headers(),
|
|
111
|
+
});
|
|
112
|
+
await expect(adapter.fetchSkillContent({
|
|
113
|
+
repo: 'unknown',
|
|
114
|
+
path: 'https://example.com/unknown.md',
|
|
115
|
+
})).rejects.toThrow('Failed to fetch skill content');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('Registry Loading (SMI-724)', () => {
|
|
119
|
+
it('should handle registry loading failure gracefully', async () => {
|
|
120
|
+
mockFetch.mockResolvedValueOnce({
|
|
121
|
+
ok: false,
|
|
122
|
+
status: 500,
|
|
123
|
+
headers: new Headers(),
|
|
124
|
+
});
|
|
125
|
+
const adapterWithRegistry = new RawUrlSourceAdapter({
|
|
126
|
+
id: 'test-registry-fail',
|
|
127
|
+
name: 'Test Registry Fail',
|
|
128
|
+
type: 'raw-url',
|
|
129
|
+
baseUrl: 'https://example.com',
|
|
130
|
+
enabled: true,
|
|
131
|
+
registryUrl: 'https://example.com/registry.json',
|
|
132
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
133
|
+
});
|
|
134
|
+
// Should not throw - registry load is optional
|
|
135
|
+
await expect(adapterWithRegistry.initialize()).resolves.not.toThrow();
|
|
136
|
+
// No skills from registry
|
|
137
|
+
expect(adapterWithRegistry.getSkillUrls()).toHaveLength(0);
|
|
138
|
+
});
|
|
139
|
+
it('should merge registry skills with predefined skills', async () => {
|
|
140
|
+
mockFetch.mockResolvedValueOnce({
|
|
141
|
+
ok: true,
|
|
142
|
+
headers: new Headers(),
|
|
143
|
+
json: async () => ({
|
|
144
|
+
skills: [
|
|
145
|
+
{
|
|
146
|
+
id: 'registry-1',
|
|
147
|
+
name: 'Registry Skill',
|
|
148
|
+
url: 'https://example.com/registry-skill.md',
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
}),
|
|
152
|
+
});
|
|
153
|
+
const adapterWithBoth = new RawUrlSourceAdapter({
|
|
154
|
+
id: 'test-merge',
|
|
155
|
+
name: 'Test Merge',
|
|
156
|
+
type: 'raw-url',
|
|
157
|
+
baseUrl: 'https://example.com',
|
|
158
|
+
enabled: true,
|
|
159
|
+
registryUrl: 'https://example.com/registry.json',
|
|
160
|
+
skillUrls: [
|
|
161
|
+
{
|
|
162
|
+
id: 'predefined-1',
|
|
163
|
+
name: 'Predefined Skill',
|
|
164
|
+
url: 'https://example.com/predefined.md',
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
168
|
+
});
|
|
169
|
+
await adapterWithBoth.initialize();
|
|
170
|
+
expect(adapterWithBoth.getSkillUrls()).toHaveLength(2);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe('Skill URL Management', () => {
|
|
174
|
+
it('should add skill URL', () => {
|
|
175
|
+
adapter.addSkillUrl({
|
|
176
|
+
id: '3',
|
|
177
|
+
name: 'New Skill',
|
|
178
|
+
url: 'https://example.com/new.md',
|
|
179
|
+
});
|
|
180
|
+
const urls = adapter.getSkillUrls();
|
|
181
|
+
expect(urls).toHaveLength(3);
|
|
182
|
+
});
|
|
183
|
+
it('should remove skill URL', () => {
|
|
184
|
+
const removed = adapter.removeSkillUrl('1');
|
|
185
|
+
expect(removed).toBe(true);
|
|
186
|
+
expect(adapter.getSkillUrls()).toHaveLength(1);
|
|
187
|
+
});
|
|
188
|
+
it('should return false when removing non-existent URL', () => {
|
|
189
|
+
const removed = adapter.removeSkillUrl('999');
|
|
190
|
+
expect(removed).toBe(false);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe('LocalFilesystemAdapter (SMI-591)', () => {
|
|
195
|
+
let adapter;
|
|
196
|
+
let testDir;
|
|
197
|
+
beforeEach(async () => {
|
|
198
|
+
// Create test directory structure
|
|
199
|
+
testDir = join(tmpdir(), `skillsmith-test-${Date.now()}`);
|
|
200
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
201
|
+
// Create test skill files
|
|
202
|
+
await fs.mkdir(join(testDir, 'skill-one'), { recursive: true });
|
|
203
|
+
await fs.writeFile(join(testDir, 'skill-one', 'SKILL.md'), '---\nname: Skill One\ndescription: First skill\n---\n# Skill One');
|
|
204
|
+
await fs.mkdir(join(testDir, 'skill-two'), { recursive: true });
|
|
205
|
+
await fs.writeFile(join(testDir, 'skill-two', 'SKILL.md'), '---\nname: Skill Two\n---\n# Skill Two');
|
|
206
|
+
// Create node_modules (should be excluded)
|
|
207
|
+
await fs.mkdir(join(testDir, 'node_modules', 'some-module'), { recursive: true });
|
|
208
|
+
await fs.writeFile(join(testDir, 'node_modules', 'some-module', 'SKILL.md'), '# Should be excluded');
|
|
209
|
+
adapter = new LocalFilesystemAdapter({
|
|
210
|
+
id: 'test-local',
|
|
211
|
+
name: 'Test Local',
|
|
212
|
+
type: 'local',
|
|
213
|
+
baseUrl: 'file://',
|
|
214
|
+
enabled: true,
|
|
215
|
+
rootDir: testDir,
|
|
216
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
217
|
+
});
|
|
218
|
+
await adapter.initialize();
|
|
219
|
+
});
|
|
220
|
+
afterEach(async () => {
|
|
221
|
+
// Clean up test directory
|
|
222
|
+
try {
|
|
223
|
+
await fs.rm(testDir, { recursive: true, force: true });
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Ignore cleanup errors
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
describe('Initialization', () => {
|
|
230
|
+
it('should discover skill files in root directory', () => {
|
|
231
|
+
expect(adapter.skillCount).toBe(2);
|
|
232
|
+
});
|
|
233
|
+
it('should exclude node_modules', () => {
|
|
234
|
+
expect(adapter.skillCount).toBe(2); // Only skill-one and skill-two
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
describe('Health Check', () => {
|
|
238
|
+
it('should return healthy when root directory exists', async () => {
|
|
239
|
+
const health = await adapter.checkHealth();
|
|
240
|
+
expect(health.healthy).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
it('should return unhealthy when root directory does not exist', async () => {
|
|
243
|
+
const badAdapter = new LocalFilesystemAdapter({
|
|
244
|
+
id: 'bad',
|
|
245
|
+
name: 'Bad',
|
|
246
|
+
type: 'local',
|
|
247
|
+
baseUrl: 'file://',
|
|
248
|
+
enabled: true,
|
|
249
|
+
rootDir: '/nonexistent/path',
|
|
250
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
251
|
+
});
|
|
252
|
+
const health = await badAdapter.checkHealth();
|
|
253
|
+
expect(health.healthy).toBe(false);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
describe('Search', () => {
|
|
257
|
+
it('should return all discovered skills', async () => {
|
|
258
|
+
const result = await adapter.search({});
|
|
259
|
+
expect(result.repositories).toHaveLength(2);
|
|
260
|
+
});
|
|
261
|
+
it('should filter by query', async () => {
|
|
262
|
+
const result = await adapter.search({ query: 'skill-one' });
|
|
263
|
+
expect(result.repositories).toHaveLength(1);
|
|
264
|
+
expect(result.repositories[0].name).toBe('Skill One');
|
|
265
|
+
});
|
|
266
|
+
it('should extract name from frontmatter', async () => {
|
|
267
|
+
const result = await adapter.search({});
|
|
268
|
+
const names = result.repositories.map((r) => r.name);
|
|
269
|
+
expect(names).toContain('Skill One');
|
|
270
|
+
expect(names).toContain('Skill Two');
|
|
271
|
+
});
|
|
272
|
+
it('should extract description from frontmatter', async () => {
|
|
273
|
+
const result = await adapter.search({});
|
|
274
|
+
const skillOne = result.repositories.find((r) => r.name === 'Skill One');
|
|
275
|
+
expect(skillOne?.description).toBe('First skill');
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
describe('Fetch Skill Content', () => {
|
|
279
|
+
it('should fetch skill content by path', async () => {
|
|
280
|
+
const content = await adapter.fetchSkillContent({
|
|
281
|
+
path: join(testDir, 'skill-one', 'SKILL.md'),
|
|
282
|
+
});
|
|
283
|
+
expect(content.rawContent).toContain('# Skill One');
|
|
284
|
+
expect(content.sha).toBeDefined();
|
|
285
|
+
});
|
|
286
|
+
it('should throw error for non-existent skill', async () => {
|
|
287
|
+
await expect(adapter.fetchSkillContent({
|
|
288
|
+
path: join(testDir, 'nonexistent', 'SKILL.md'),
|
|
289
|
+
})).rejects.toThrow('Failed to read skill file');
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
describe('Skill Exists', () => {
|
|
293
|
+
it('should return true for existing skill', async () => {
|
|
294
|
+
const exists = await adapter.skillExists({
|
|
295
|
+
path: join(testDir, 'skill-one', 'SKILL.md'),
|
|
296
|
+
});
|
|
297
|
+
expect(exists).toBe(true);
|
|
298
|
+
});
|
|
299
|
+
it('should return false for non-existent skill', async () => {
|
|
300
|
+
const exists = await adapter.skillExists({
|
|
301
|
+
path: join(testDir, 'nonexistent', 'SKILL.md'),
|
|
302
|
+
});
|
|
303
|
+
expect(exists).toBe(false);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
describe('Rescan', () => {
|
|
307
|
+
it('should discover newly added skills', async () => {
|
|
308
|
+
// Add a new skill
|
|
309
|
+
await fs.mkdir(join(testDir, 'skill-three'), { recursive: true });
|
|
310
|
+
await fs.writeFile(join(testDir, 'skill-three', 'SKILL.md'), '# Skill Three');
|
|
311
|
+
// Rescan
|
|
312
|
+
const count = await adapter.rescan();
|
|
313
|
+
expect(count).toBe(3);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
describe('Path Traversal Prevention (SMI-720)', () => {
|
|
317
|
+
it('should reject relative path traversal with ../', async () => {
|
|
318
|
+
await expect(adapter.fetchSkillContent({
|
|
319
|
+
path: '../../../etc/passwd',
|
|
320
|
+
})).rejects.toThrow('Path traversal detected');
|
|
321
|
+
});
|
|
322
|
+
it('should reject deeply nested path traversal', async () => {
|
|
323
|
+
await expect(adapter.fetchSkillContent({
|
|
324
|
+
path: 'skill-one/../../../../../../etc/shadow',
|
|
325
|
+
})).rejects.toThrow('Path traversal detected');
|
|
326
|
+
});
|
|
327
|
+
it('should reject absolute paths outside rootDir', async () => {
|
|
328
|
+
await expect(adapter.fetchSkillContent({
|
|
329
|
+
path: '/etc/passwd',
|
|
330
|
+
})).rejects.toThrow('Path traversal detected');
|
|
331
|
+
});
|
|
332
|
+
it('should reject path traversal via owner/repo', async () => {
|
|
333
|
+
await expect(adapter.getRepository({
|
|
334
|
+
owner: '..',
|
|
335
|
+
repo: '../../../etc',
|
|
336
|
+
})).rejects.toThrow('Path traversal detected');
|
|
337
|
+
});
|
|
338
|
+
it('should reject path traversal via repo only', async () => {
|
|
339
|
+
await expect(adapter.skillExists({
|
|
340
|
+
repo: '../../../etc/passwd',
|
|
341
|
+
})).rejects.toThrow('Path traversal detected');
|
|
342
|
+
});
|
|
343
|
+
it('should allow valid paths within rootDir', async () => {
|
|
344
|
+
const exists = await adapter.skillExists({
|
|
345
|
+
path: join(testDir, 'skill-one', 'SKILL.md'),
|
|
346
|
+
});
|
|
347
|
+
expect(exists).toBe(true);
|
|
348
|
+
});
|
|
349
|
+
it('should allow valid relative paths that stay within rootDir', async () => {
|
|
350
|
+
const content = await adapter.fetchSkillContent({
|
|
351
|
+
path: 'skill-one/SKILL.md',
|
|
352
|
+
});
|
|
353
|
+
expect(content.rawContent).toContain('# Skill One');
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe('Symlink Handling (SMI-724)', () => {
|
|
357
|
+
it('should skip symlinks by default', async () => {
|
|
358
|
+
// Create a symlink to external directory
|
|
359
|
+
const externalDir = join(tmpdir(), `external-${Date.now()}`);
|
|
360
|
+
await fs.mkdir(externalDir, { recursive: true });
|
|
361
|
+
await fs.writeFile(join(externalDir, 'SKILL.md'), '# External Skill');
|
|
362
|
+
try {
|
|
363
|
+
await fs.symlink(externalDir, join(testDir, 'symlink-skill'));
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// Skip test on platforms that don't support symlinks
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
// Create new adapter (symlinks disabled by default)
|
|
370
|
+
const newAdapter = new LocalFilesystemAdapter({
|
|
371
|
+
id: 'test-symlink',
|
|
372
|
+
name: 'Test Symlink',
|
|
373
|
+
type: 'local',
|
|
374
|
+
baseUrl: 'file://',
|
|
375
|
+
enabled: true,
|
|
376
|
+
rootDir: testDir,
|
|
377
|
+
followSymlinks: false,
|
|
378
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
379
|
+
});
|
|
380
|
+
await newAdapter.initialize();
|
|
381
|
+
// Should not include symlinked skill
|
|
382
|
+
expect(newAdapter.skillCount).toBe(2);
|
|
383
|
+
// Cleanup
|
|
384
|
+
await fs.rm(externalDir, { recursive: true, force: true });
|
|
385
|
+
});
|
|
386
|
+
it('should follow symlinks when enabled', async () => {
|
|
387
|
+
// Create a symlink to skill directory
|
|
388
|
+
const externalDir = join(tmpdir(), `external-follow-${Date.now()}`);
|
|
389
|
+
await fs.mkdir(externalDir, { recursive: true });
|
|
390
|
+
await fs.writeFile(join(externalDir, 'SKILL.md'), '# Symlinked Skill');
|
|
391
|
+
try {
|
|
392
|
+
await fs.symlink(externalDir, join(testDir, 'symlink-follow'));
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
// Skip test on platforms that don't support symlinks
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const followAdapter = new LocalFilesystemAdapter({
|
|
399
|
+
id: 'test-follow-symlink',
|
|
400
|
+
name: 'Test Follow Symlink',
|
|
401
|
+
type: 'local',
|
|
402
|
+
baseUrl: 'file://',
|
|
403
|
+
enabled: true,
|
|
404
|
+
rootDir: testDir,
|
|
405
|
+
followSymlinks: true,
|
|
406
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
407
|
+
});
|
|
408
|
+
await followAdapter.initialize();
|
|
409
|
+
// Should include symlinked skill
|
|
410
|
+
expect(followAdapter.skillCount).toBe(3);
|
|
411
|
+
// Cleanup
|
|
412
|
+
await fs.rm(externalDir, { recursive: true, force: true });
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
describe('Deep Directory Structures (SMI-724)', () => {
|
|
416
|
+
it('should respect maxDepth limit', async () => {
|
|
417
|
+
// Create deeply nested skill
|
|
418
|
+
const deepPath = join(testDir, 'level1', 'level2', 'level3', 'level4', 'level5', 'level6');
|
|
419
|
+
await fs.mkdir(deepPath, { recursive: true });
|
|
420
|
+
await fs.writeFile(join(deepPath, 'SKILL.md'), '# Deep Skill');
|
|
421
|
+
const shallowAdapter = new LocalFilesystemAdapter({
|
|
422
|
+
id: 'test-shallow',
|
|
423
|
+
name: 'Test Shallow',
|
|
424
|
+
type: 'local',
|
|
425
|
+
baseUrl: 'file://',
|
|
426
|
+
enabled: true,
|
|
427
|
+
rootDir: testDir,
|
|
428
|
+
maxDepth: 3, // Only go 3 levels deep
|
|
429
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
430
|
+
});
|
|
431
|
+
await shallowAdapter.initialize();
|
|
432
|
+
// Should not find the deep skill (at level 6)
|
|
433
|
+
expect(shallowAdapter.skillCount).toBe(2);
|
|
434
|
+
});
|
|
435
|
+
it('should find skills within maxDepth', async () => {
|
|
436
|
+
// Create skill at level 3
|
|
437
|
+
const level3Path = join(testDir, 'a', 'b', 'c');
|
|
438
|
+
await fs.mkdir(level3Path, { recursive: true });
|
|
439
|
+
await fs.writeFile(join(level3Path, 'SKILL.md'), '# Level 3 Skill');
|
|
440
|
+
const deepAdapter = new LocalFilesystemAdapter({
|
|
441
|
+
id: 'test-deep',
|
|
442
|
+
name: 'Test Deep',
|
|
443
|
+
type: 'local',
|
|
444
|
+
baseUrl: 'file://',
|
|
445
|
+
enabled: true,
|
|
446
|
+
rootDir: testDir,
|
|
447
|
+
maxDepth: 5,
|
|
448
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
449
|
+
});
|
|
450
|
+
await deepAdapter.initialize();
|
|
451
|
+
// Should find the level 3 skill
|
|
452
|
+
expect(deepAdapter.skillCount).toBe(3);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
describe('Invalid Regex Patterns (SMI-722)', () => {
|
|
456
|
+
it('should not crash with invalid regex patterns like unclosed parenthesis', async () => {
|
|
457
|
+
// Create adapter with invalid regex pattern that would crash without fix
|
|
458
|
+
const adapterWithInvalidPattern = new LocalFilesystemAdapter({
|
|
459
|
+
id: 'test-invalid-regex',
|
|
460
|
+
name: 'Test Invalid Regex',
|
|
461
|
+
type: 'local',
|
|
462
|
+
baseUrl: 'file://',
|
|
463
|
+
enabled: true,
|
|
464
|
+
rootDir: testDir,
|
|
465
|
+
excludePatterns: ['(', 'node_modules'], // '(' is invalid regex
|
|
466
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
467
|
+
});
|
|
468
|
+
// Should not throw during initialization
|
|
469
|
+
await expect(adapterWithInvalidPattern.initialize()).resolves.not.toThrow();
|
|
470
|
+
expect(adapterWithInvalidPattern.skillCount).toBe(2);
|
|
471
|
+
});
|
|
472
|
+
it('should fall back to includes check for invalid regex patterns', async () => {
|
|
473
|
+
// Create a directory that contains the invalid pattern as substring
|
|
474
|
+
await fs.mkdir(join(testDir, 'test(dir'), { recursive: true });
|
|
475
|
+
await fs.writeFile(join(testDir, 'test(dir', 'SKILL.md'), '# Test Paren Dir');
|
|
476
|
+
const adapterWithInvalidPattern = new LocalFilesystemAdapter({
|
|
477
|
+
id: 'test-includes-fallback',
|
|
478
|
+
name: 'Test Includes Fallback',
|
|
479
|
+
type: 'local',
|
|
480
|
+
baseUrl: 'file://',
|
|
481
|
+
enabled: true,
|
|
482
|
+
rootDir: testDir,
|
|
483
|
+
excludePatterns: ['(', 'node_modules'], // '(' should match via includes
|
|
484
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
485
|
+
});
|
|
486
|
+
await adapterWithInvalidPattern.initialize();
|
|
487
|
+
// test(dir should be excluded because it includes '('
|
|
488
|
+
expect(adapterWithInvalidPattern.skillCount).toBe(2);
|
|
489
|
+
});
|
|
490
|
+
it('should handle multiple invalid regex patterns', async () => {
|
|
491
|
+
const adapterWithMultipleInvalid = new LocalFilesystemAdapter({
|
|
492
|
+
id: 'test-multiple-invalid',
|
|
493
|
+
name: 'Test Multiple Invalid',
|
|
494
|
+
type: 'local',
|
|
495
|
+
baseUrl: 'file://',
|
|
496
|
+
enabled: true,
|
|
497
|
+
rootDir: testDir,
|
|
498
|
+
excludePatterns: ['[invalid', '(unclosed', '*bad', 'node_modules'],
|
|
499
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
500
|
+
});
|
|
501
|
+
await expect(adapterWithMultipleInvalid.initialize()).resolves.not.toThrow();
|
|
502
|
+
expect(adapterWithMultipleInvalid.skillCount).toBe(2);
|
|
503
|
+
});
|
|
504
|
+
it('should still work with valid regex patterns', async () => {
|
|
505
|
+
// Create a directory matching a valid regex pattern
|
|
506
|
+
await fs.mkdir(join(testDir, 'test-temp-123'), { recursive: true });
|
|
507
|
+
await fs.writeFile(join(testDir, 'test-temp-123', 'SKILL.md'), '# Temp Skill');
|
|
508
|
+
const adapterWithValidRegex = new LocalFilesystemAdapter({
|
|
509
|
+
id: 'test-valid-regex',
|
|
510
|
+
name: 'Test Valid Regex',
|
|
511
|
+
type: 'local',
|
|
512
|
+
baseUrl: 'file://',
|
|
513
|
+
enabled: true,
|
|
514
|
+
rootDir: testDir,
|
|
515
|
+
excludePatterns: ['test-temp-\\d+', 'node_modules'], // Valid regex
|
|
516
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
517
|
+
});
|
|
518
|
+
await adapterWithValidRegex.initialize();
|
|
519
|
+
// test-temp-123 should be excluded by valid regex
|
|
520
|
+
expect(adapterWithValidRegex.skillCount).toBe(2);
|
|
521
|
+
});
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
describe('GitLabSourceAdapter (SMI-591)', () => {
|
|
525
|
+
let adapter;
|
|
526
|
+
beforeEach(() => {
|
|
527
|
+
mockFetch.mockReset();
|
|
528
|
+
adapter = new GitLabSourceAdapter({
|
|
529
|
+
id: 'test-gitlab',
|
|
530
|
+
name: 'Test GitLab',
|
|
531
|
+
type: 'gitlab',
|
|
532
|
+
baseUrl: 'https://gitlab.com/api/v4',
|
|
533
|
+
enabled: true,
|
|
534
|
+
rateLimit: { maxRequests: 100, windowMs: 60000, minDelayMs: 0 },
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
describe('Initialization', () => {
|
|
538
|
+
it('should have correct type', () => {
|
|
539
|
+
expect(adapter.type).toBe('gitlab');
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
describe('Health Check', () => {
|
|
543
|
+
it('should return healthy when API is reachable', async () => {
|
|
544
|
+
mockFetch.mockResolvedValueOnce({
|
|
545
|
+
ok: true,
|
|
546
|
+
headers: new Headers({
|
|
547
|
+
'ratelimit-remaining': '100',
|
|
548
|
+
'ratelimit-reset': String(Math.floor(Date.now() / 1000) + 3600),
|
|
549
|
+
}),
|
|
550
|
+
json: async () => ({ version: '15.0.0' }),
|
|
551
|
+
});
|
|
552
|
+
const health = await adapter.checkHealth();
|
|
553
|
+
expect(health.healthy).toBe(true);
|
|
554
|
+
});
|
|
555
|
+
it('should return unhealthy when API returns error', async () => {
|
|
556
|
+
mockFetch.mockResolvedValueOnce({
|
|
557
|
+
ok: false,
|
|
558
|
+
status: 500,
|
|
559
|
+
headers: new Headers(),
|
|
560
|
+
});
|
|
561
|
+
const health = await adapter.checkHealth();
|
|
562
|
+
expect(health.healthy).toBe(false);
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
describe('Search', () => {
|
|
566
|
+
it('should search for projects with topics', async () => {
|
|
567
|
+
mockFetch.mockResolvedValueOnce({
|
|
568
|
+
ok: true,
|
|
569
|
+
headers: new Headers({
|
|
570
|
+
'x-total': '2',
|
|
571
|
+
'x-total-pages': '1',
|
|
572
|
+
}),
|
|
573
|
+
json: async () => [
|
|
574
|
+
{
|
|
575
|
+
id: 1,
|
|
576
|
+
name: 'Skill Repo',
|
|
577
|
+
path_with_namespace: 'user/skill-repo',
|
|
578
|
+
namespace: { path: 'user', name: 'User' },
|
|
579
|
+
description: 'A skill repository',
|
|
580
|
+
web_url: 'https://gitlab.com/user/skill-repo',
|
|
581
|
+
star_count: 10,
|
|
582
|
+
forks_count: 5,
|
|
583
|
+
topics: ['claude-skill'],
|
|
584
|
+
last_activity_at: '2024-01-01T00:00:00Z',
|
|
585
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
586
|
+
default_branch: 'main',
|
|
587
|
+
},
|
|
588
|
+
],
|
|
589
|
+
});
|
|
590
|
+
const result = await adapter.search({ topics: ['claude-skill'] });
|
|
591
|
+
expect(result.repositories).toHaveLength(1);
|
|
592
|
+
expect(result.repositories[0].name).toBe('Skill Repo');
|
|
593
|
+
expect(result.repositories[0].owner).toBe('user');
|
|
594
|
+
});
|
|
595
|
+
it('should throw on rate limit', async () => {
|
|
596
|
+
mockFetch.mockResolvedValueOnce({
|
|
597
|
+
ok: false,
|
|
598
|
+
status: 429,
|
|
599
|
+
headers: new Headers(),
|
|
600
|
+
});
|
|
601
|
+
await expect(adapter.search({})).rejects.toThrow('rate limit');
|
|
602
|
+
});
|
|
603
|
+
});
|
|
604
|
+
describe('Paginated Search (SMI-724)', () => {
|
|
605
|
+
it('should handle searchWithCursor pagination', async () => {
|
|
606
|
+
// First page
|
|
607
|
+
mockFetch.mockResolvedValueOnce({
|
|
608
|
+
ok: true,
|
|
609
|
+
headers: new Headers({
|
|
610
|
+
'x-total': '50',
|
|
611
|
+
'x-total-pages': '2',
|
|
612
|
+
}),
|
|
613
|
+
json: async () => [
|
|
614
|
+
{
|
|
615
|
+
id: 1,
|
|
616
|
+
name: 'Skill 1',
|
|
617
|
+
path_with_namespace: 'user/skill-1',
|
|
618
|
+
namespace: { path: 'user', name: 'User' },
|
|
619
|
+
description: 'First skill',
|
|
620
|
+
web_url: 'https://gitlab.com/user/skill-1',
|
|
621
|
+
star_count: 10,
|
|
622
|
+
forks_count: 5,
|
|
623
|
+
topics: ['claude-skill'],
|
|
624
|
+
last_activity_at: '2024-01-01T00:00:00Z',
|
|
625
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
626
|
+
default_branch: 'main',
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
});
|
|
630
|
+
const result = await adapter.searchWithCursor({ limit: 30 }, 1);
|
|
631
|
+
expect(result.repositories).toHaveLength(1);
|
|
632
|
+
expect(result.hasMore).toBe(true);
|
|
633
|
+
expect(result.nextCursor).toBe('2');
|
|
634
|
+
});
|
|
635
|
+
it('should indicate no more pages on last page', async () => {
|
|
636
|
+
mockFetch.mockResolvedValueOnce({
|
|
637
|
+
ok: true,
|
|
638
|
+
headers: new Headers({
|
|
639
|
+
'x-total': '25',
|
|
640
|
+
'x-total-pages': '1',
|
|
641
|
+
}),
|
|
642
|
+
json: async () => [
|
|
643
|
+
{
|
|
644
|
+
id: 1,
|
|
645
|
+
name: 'Skill 1',
|
|
646
|
+
path_with_namespace: 'user/skill-1',
|
|
647
|
+
namespace: { path: 'user', name: 'User' },
|
|
648
|
+
description: 'Only skill',
|
|
649
|
+
web_url: 'https://gitlab.com/user/skill-1',
|
|
650
|
+
star_count: 5,
|
|
651
|
+
forks_count: 2,
|
|
652
|
+
topics: ['claude-skill'],
|
|
653
|
+
last_activity_at: '2024-01-01T00:00:00Z',
|
|
654
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
655
|
+
default_branch: 'main',
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
});
|
|
659
|
+
const result = await adapter.searchWithCursor({}, 1);
|
|
660
|
+
expect(result.hasMore).toBe(false);
|
|
661
|
+
expect(result.nextCursor).toBeUndefined();
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
describe('Get Repository', () => {
|
|
665
|
+
it('should get repository by location', async () => {
|
|
666
|
+
mockFetch.mockResolvedValueOnce({
|
|
667
|
+
ok: true,
|
|
668
|
+
headers: new Headers(),
|
|
669
|
+
json: async () => ({
|
|
670
|
+
id: 1,
|
|
671
|
+
name: 'skill-repo',
|
|
672
|
+
path_with_namespace: 'user/skill-repo',
|
|
673
|
+
namespace: { path: 'user', name: 'User' },
|
|
674
|
+
description: 'A skill repository',
|
|
675
|
+
web_url: 'https://gitlab.com/user/skill-repo',
|
|
676
|
+
star_count: 10,
|
|
677
|
+
forks_count: 5,
|
|
678
|
+
topics: [],
|
|
679
|
+
last_activity_at: '2024-01-01T00:00:00Z',
|
|
680
|
+
created_at: '2023-01-01T00:00:00Z',
|
|
681
|
+
default_branch: 'main',
|
|
682
|
+
}),
|
|
683
|
+
});
|
|
684
|
+
const repo = await adapter.getRepository({ owner: 'user', repo: 'skill-repo' });
|
|
685
|
+
expect(repo.name).toBe('skill-repo');
|
|
686
|
+
expect(repo.owner).toBe('user');
|
|
687
|
+
});
|
|
688
|
+
it('should throw for non-existent repository', async () => {
|
|
689
|
+
mockFetch.mockResolvedValueOnce({
|
|
690
|
+
ok: false,
|
|
691
|
+
status: 404,
|
|
692
|
+
headers: new Headers(),
|
|
693
|
+
});
|
|
694
|
+
await expect(adapter.getRepository({ owner: 'user', repo: 'nonexistent' })).rejects.toThrow('not found');
|
|
695
|
+
});
|
|
696
|
+
});
|
|
697
|
+
describe('Fetch Skill Content', () => {
|
|
698
|
+
it('should fetch and decode skill content', async () => {
|
|
699
|
+
const content = '---\nname: Test\n---\n# Test Skill';
|
|
700
|
+
const base64Content = Buffer.from(content).toString('base64');
|
|
701
|
+
mockFetch.mockResolvedValueOnce({
|
|
702
|
+
ok: true,
|
|
703
|
+
headers: new Headers(),
|
|
704
|
+
json: async () => ({
|
|
705
|
+
file_name: 'SKILL.md',
|
|
706
|
+
file_path: 'SKILL.md',
|
|
707
|
+
content: base64Content,
|
|
708
|
+
encoding: 'base64',
|
|
709
|
+
content_sha256: 'abc123',
|
|
710
|
+
last_commit_id: 'def456',
|
|
711
|
+
}),
|
|
712
|
+
});
|
|
713
|
+
const result = await adapter.fetchSkillContent({
|
|
714
|
+
owner: 'user',
|
|
715
|
+
repo: 'skill-repo',
|
|
716
|
+
});
|
|
717
|
+
expect(result.rawContent).toBe(content);
|
|
718
|
+
expect(result.sha).toBe('abc123');
|
|
719
|
+
});
|
|
720
|
+
it('should try multiple skill file paths', async () => {
|
|
721
|
+
// First path fails
|
|
722
|
+
mockFetch.mockResolvedValueOnce({
|
|
723
|
+
ok: false,
|
|
724
|
+
status: 404,
|
|
725
|
+
headers: new Headers(),
|
|
726
|
+
});
|
|
727
|
+
// Second path succeeds
|
|
728
|
+
const content = '# Skill';
|
|
729
|
+
mockFetch.mockResolvedValueOnce({
|
|
730
|
+
ok: true,
|
|
731
|
+
headers: new Headers(),
|
|
732
|
+
json: async () => ({
|
|
733
|
+
file_name: 'skill.md',
|
|
734
|
+
file_path: 'skill.md',
|
|
735
|
+
content: Buffer.from(content).toString('base64'),
|
|
736
|
+
encoding: 'base64',
|
|
737
|
+
content_sha256: 'xyz789',
|
|
738
|
+
}),
|
|
739
|
+
});
|
|
740
|
+
const result = await adapter.fetchSkillContent({
|
|
741
|
+
owner: 'user',
|
|
742
|
+
repo: 'skill-repo',
|
|
743
|
+
});
|
|
744
|
+
expect(result.rawContent).toBe(content);
|
|
745
|
+
});
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
//# sourceMappingURL=ScraperAdapters.test.js.map
|