@dollhousemcp/mcp-server 1.5.1 → 1.6.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/CHANGELOG.md +90 -0
- package/README.md +497 -110
- package/data/agents/code-reviewer.md +8 -1
- package/data/agents/research-assistant.md +8 -1
- package/data/agents/task-manager.md +8 -1
- package/data/ensembles/business-advisor.md +8 -1
- package/data/ensembles/creative-studio.md +8 -1
- package/data/ensembles/development-team.md +8 -1
- package/data/ensembles/security-analysis-team.md +8 -1
- package/data/memories/conversation-history.md +8 -1
- package/data/memories/learning-progress.md +8 -1
- package/data/memories/project-context.md +8 -1
- package/data/personas/business-consultant.md +8 -1
- package/data/personas/creative-writer.md +8 -1
- package/data/personas/debug-detective.md +8 -1
- package/data/personas/eli5-explainer.md +8 -1
- package/data/personas/security-analyst.md +8 -1
- package/data/personas/technical-analyst.md +8 -1
- package/data/skills/code-review.md +8 -1
- package/data/skills/creative-writing.md +8 -1
- package/data/skills/data-analysis.md +8 -1
- package/data/skills/penetration-testing.md +8 -1
- package/data/skills/research.md +8 -1
- package/data/skills/threat-modeling.md +8 -1
- package/data/skills/translation.md +8 -1
- package/data/templates/code-documentation.md +8 -1
- package/data/templates/email-professional.md +8 -1
- package/data/templates/meeting-notes.md +8 -1
- package/data/templates/penetration-test-report.md +8 -1
- package/data/templates/project-brief.md +8 -1
- package/data/templates/report-executive.md +8 -1
- package/data/templates/security-vulnerability-report.md +8 -1
- package/data/templates/threat-assessment-report.md +8 -1
- package/dist/auth/GitHubAuthManager.d.ts +6 -1
- package/dist/auth/GitHubAuthManager.d.ts.map +1 -1
- package/dist/auth/GitHubAuthManager.js +45 -18
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts +98 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts.map +1 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.js +531 -0
- package/dist/cache/CollectionCache.d.ts +65 -0
- package/dist/cache/CollectionCache.d.ts.map +1 -0
- package/dist/cache/CollectionCache.js +172 -0
- package/dist/cache/CollectionIndexCache.d.ts +77 -0
- package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
- package/dist/cache/CollectionIndexCache.js +349 -0
- package/dist/cache/LRUCache.d.ts +93 -0
- package/dist/cache/LRUCache.d.ts.map +1 -0
- package/dist/cache/LRUCache.js +299 -0
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -1
- package/dist/collection/CollectionBrowser.d.ts +44 -1
- package/dist/collection/CollectionBrowser.d.ts.map +1 -1
- package/dist/collection/CollectionBrowser.js +260 -28
- package/dist/collection/CollectionIndexManager.d.ts +151 -0
- package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
- package/dist/collection/CollectionIndexManager.js +499 -0
- package/dist/collection/CollectionSearch.d.ts +75 -1
- package/dist/collection/CollectionSearch.d.ts.map +1 -1
- package/dist/collection/CollectionSearch.js +435 -6
- package/dist/collection/CollectionSeeder.d.ts +36 -0
- package/dist/collection/CollectionSeeder.d.ts.map +1 -0
- package/dist/collection/CollectionSeeder.js +267 -0
- package/dist/collection/ElementInstaller.d.ts +31 -0
- package/dist/collection/ElementInstaller.d.ts.map +1 -1
- package/dist/collection/ElementInstaller.js +77 -15
- package/dist/collection/PersonaSubmitter.d.ts +48 -1
- package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
- package/dist/collection/PersonaSubmitter.js +170 -34
- package/dist/collection/index.d.ts +2 -0
- package/dist/collection/index.d.ts.map +1 -1
- package/dist/collection/index.js +3 -1
- package/dist/config/ConfigManager.d.ts +78 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +216 -0
- package/dist/config/element-types.d.ts +135 -0
- package/dist/config/element-types.d.ts.map +1 -0
- package/dist/config/element-types.js +108 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/portfolio-constants.d.ts +83 -0
- package/dist/config/portfolio-constants.d.ts.map +1 -0
- package/dist/config/portfolio-constants.js +99 -0
- package/dist/elements/BaseElement.d.ts +14 -2
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +88 -6
- package/dist/elements/agents/Agent.d.ts +10 -1
- package/dist/elements/agents/Agent.d.ts.map +1 -1
- package/dist/elements/agents/Agent.js +66 -19
- package/dist/elements/agents/AgentManager.d.ts +2 -0
- package/dist/elements/agents/AgentManager.d.ts.map +1 -1
- package/dist/elements/agents/AgentManager.js +12 -10
- package/dist/elements/skills/Skill.d.ts +10 -1
- package/dist/elements/skills/Skill.d.ts.map +1 -1
- package/dist/elements/skills/Skill.js +40 -3
- package/dist/elements/skills/SkillManager.d.ts +1 -0
- package/dist/elements/skills/SkillManager.d.ts.map +1 -1
- package/dist/elements/skills/SkillManager.js +10 -4
- package/dist/elements/templates/Template.d.ts +10 -1
- package/dist/elements/templates/Template.d.ts.map +1 -1
- package/dist/elements/templates/Template.js +35 -18
- package/dist/elements/templates/TemplateManager.d.ts +1 -1
- package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
- package/dist/elements/templates/TemplateManager.js +6 -5
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/index.barrel.d.ts +1 -2
- package/dist/index.barrel.d.ts.map +1 -1
- package/dist/index.barrel.js +2 -4
- package/dist/index.d.ts +154 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1951 -264
- package/dist/persona/PersonaElement.d.ts +10 -0
- package/dist/persona/PersonaElement.d.ts.map +1 -1
- package/dist/persona/PersonaElement.js +55 -32
- package/dist/persona/PersonaElementManager.d.ts.map +1 -1
- package/dist/persona/PersonaElementManager.js +13 -11
- package/dist/persona/PersonaLoader.d.ts.map +1 -1
- package/dist/persona/PersonaLoader.js +8 -2
- package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaImporter.js +24 -5
- package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
- package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaSharer.js +198 -22
- package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
- package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
- package/dist/portfolio/DefaultElementProvider.js +499 -7
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
- package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
- package/dist/portfolio/MigrationManager.d.ts.map +1 -1
- package/dist/portfolio/MigrationManager.js +136 -3
- package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
- package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioIndexManager.js +478 -0
- package/dist/portfolio/PortfolioManager.d.ts +5 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
- package/dist/portfolio/PortfolioManager.js +61 -20
- package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
- package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioRepoManager.js +337 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
- package/dist/portfolio/UnifiedIndexManager.js +1434 -0
- package/dist/portfolio/index.d.ts +15 -0
- package/dist/portfolio/index.d.ts.map +1 -0
- package/dist/portfolio/index.js +15 -0
- package/dist/portfolio/types.d.ts +7 -0
- package/dist/portfolio/types.d.ts.map +1 -1
- package/dist/portfolio/types.js +6 -1
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +50 -48
- package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
- package/dist/security/audit/SecurityAuditor.js +17 -9
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +19 -3
- package/dist/security/contentValidator.d.ts +2 -0
- package/dist/security/contentValidator.d.ts.map +1 -1
- package/dist/security/contentValidator.js +115 -4
- package/dist/security/secureYamlParser.d.ts +1 -0
- package/dist/security/secureYamlParser.d.ts.map +1 -1
- package/dist/security/secureYamlParser.js +29 -7
- package/dist/security/securityMonitor.d.ts +1 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +1 -1
- package/dist/security/tokenManager.d.ts +1 -1
- package/dist/security/tokenManager.d.ts.map +1 -1
- package/dist/security/tokenManager.js +30 -10
- package/dist/server/ServerSetup.d.ts +22 -2
- package/dist/server/ServerSetup.d.ts.map +1 -1
- package/dist/server/ServerSetup.js +77 -12
- package/dist/server/tools/AuthTools.d.ts.map +1 -1
- package/dist/server/tools/AuthTools.js +33 -1
- package/dist/server/tools/BuildInfoTools.d.ts +25 -0
- package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
- package/dist/server/tools/BuildInfoTools.js +36 -0
- package/dist/server/tools/CollectionTools.d.ts.map +1 -1
- package/dist/server/tools/CollectionTools.js +62 -42
- package/dist/server/tools/ConfigTools.d.ts.map +1 -1
- package/dist/server/tools/ConfigTools.js +29 -1
- package/dist/server/tools/PersonaTools.d.ts +4 -2
- package/dist/server/tools/PersonaTools.d.ts.map +1 -1
- package/dist/server/tools/PersonaTools.js +5 -152
- package/dist/server/tools/PortfolioTools.d.ts +12 -0
- package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
- package/dist/server/tools/PortfolioTools.js +221 -0
- package/dist/server/tools/index.d.ts +3 -1
- package/dist/server/tools/index.d.ts.map +1 -1
- package/dist/server/tools/index.js +4 -2
- package/dist/server/types.d.ts +41 -5
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -1
- package/dist/services/BuildInfoService.d.ts +84 -0
- package/dist/services/BuildInfoService.d.ts.map +1 -0
- package/dist/services/BuildInfoService.js +271 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
- package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
- package/dist/tools/portfolio/types.d.ts +41 -0
- package/dist/tools/portfolio/types.d.ts.map +1 -0
- package/dist/tools/portfolio/types.js +15 -0
- package/dist/types/collection.d.ts +51 -0
- package/dist/types/collection.d.ts.map +1 -1
- package/dist/types/collection.js +1 -1
- package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
- package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
- package/dist/utils/EarlyTerminationSearch.js +164 -0
- package/dist/utils/ErrorHandler.d.ts +86 -0
- package/dist/utils/ErrorHandler.d.ts.map +1 -0
- package/dist/utils/ErrorHandler.js +201 -0
- package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
- package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
- package/dist/utils/FileDiscoveryUtil.js +169 -0
- package/dist/utils/GitHubRateLimiter.d.ts +88 -0
- package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
- package/dist/utils/GitHubRateLimiter.js +315 -0
- package/dist/utils/PerformanceMonitor.d.ts +134 -0
- package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
- package/dist/utils/PerformanceMonitor.js +347 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +172 -0
- package/dist/utils/SecureDownloader.d.ts +241 -0
- package/dist/utils/SecureDownloader.d.ts.map +1 -0
- package/dist/utils/SecureDownloader.js +759 -0
- package/dist/utils/ToolCache.d.ts +82 -0
- package/dist/utils/ToolCache.d.ts.map +1 -0
- package/dist/utils/ToolCache.js +196 -0
- package/dist/utils/errorCodes.d.ts +136 -0
- package/dist/utils/errorCodes.d.ts.map +1 -0
- package/dist/utils/errorCodes.js +87 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/installation.d.ts +1 -1
- package/dist/utils/installation.d.ts.map +1 -1
- package/dist/utils/installation.js +9 -8
- package/dist/utils/searchUtils.d.ts +54 -0
- package/dist/utils/searchUtils.d.ts.map +1 -0
- package/dist/utils/searchUtils.js +118 -0
- package/package.json +17 -7
- package/dist/config/updateConfig.d.ts +0 -84
- package/dist/config/updateConfig.d.ts.map +0 -1
- package/dist/config/updateConfig.js +0 -148
- package/dist/server/tools/UpdateTools.d.ts +0 -10
- package/dist/server/tools/UpdateTools.d.ts.map +0 -1
- package/dist/server/tools/UpdateTools.js +0 -85
- package/dist/update/BackupManager.d.ts +0 -63
- package/dist/update/BackupManager.d.ts.map +0 -1
- package/dist/update/BackupManager.js +0 -370
- package/dist/update/DependencyChecker.d.ts +0 -41
- package/dist/update/DependencyChecker.d.ts.map +0 -1
- package/dist/update/DependencyChecker.js +0 -132
- package/dist/update/RateLimiter.d.ts.map +0 -1
- package/dist/update/RateLimiter.js +0 -172
- package/dist/update/SignatureVerifier.d.ts +0 -71
- package/dist/update/SignatureVerifier.d.ts.map +0 -1
- package/dist/update/SignatureVerifier.js +0 -214
- package/dist/update/UpdateChecker.d.ts +0 -132
- package/dist/update/UpdateChecker.d.ts.map +0 -1
- package/dist/update/UpdateChecker.js +0 -506
- package/dist/update/UpdateManager.d.ts +0 -60
- package/dist/update/UpdateManager.d.ts.map +0 -1
- package/dist/update/UpdateManager.js +0 -730
- package/dist/update/VersionManager.d.ts +0 -31
- package/dist/update/VersionManager.d.ts.map +0 -1
- package/dist/update/VersionManager.js +0 -181
- package/dist/update/index.d.ts +0 -9
- package/dist/update/index.d.ts.map +0 -1
- package/dist/update/index.js +0 -9
- /package/dist/{update → utils}/RateLimiter.d.ts +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent cache for collection data to support offline/anonymous browsing
|
|
3
|
+
*/
|
|
4
|
+
export interface CollectionItem {
|
|
5
|
+
name: string;
|
|
6
|
+
path: string;
|
|
7
|
+
sha: string;
|
|
8
|
+
content?: string;
|
|
9
|
+
last_modified?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CollectionCacheEntry {
|
|
12
|
+
items: CollectionItem[];
|
|
13
|
+
timestamp: number;
|
|
14
|
+
etag?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Persistent cache for collection data that supports offline browsing
|
|
18
|
+
*/
|
|
19
|
+
export declare class CollectionCache {
|
|
20
|
+
private cacheDir;
|
|
21
|
+
private cacheFile;
|
|
22
|
+
private readonly CACHE_TTL_MS;
|
|
23
|
+
constructor(baseDir?: string);
|
|
24
|
+
/**
|
|
25
|
+
* Initialize cache directory
|
|
26
|
+
*/
|
|
27
|
+
private ensureCacheDir;
|
|
28
|
+
/**
|
|
29
|
+
* Load collection data from persistent cache
|
|
30
|
+
*/
|
|
31
|
+
loadCache(): Promise<CollectionCacheEntry | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Save collection data to persistent cache
|
|
34
|
+
*/
|
|
35
|
+
saveCache(items: CollectionItem[], etag?: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Search cached collection items with fuzzy matching
|
|
38
|
+
*/
|
|
39
|
+
searchCache(query: string): Promise<CollectionItem[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Normalize search terms for better matching (handles spaces, dashes, etc.)
|
|
42
|
+
*/
|
|
43
|
+
private normalizeSearchTerm;
|
|
44
|
+
/**
|
|
45
|
+
* Get cached collection items by type/path
|
|
46
|
+
*/
|
|
47
|
+
getItemsByPath(pathPrefix: string): Promise<CollectionItem[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if cache exists and is valid
|
|
50
|
+
*/
|
|
51
|
+
isCacheValid(): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Clear the cache
|
|
54
|
+
*/
|
|
55
|
+
clearCache(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Get cache stats for debugging
|
|
58
|
+
*/
|
|
59
|
+
getCacheStats(): Promise<{
|
|
60
|
+
itemCount: number;
|
|
61
|
+
cacheAge: number;
|
|
62
|
+
isValid: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=CollectionCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionCache.d.ts","sourceRoot":"","sources":["../../src/cache/CollectionCache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;gBAExC,OAAO,CAAC,EAAE,MAAM;IAc5B;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAkCvD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtE;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAkB3D;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IASnE;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAKtC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAY1F"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent cache for collection data to support offline/anonymous browsing
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { SecurityMonitor } from '../security/securityMonitor.js';
|
|
8
|
+
/**
|
|
9
|
+
* Persistent cache for collection data that supports offline browsing
|
|
10
|
+
*/
|
|
11
|
+
export class CollectionCache {
|
|
12
|
+
cacheDir;
|
|
13
|
+
cacheFile;
|
|
14
|
+
CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours for collection cache
|
|
15
|
+
constructor(baseDir) {
|
|
16
|
+
// Use environment variable if set, otherwise fall back to parameter or default
|
|
17
|
+
const envCacheDir = process.env.DOLLHOUSE_CACHE_DIR;
|
|
18
|
+
if (envCacheDir) {
|
|
19
|
+
this.cacheDir = envCacheDir;
|
|
20
|
+
logger.debug(`CollectionCache: Using environment cache directory: ${this.cacheDir}`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const defaultBaseDir = baseDir || process.cwd();
|
|
24
|
+
this.cacheDir = path.join(defaultBaseDir, '.dollhousemcp', 'cache');
|
|
25
|
+
logger.debug(`CollectionCache: Using default cache directory: ${this.cacheDir}`);
|
|
26
|
+
}
|
|
27
|
+
this.cacheFile = path.join(this.cacheDir, 'collection-cache.json');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize cache directory
|
|
31
|
+
*/
|
|
32
|
+
async ensureCacheDir() {
|
|
33
|
+
try {
|
|
34
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
logger.error(`Failed to create cache directory: ${error}`);
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load collection data from persistent cache
|
|
43
|
+
*/
|
|
44
|
+
async loadCache() {
|
|
45
|
+
try {
|
|
46
|
+
// Validate cache file path (basic security check)
|
|
47
|
+
if (this.cacheFile.includes('..') || this.cacheFile.includes('\0')) {
|
|
48
|
+
// SECURITY FIX: Add audit logging for path traversal attempt detection
|
|
49
|
+
SecurityMonitor.logSecurityEvent({
|
|
50
|
+
type: 'PATH_TRAVERSAL_ATTEMPT',
|
|
51
|
+
severity: 'HIGH',
|
|
52
|
+
source: 'CollectionCache.loadCache',
|
|
53
|
+
details: `Potential path traversal attempt detected in cache file path: ${this.cacheFile.substring(0, 100)}`
|
|
54
|
+
});
|
|
55
|
+
logger.warn('Invalid cache file path, skipping cache load');
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const data = await fs.readFile(this.cacheFile, 'utf8');
|
|
59
|
+
const cache = JSON.parse(data);
|
|
60
|
+
// Check if cache is expired
|
|
61
|
+
if (Date.now() - cache.timestamp > this.CACHE_TTL_MS) {
|
|
62
|
+
logger.debug('Collection cache expired, will refresh from GitHub');
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
logger.debug(`Loaded ${cache.items.length} items from collection cache`);
|
|
66
|
+
return cache;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error.code !== 'ENOENT') {
|
|
70
|
+
logger.debug(`Failed to load collection cache: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Save collection data to persistent cache
|
|
77
|
+
*/
|
|
78
|
+
async saveCache(items, etag) {
|
|
79
|
+
try {
|
|
80
|
+
await this.ensureCacheDir();
|
|
81
|
+
const cacheEntry = {
|
|
82
|
+
items,
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
etag
|
|
85
|
+
};
|
|
86
|
+
const data = JSON.stringify(cacheEntry, null, 2);
|
|
87
|
+
await fs.writeFile(this.cacheFile, data, 'utf8');
|
|
88
|
+
logger.debug(`Saved ${items.length} items to collection cache`);
|
|
89
|
+
// SECURITY FIX: Add audit logging for cache write operations
|
|
90
|
+
logger.debug('Security audit: Cache write operation completed successfully');
|
|
91
|
+
// Log operation completed successfully
|
|
92
|
+
logger.debug(`Cache file operation completed with ${items.length} items`);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger.error(`Failed to save collection cache: ${error}`);
|
|
96
|
+
// Don't throw - caching failures shouldn't break functionality
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Search cached collection items with fuzzy matching
|
|
101
|
+
*/
|
|
102
|
+
async searchCache(query) {
|
|
103
|
+
const cache = await this.loadCache();
|
|
104
|
+
if (!cache) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
const normalizedQuery = this.normalizeSearchTerm(query);
|
|
108
|
+
return cache.items.filter(item => {
|
|
109
|
+
// Search in filename and path with normalization
|
|
110
|
+
const normalizedName = this.normalizeSearchTerm(item.name);
|
|
111
|
+
const normalizedPath = this.normalizeSearchTerm(item.path);
|
|
112
|
+
return normalizedName.includes(normalizedQuery) ||
|
|
113
|
+
normalizedPath.includes(normalizedQuery) ||
|
|
114
|
+
(item.content && this.normalizeSearchTerm(item.content).includes(normalizedQuery));
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Normalize search terms for better matching (handles spaces, dashes, etc.)
|
|
119
|
+
*/
|
|
120
|
+
normalizeSearchTerm(term) {
|
|
121
|
+
return term.toLowerCase()
|
|
122
|
+
.replace(/[-_\s]+/g, ' ') // Convert dashes, underscores to spaces
|
|
123
|
+
.replace(/\.md$/, '') // Remove .md extension
|
|
124
|
+
.trim();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get cached collection items by type/path
|
|
128
|
+
*/
|
|
129
|
+
async getItemsByPath(pathPrefix) {
|
|
130
|
+
const cache = await this.loadCache();
|
|
131
|
+
if (!cache) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
return cache.items.filter(item => item.path.startsWith(pathPrefix));
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if cache exists and is valid
|
|
138
|
+
*/
|
|
139
|
+
async isCacheValid() {
|
|
140
|
+
const cache = await this.loadCache();
|
|
141
|
+
return cache !== null;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Clear the cache
|
|
145
|
+
*/
|
|
146
|
+
async clearCache() {
|
|
147
|
+
try {
|
|
148
|
+
await fs.unlink(this.cacheFile);
|
|
149
|
+
logger.debug('Collection cache cleared');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
if (error.code !== 'ENOENT') {
|
|
153
|
+
logger.debug(`Failed to clear collection cache: ${error}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get cache stats for debugging
|
|
159
|
+
*/
|
|
160
|
+
async getCacheStats() {
|
|
161
|
+
const cache = await this.loadCache();
|
|
162
|
+
if (!cache) {
|
|
163
|
+
return { itemCount: 0, cacheAge: 0, isValid: false };
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
itemCount: cache.items.length,
|
|
167
|
+
cacheAge: Date.now() - cache.timestamp,
|
|
168
|
+
isValid: Date.now() - cache.timestamp <= this.CACHE_TTL_MS
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sbGVjdGlvbkNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhY2hlL0NvbGxlY3Rpb25DYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFnQmpFOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDbEIsUUFBUSxDQUFTO0lBQ2pCLFNBQVMsQ0FBUztJQUNULFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxnQ0FBZ0M7SUFFckYsWUFBWSxPQUFnQjtRQUMxQiwrRUFBK0U7UUFDL0UsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztRQUNwRCxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxLQUFLLENBQUMsdURBQXVELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxjQUFjLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRSxNQUFNLENBQUMsS0FBSyxDQUFDLG1EQUFtRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENB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QUcsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdkQsQ0FBQztRQUVELE9BQU87WUFDTCxTQUFTLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNO1lBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFNBQVM7WUFDdEMsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZO1NBQzNELENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBlcnNpc3RlbnQgY2FjaGUgZm9yIGNvbGxlY3Rpb24gZGF0YSB0byBzdXBwb3J0IG9mZmxpbmUvYW5vbnltb3VzIGJyb3dzaW5nXG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBQYXRoVmFsaWRhdG9yIH0gZnJvbSAnLi4vc2VjdXJpdHkvcGF0aFZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBTZWN1cml0eU1vbml0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cml0eU1vbml0b3IuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3Rpb25JdGVtIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHNoYTogc3RyaW5nO1xuICBjb250ZW50Pzogc3RyaW5nO1xuICBsYXN0X21vZGlmaWVkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3Rpb25DYWNoZUVudHJ5IHtcbiAgaXRlbXM6IENvbGxlY3Rpb25JdGVtW107XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICBldGFnPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBlcnNpc3RlbnQgY2FjaGUgZm9yIGNvbGxlY3Rpb24gZGF0YSB0aGF0IHN1cHBvcnRzIG9mZmxpbmUgYnJvd3NpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIENvbGxlY3Rpb25DYWNoZSB7XG4gIHByaXZhdGUgY2FjaGVEaXI6IHN0cmluZztcbiAgcHJpdmF0ZSBjYWNoZUZpbGU6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBDQUNIRV9UVExfTVMgPSAyNCAqIDYwICogNjAgKiAxMDAwOyAvLyAyNCBob3VycyBmb3IgY29sbGVjdGlvbiBjYWNoZVxuICBcbiAgY29uc3RydWN0b3IoYmFzZURpcj86IHN0cmluZykge1xuICAgIC8vIFVzZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBpZiBzZXQsIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gcGFyYW1ldGVyIG9yIGRlZmF1bHRcbiAgICBjb25zdCBlbnZDYWNoZURpciA9IHByb2Nlc3MuZW52LkRPTExIT1VTRV9DQUNIRV9ESVI7XG4gICAgaWYgKGVudkNhY2hlRGlyKSB7XG4gICAgICB0aGlzLmNhY2hlRGlyID0gZW52Q2FjaGVEaXI7XG4gICAgICBsb2dnZXIuZGVidWcoYENvbGxlY3Rpb25DYWNoZTogVXNpbmcgZW52aXJvbm1lbnQgY2FjaGUgZGlyZWN0b3J5OiAke3RoaXMuY2FjaGVEaXJ9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRCYXNlRGlyID0gYmFzZURpciB8fCBwcm9jZXNzLmN3ZCgpO1xuICAgICAgdGhpcy5jYWNoZURpciA9IHBhdGguam9pbihkZWZhdWx0QmFzZURpciwgJy5kb2xsaG91c2VtY3AnLCAnY2FjaGUnKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ29sbGVjdGlvbkNhY2hlOiBVc2luZyBkZWZhdWx0IGNhY2hlIGRpcmVjdG9yeTogJHt0aGlzLmNhY2hlRGlyfWApO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlRmlsZSA9IHBhdGguam9pbih0aGlzLmNhY2hlRGlyLCAnY29sbGVjdGlvbi1jYWNoZS5qc29uJyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGNhY2hlIGRpcmVjdG9yeVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVDYWNoZURpcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMubWtkaXIodGhpcy5jYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBjYWNoZSBkaXJlY3Rvcnk6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBMb2FkIGNvbGxlY3Rpb24gZGF0YSBmcm9tIHBlcnNpc3RlbnQgY2FjaGVcbiAgICovXG4gIGFzeW5jIGxvYWRDYWNoZSgpOiBQcm9taXNlPENvbGxlY3Rpb25DYWNoZUVudHJ5IHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBWYWxpZGF0ZSBjYWNoZSBmaWxlIHBhdGggKGJhc2ljIHNlY3VyaXR5IGNoZWNrKVxuICAgICAgaWYgKHRoaXMuY2FjaGVGaWxlLmluY2x1ZGVzKCcuLicpIHx8IHRoaXMuY2FjaGVGaWxlLmluY2x1ZGVzKCdcXDAnKSkge1xuICAgICAgICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBwYXRoIHRyYXZlcnNhbCBhdHRlbXB0IGRldGVjdGlvblxuICAgICAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ1BBVEhfVFJBVkVSU0FMX0FUVEVNUFQnLFxuICAgICAgICAgIHNldmVyaXR5OiAnSElHSCcsXG4gICAgICAgICAgc291cmNlOiAnQ29sbGVjdGlvbkNhY2hlLmxvYWRDYWNoZScsXG4gICAgICAgICAgZGV0YWlsczogYFBvdGVudGlhbCBwYXRoIHRyYXZlcnNhbCBhdHRlbXB0IGRldGVjdGVkIGluIGNhY2hlIGZpbGUgcGF0aDogJHt0aGlzLmNhY2hlRmlsZS5zdWJzdHJpbmcoMCwgMTAwKX1gXG4gICAgICAgIH0pO1xuICAgICAgICBsb2dnZXIud2FybignSW52YWxpZCBjYWNoZSBmaWxlIHBhdGgsIHNraXBwaW5nIGNhY2hlIGxvYWQnKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZSh0aGlzLmNhY2hlRmlsZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGNhY2hlOiBDb2xsZWN0aW9uQ2FjaGVFbnRyeSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIGNhY2hlIGlzIGV4cGlyZWRcbiAgICAgIGlmIChEYXRlLm5vdygpIC0gY2FjaGUudGltZXN0YW1wID4gdGhpcy5DQUNIRV9UVExfTVMpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGNhY2hlIGV4cGlyZWQsIHdpbGwgcmVmcmVzaCBmcm9tIEdpdEh1YicpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtjYWNoZS5pdGVtcy5sZW5ndGh9IGl0ZW1zIGZyb20gY29sbGVjdGlvbiBjYWNoZWApO1xuICAgICAgcmV0dXJuIGNhY2hlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoKGVycm9yIGFzIGFueSkuY29kZSAhPT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gbG9hZCBjb2xsZWN0aW9uIGNhY2hlOiAke2Vycm9yfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogU2F2ZSBjb2xsZWN0aW9uIGRhdGEgdG8gcGVyc2lzdGVudCBjYWNoZVxuICAgKi9cbiAgYXN5bmMgc2F2ZUNhY2hlKGl0ZW1zOiBDb2xsZWN0aW9uSXRlbVtdLCBldGFnPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ2FjaGVEaXIoKTtcbiAgICAgIFxuICAgICAgY29uc3QgY2FjaGVFbnRyeTogQ29sbGVjdGlvbkNhY2hlRW50cnkgPSB7XG4gICAgICAgIGl0ZW1zLFxuICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgIGV0YWdcbiAgICAgIH07XG4gICAgICBcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnN0cmluZ2lmeShjYWNoZUVudHJ5LCBudWxsLCAyKTtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0aGlzLmNhY2hlRmlsZSwgZGF0YSwgJ3V0ZjgnKTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKGBTYXZlZCAke2l0ZW1zLmxlbmd0aH0gaXRlbXMgdG8gY29sbGVjdGlvbiBjYWNoZWApO1xuICAgICAgXG4gICAgICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBjYWNoZSB3cml0ZSBvcGVyYXRpb25zXG4gICAgICBsb2dnZXIuZGVidWcoJ1NlY3VyaXR5IGF1ZGl0OiBDYWNoZSB3cml0ZSBvcGVyYXRpb24gY29tcGxldGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgXG4gICAgICAvLyBMb2cgb3BlcmF0aW9uIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHlcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2FjaGUgZmlsZSBvcGVyYXRpb24gY29tcGxldGVkIHdpdGggJHtpdGVtcy5sZW5ndGh9IGl0ZW1zYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNhdmUgY29sbGVjdGlvbiBjYWNoZTogJHtlcnJvcn1gKTtcbiAgICAgIC8vIERvbid0IHRocm93IC0gY2FjaGluZyBmYWlsdXJlcyBzaG91bGRuJ3QgYnJlYWsgZnVuY3Rpb25hbGl0eVxuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFNlYXJjaCBjYWNoZWQgY29sbGVjdGlvbiBpdGVtcyB3aXRoIGZ1enp5IG1hdGNoaW5nXG4gICAqL1xuICBhc3luYyBzZWFyY2hDYWNoZShxdWVyeTogc3RyaW5nKTogUHJvbWlzZTxDb2xsZWN0aW9uSXRlbVtdPiB7XG4gICAgY29uc3QgY2FjaGUgPSBhd2FpdCB0aGlzLmxvYWRDYWNoZSgpO1xuICAgIGlmICghY2FjaGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgXG4gICAgY29uc3Qgbm9ybWFsaXplZFF1ZXJ5ID0gdGhpcy5ub3JtYWxpemVTZWFyY2hUZXJtKHF1ZXJ5KTtcbiAgICByZXR1cm4gY2FjaGUuaXRlbXMuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgLy8gU2VhcmNoIGluIGZpbGVuYW1lIGFuZCBwYXRoIHdpdGggbm9ybWFsaXphdGlvblxuICAgICAgY29uc3Qgbm9ybWFsaXplZE5hbWUgPSB0aGlzLm5vcm1hbGl6ZVNlYXJjaFRlcm0oaXRlbS5uYW1lKTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gdGhpcy5ub3JtYWxpemVTZWFyY2hUZXJtKGl0ZW0ucGF0aCk7XG4gICAgICBcbiAgICAgIHJldHVybiBub3JtYWxpemVkTmFtZS5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpIHx8IFxuICAgICAgICAgICAgIG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSkgfHxcbiAgICAgICAgICAgICAoaXRlbS5jb250ZW50ICYmIHRoaXMubm9ybWFsaXplU2VhcmNoVGVybShpdGVtLmNvbnRlbnQpLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSkpO1xuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogTm9ybWFsaXplIHNlYXJjaCB0ZXJtcyBmb3IgYmV0dGVyIG1hdGNoaW5nIChoYW5kbGVzIHNwYWNlcywgZGFzaGVzLCBldGMuKVxuICAgKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVTZWFyY2hUZXJtKHRlcm06IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRlcm0udG9Mb3dlckNhc2UoKVxuICAgICAgLnJlcGxhY2UoL1stX1xcc10rL2csICcgJykgIC8vIENvbnZlcnQgZGFzaGVzLCB1bmRlcnNjb3JlcyB0byBzcGFjZXNcbiAgICAgIC5yZXBsYWNlKC9cXC5tZCQvLCAnJykgICAgICAgLy8gUmVtb3ZlIC5tZCBleHRlbnNpb25cbiAgICAgIC50cmltKCk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgY2FjaGVkIGNvbGxlY3Rpb24gaXRlbXMgYnkgdHlwZS9wYXRoXG4gICAqL1xuICBhc3luYyBnZXRJdGVtc0J5UGF0aChwYXRoUHJlZml4OiBzdHJpbmcpOiBQcm9taXNlPENvbGxlY3Rpb25JdGVtW10+IHtcbiAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHRoaXMubG9hZENhY2hlKCk7XG4gICAgaWYgKCFjYWNoZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gY2FjaGUuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5wYXRoLnN0YXJ0c1dpdGgocGF0aFByZWZpeCkpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgY2FjaGUgZXhpc3RzIGFuZCBpcyB2YWxpZFxuICAgKi9cbiAgYXN5bmMgaXNDYWNoZVZhbGlkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgdGhpcy5sb2FkQ2FjaGUoKTtcbiAgICByZXR1cm4gY2FjaGUgIT09IG51bGw7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgY2FjaGVcbiAgICovXG4gIGFzeW5jIGNsZWFyQ2FjaGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLnVubGluayh0aGlzLmNhY2hlRmlsZSk7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NvbGxlY3Rpb24gY2FjaGUgY2xlYXJlZCcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoKGVycm9yIGFzIGFueSkuY29kZSAhPT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gY2xlYXIgY29sbGVjdGlvbiBjYWNoZTogJHtlcnJvcn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgY2FjaGUgc3RhdHMgZm9yIGRlYnVnZ2luZ1xuICAgKi9cbiAgYXN5bmMgZ2V0Q2FjaGVTdGF0cygpOiBQcm9taXNlPHsgaXRlbUNvdW50OiBudW1iZXI7IGNhY2hlQWdlOiBudW1iZXI7IGlzVmFsaWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgdGhpcy5sb2FkQ2FjaGUoKTtcbiAgICBpZiAoIWNhY2hlKSB7XG4gICAgICByZXR1cm4geyBpdGVtQ291bnQ6IDAsIGNhY2hlQWdlOiAwLCBpc1ZhbGlkOiBmYWxzZSB9O1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgaXRlbUNvdW50OiBjYWNoZS5pdGVtcy5sZW5ndGgsXG4gICAgICBjYWNoZUFnZTogRGF0ZS5ub3coKSAtIGNhY2hlLnRpbWVzdGFtcCxcbiAgICAgIGlzVmFsaWQ6IERhdGUubm93KCkgLSBjYWNoZS50aW1lc3RhbXAgPD0gdGhpcy5DQUNIRV9UVExfTVNcbiAgICB9O1xuICB9XG59Il19
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart cache for collection index with conditional fetching and performance optimization
|
|
3
|
+
*/
|
|
4
|
+
import { CollectionIndex } from '../types/collection.js';
|
|
5
|
+
import { GitHubClient } from '../collection/GitHubClient.js';
|
|
6
|
+
export declare class CollectionIndexCache {
|
|
7
|
+
private cache;
|
|
8
|
+
private readonly TTL;
|
|
9
|
+
private readonly INDEX_URL;
|
|
10
|
+
private cacheDir;
|
|
11
|
+
private cacheFile;
|
|
12
|
+
private githubClient;
|
|
13
|
+
private performanceMonitor;
|
|
14
|
+
private memoryCache;
|
|
15
|
+
private fetchPromise;
|
|
16
|
+
constructor(githubClient: GitHubClient, baseDir?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Get the collection index with performance optimization and lazy loading
|
|
19
|
+
*/
|
|
20
|
+
getIndex(lazyLoad?: boolean): Promise<CollectionIndex>;
|
|
21
|
+
/**
|
|
22
|
+
* Check if current cache is valid (within TTL)
|
|
23
|
+
*/
|
|
24
|
+
private isValid;
|
|
25
|
+
/**
|
|
26
|
+
* Fetch fresh index from GitHub with conditional requests
|
|
27
|
+
*/
|
|
28
|
+
private fetchFresh;
|
|
29
|
+
/**
|
|
30
|
+
* Validate the structure of a collection index
|
|
31
|
+
*/
|
|
32
|
+
private validateIndexStructure;
|
|
33
|
+
/**
|
|
34
|
+
* Save cache to persistent storage
|
|
35
|
+
*/
|
|
36
|
+
private saveToDisk;
|
|
37
|
+
/**
|
|
38
|
+
* Load cache from persistent storage
|
|
39
|
+
*/
|
|
40
|
+
private loadFromDisk;
|
|
41
|
+
/**
|
|
42
|
+
* Ensure cache directory exists
|
|
43
|
+
*/
|
|
44
|
+
private ensureCacheDir;
|
|
45
|
+
/**
|
|
46
|
+
* Clear all cache data with performance monitoring
|
|
47
|
+
*/
|
|
48
|
+
clearCache(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Get comprehensive cache statistics for debugging and monitoring
|
|
51
|
+
*/
|
|
52
|
+
getCacheStats(): {
|
|
53
|
+
isValid: boolean;
|
|
54
|
+
age: number;
|
|
55
|
+
hasCache: boolean;
|
|
56
|
+
elements: number;
|
|
57
|
+
memoryCache: any;
|
|
58
|
+
performanceMetrics: any;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Fetch fresh index with comprehensive fallback strategy
|
|
62
|
+
*/
|
|
63
|
+
private fetchFreshWithFallback;
|
|
64
|
+
/**
|
|
65
|
+
* Record performance metrics for cache operations
|
|
66
|
+
*/
|
|
67
|
+
private recordPerformanceMetrics;
|
|
68
|
+
/**
|
|
69
|
+
* Calculate cache hit rate (placeholder for future implementation)
|
|
70
|
+
*/
|
|
71
|
+
private calculateCacheHitRate;
|
|
72
|
+
/**
|
|
73
|
+
* Calculate average access time (placeholder for future implementation)
|
|
74
|
+
*/
|
|
75
|
+
private calculateAverageAccessTime;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=CollectionIndexCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionIndexCache.d.ts","sourceRoot":"","sources":["../../src/cache/CollectionIndexCache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAe,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAK7D,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiG;IAC3H,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,YAAY,CAAyC;gBAEjD,YAAY,EAAE,YAAY,EAAE,OAAO,GAAE,MAAsB;IAiBvE;;OAEG;IACG,QAAQ,CAAC,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAiEnE;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;YACW,UAAU;IAiExB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAc9B;;OAEG;YACW,UAAU;IAmBxB;;OAEG;YACW,YAAY;IA4B1B;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBjC;;OAEG;IACH,aAAa,IAAI;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,GAAG,CAAC;QACjB,kBAAkB,EAAE,GAAG,CAAC;KACzB;IA8BD;;OAEG;YACW,sBAAsB;IAuBpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;OAEG;IACH,OAAO,CAAC,0BAA0B;CAInC"}
|