@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.
Files changed (274) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +497 -110
  3. package/data/agents/code-reviewer.md +8 -1
  4. package/data/agents/research-assistant.md +8 -1
  5. package/data/agents/task-manager.md +8 -1
  6. package/data/ensembles/business-advisor.md +8 -1
  7. package/data/ensembles/creative-studio.md +8 -1
  8. package/data/ensembles/development-team.md +8 -1
  9. package/data/ensembles/security-analysis-team.md +8 -1
  10. package/data/memories/conversation-history.md +8 -1
  11. package/data/memories/learning-progress.md +8 -1
  12. package/data/memories/project-context.md +8 -1
  13. package/data/personas/business-consultant.md +8 -1
  14. package/data/personas/creative-writer.md +8 -1
  15. package/data/personas/debug-detective.md +8 -1
  16. package/data/personas/eli5-explainer.md +8 -1
  17. package/data/personas/security-analyst.md +8 -1
  18. package/data/personas/technical-analyst.md +8 -1
  19. package/data/skills/code-review.md +8 -1
  20. package/data/skills/creative-writing.md +8 -1
  21. package/data/skills/data-analysis.md +8 -1
  22. package/data/skills/penetration-testing.md +8 -1
  23. package/data/skills/research.md +8 -1
  24. package/data/skills/threat-modeling.md +8 -1
  25. package/data/skills/translation.md +8 -1
  26. package/data/templates/code-documentation.md +8 -1
  27. package/data/templates/email-professional.md +8 -1
  28. package/data/templates/meeting-notes.md +8 -1
  29. package/data/templates/penetration-test-report.md +8 -1
  30. package/data/templates/project-brief.md +8 -1
  31. package/data/templates/report-executive.md +8 -1
  32. package/data/templates/security-vulnerability-report.md +8 -1
  33. package/data/templates/threat-assessment-report.md +8 -1
  34. package/dist/auth/GitHubAuthManager.d.ts +6 -1
  35. package/dist/auth/GitHubAuthManager.d.ts.map +1 -1
  36. package/dist/auth/GitHubAuthManager.js +45 -18
  37. package/dist/benchmarks/IndexPerformanceBenchmark.d.ts +98 -0
  38. package/dist/benchmarks/IndexPerformanceBenchmark.d.ts.map +1 -0
  39. package/dist/benchmarks/IndexPerformanceBenchmark.js +531 -0
  40. package/dist/cache/CollectionCache.d.ts +65 -0
  41. package/dist/cache/CollectionCache.d.ts.map +1 -0
  42. package/dist/cache/CollectionCache.js +172 -0
  43. package/dist/cache/CollectionIndexCache.d.ts +77 -0
  44. package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
  45. package/dist/cache/CollectionIndexCache.js +349 -0
  46. package/dist/cache/LRUCache.d.ts +93 -0
  47. package/dist/cache/LRUCache.d.ts.map +1 -0
  48. package/dist/cache/LRUCache.js +299 -0
  49. package/dist/cache/index.d.ts +2 -0
  50. package/dist/cache/index.d.ts.map +1 -1
  51. package/dist/cache/index.js +3 -1
  52. package/dist/collection/CollectionBrowser.d.ts +44 -1
  53. package/dist/collection/CollectionBrowser.d.ts.map +1 -1
  54. package/dist/collection/CollectionBrowser.js +260 -28
  55. package/dist/collection/CollectionIndexManager.d.ts +151 -0
  56. package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
  57. package/dist/collection/CollectionIndexManager.js +499 -0
  58. package/dist/collection/CollectionSearch.d.ts +75 -1
  59. package/dist/collection/CollectionSearch.d.ts.map +1 -1
  60. package/dist/collection/CollectionSearch.js +435 -6
  61. package/dist/collection/CollectionSeeder.d.ts +36 -0
  62. package/dist/collection/CollectionSeeder.d.ts.map +1 -0
  63. package/dist/collection/CollectionSeeder.js +267 -0
  64. package/dist/collection/ElementInstaller.d.ts +31 -0
  65. package/dist/collection/ElementInstaller.d.ts.map +1 -1
  66. package/dist/collection/ElementInstaller.js +77 -15
  67. package/dist/collection/PersonaSubmitter.d.ts +48 -1
  68. package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
  69. package/dist/collection/PersonaSubmitter.js +170 -34
  70. package/dist/collection/index.d.ts +2 -0
  71. package/dist/collection/index.d.ts.map +1 -1
  72. package/dist/collection/index.js +3 -1
  73. package/dist/config/ConfigManager.d.ts +78 -0
  74. package/dist/config/ConfigManager.d.ts.map +1 -0
  75. package/dist/config/ConfigManager.js +216 -0
  76. package/dist/config/element-types.d.ts +135 -0
  77. package/dist/config/element-types.d.ts.map +1 -0
  78. package/dist/config/element-types.js +108 -0
  79. package/dist/config/index.d.ts +2 -0
  80. package/dist/config/index.d.ts.map +1 -1
  81. package/dist/config/index.js +3 -1
  82. package/dist/config/portfolio-constants.d.ts +83 -0
  83. package/dist/config/portfolio-constants.d.ts.map +1 -0
  84. package/dist/config/portfolio-constants.js +99 -0
  85. package/dist/elements/BaseElement.d.ts +14 -2
  86. package/dist/elements/BaseElement.d.ts.map +1 -1
  87. package/dist/elements/BaseElement.js +88 -6
  88. package/dist/elements/agents/Agent.d.ts +10 -1
  89. package/dist/elements/agents/Agent.d.ts.map +1 -1
  90. package/dist/elements/agents/Agent.js +66 -19
  91. package/dist/elements/agents/AgentManager.d.ts +2 -0
  92. package/dist/elements/agents/AgentManager.d.ts.map +1 -1
  93. package/dist/elements/agents/AgentManager.js +12 -10
  94. package/dist/elements/skills/Skill.d.ts +10 -1
  95. package/dist/elements/skills/Skill.d.ts.map +1 -1
  96. package/dist/elements/skills/Skill.js +40 -3
  97. package/dist/elements/skills/SkillManager.d.ts +1 -0
  98. package/dist/elements/skills/SkillManager.d.ts.map +1 -1
  99. package/dist/elements/skills/SkillManager.js +10 -4
  100. package/dist/elements/templates/Template.d.ts +10 -1
  101. package/dist/elements/templates/Template.d.ts.map +1 -1
  102. package/dist/elements/templates/Template.js +35 -18
  103. package/dist/elements/templates/TemplateManager.d.ts +1 -1
  104. package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
  105. package/dist/elements/templates/TemplateManager.js +6 -5
  106. package/dist/generated/version.d.ts +2 -2
  107. package/dist/generated/version.js +3 -3
  108. package/dist/index.barrel.d.ts +1 -2
  109. package/dist/index.barrel.d.ts.map +1 -1
  110. package/dist/index.barrel.js +2 -4
  111. package/dist/index.d.ts +154 -25
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +1951 -264
  114. package/dist/persona/PersonaElement.d.ts +10 -0
  115. package/dist/persona/PersonaElement.d.ts.map +1 -1
  116. package/dist/persona/PersonaElement.js +55 -32
  117. package/dist/persona/PersonaElementManager.d.ts.map +1 -1
  118. package/dist/persona/PersonaElementManager.js +13 -11
  119. package/dist/persona/PersonaLoader.d.ts.map +1 -1
  120. package/dist/persona/PersonaLoader.js +8 -2
  121. package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
  122. package/dist/persona/export-import/PersonaImporter.js +24 -5
  123. package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
  124. package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
  125. package/dist/persona/export-import/PersonaSharer.js +198 -22
  126. package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
  127. package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
  128. package/dist/portfolio/DefaultElementProvider.js +499 -7
  129. package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
  130. package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
  131. package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
  132. package/dist/portfolio/MigrationManager.d.ts.map +1 -1
  133. package/dist/portfolio/MigrationManager.js +136 -3
  134. package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
  135. package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
  136. package/dist/portfolio/PortfolioIndexManager.js +478 -0
  137. package/dist/portfolio/PortfolioManager.d.ts +5 -0
  138. package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
  139. package/dist/portfolio/PortfolioManager.js +61 -20
  140. package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
  141. package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
  142. package/dist/portfolio/PortfolioRepoManager.js +337 -0
  143. package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
  144. package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
  145. package/dist/portfolio/UnifiedIndexManager.js +1434 -0
  146. package/dist/portfolio/index.d.ts +15 -0
  147. package/dist/portfolio/index.d.ts.map +1 -0
  148. package/dist/portfolio/index.js +15 -0
  149. package/dist/portfolio/types.d.ts +7 -0
  150. package/dist/portfolio/types.d.ts.map +1 -1
  151. package/dist/portfolio/types.js +6 -1
  152. package/dist/security/InputValidator.d.ts.map +1 -1
  153. package/dist/security/InputValidator.js +50 -48
  154. package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
  155. package/dist/security/audit/SecurityAuditor.js +17 -9
  156. package/dist/security/audit/config/suppressions.d.ts.map +1 -1
  157. package/dist/security/audit/config/suppressions.js +19 -3
  158. package/dist/security/contentValidator.d.ts +2 -0
  159. package/dist/security/contentValidator.d.ts.map +1 -1
  160. package/dist/security/contentValidator.js +115 -4
  161. package/dist/security/secureYamlParser.d.ts +1 -0
  162. package/dist/security/secureYamlParser.d.ts.map +1 -1
  163. package/dist/security/secureYamlParser.js +29 -7
  164. package/dist/security/securityMonitor.d.ts +1 -1
  165. package/dist/security/securityMonitor.d.ts.map +1 -1
  166. package/dist/security/securityMonitor.js +1 -1
  167. package/dist/security/tokenManager.d.ts +1 -1
  168. package/dist/security/tokenManager.d.ts.map +1 -1
  169. package/dist/security/tokenManager.js +30 -10
  170. package/dist/server/ServerSetup.d.ts +22 -2
  171. package/dist/server/ServerSetup.d.ts.map +1 -1
  172. package/dist/server/ServerSetup.js +77 -12
  173. package/dist/server/tools/AuthTools.d.ts.map +1 -1
  174. package/dist/server/tools/AuthTools.js +33 -1
  175. package/dist/server/tools/BuildInfoTools.d.ts +25 -0
  176. package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
  177. package/dist/server/tools/BuildInfoTools.js +36 -0
  178. package/dist/server/tools/CollectionTools.d.ts.map +1 -1
  179. package/dist/server/tools/CollectionTools.js +62 -42
  180. package/dist/server/tools/ConfigTools.d.ts.map +1 -1
  181. package/dist/server/tools/ConfigTools.js +29 -1
  182. package/dist/server/tools/PersonaTools.d.ts +4 -2
  183. package/dist/server/tools/PersonaTools.d.ts.map +1 -1
  184. package/dist/server/tools/PersonaTools.js +5 -152
  185. package/dist/server/tools/PortfolioTools.d.ts +12 -0
  186. package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
  187. package/dist/server/tools/PortfolioTools.js +221 -0
  188. package/dist/server/tools/index.d.ts +3 -1
  189. package/dist/server/tools/index.d.ts.map +1 -1
  190. package/dist/server/tools/index.js +4 -2
  191. package/dist/server/types.d.ts +41 -5
  192. package/dist/server/types.d.ts.map +1 -1
  193. package/dist/server/types.js +1 -1
  194. package/dist/services/BuildInfoService.d.ts +84 -0
  195. package/dist/services/BuildInfoService.d.ts.map +1 -0
  196. package/dist/services/BuildInfoService.js +271 -0
  197. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
  198. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
  199. package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
  200. package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
  201. package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
  202. package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
  203. package/dist/tools/portfolio/types.d.ts +41 -0
  204. package/dist/tools/portfolio/types.d.ts.map +1 -0
  205. package/dist/tools/portfolio/types.js +15 -0
  206. package/dist/types/collection.d.ts +51 -0
  207. package/dist/types/collection.d.ts.map +1 -1
  208. package/dist/types/collection.js +1 -1
  209. package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
  210. package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
  211. package/dist/utils/EarlyTerminationSearch.js +164 -0
  212. package/dist/utils/ErrorHandler.d.ts +86 -0
  213. package/dist/utils/ErrorHandler.d.ts.map +1 -0
  214. package/dist/utils/ErrorHandler.js +201 -0
  215. package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
  216. package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
  217. package/dist/utils/FileDiscoveryUtil.js +169 -0
  218. package/dist/utils/GitHubRateLimiter.d.ts +88 -0
  219. package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
  220. package/dist/utils/GitHubRateLimiter.js +315 -0
  221. package/dist/utils/PerformanceMonitor.d.ts +134 -0
  222. package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
  223. package/dist/utils/PerformanceMonitor.js +347 -0
  224. package/dist/utils/RateLimiter.d.ts.map +1 -0
  225. package/dist/utils/RateLimiter.js +172 -0
  226. package/dist/utils/SecureDownloader.d.ts +241 -0
  227. package/dist/utils/SecureDownloader.d.ts.map +1 -0
  228. package/dist/utils/SecureDownloader.js +759 -0
  229. package/dist/utils/ToolCache.d.ts +82 -0
  230. package/dist/utils/ToolCache.d.ts.map +1 -0
  231. package/dist/utils/ToolCache.js +196 -0
  232. package/dist/utils/errorCodes.d.ts +136 -0
  233. package/dist/utils/errorCodes.d.ts.map +1 -0
  234. package/dist/utils/errorCodes.js +87 -0
  235. package/dist/utils/index.d.ts +3 -0
  236. package/dist/utils/index.d.ts.map +1 -1
  237. package/dist/utils/index.js +4 -1
  238. package/dist/utils/installation.d.ts +1 -1
  239. package/dist/utils/installation.d.ts.map +1 -1
  240. package/dist/utils/installation.js +9 -8
  241. package/dist/utils/searchUtils.d.ts +54 -0
  242. package/dist/utils/searchUtils.d.ts.map +1 -0
  243. package/dist/utils/searchUtils.js +118 -0
  244. package/package.json +17 -7
  245. package/dist/config/updateConfig.d.ts +0 -84
  246. package/dist/config/updateConfig.d.ts.map +0 -1
  247. package/dist/config/updateConfig.js +0 -148
  248. package/dist/server/tools/UpdateTools.d.ts +0 -10
  249. package/dist/server/tools/UpdateTools.d.ts.map +0 -1
  250. package/dist/server/tools/UpdateTools.js +0 -85
  251. package/dist/update/BackupManager.d.ts +0 -63
  252. package/dist/update/BackupManager.d.ts.map +0 -1
  253. package/dist/update/BackupManager.js +0 -370
  254. package/dist/update/DependencyChecker.d.ts +0 -41
  255. package/dist/update/DependencyChecker.d.ts.map +0 -1
  256. package/dist/update/DependencyChecker.js +0 -132
  257. package/dist/update/RateLimiter.d.ts.map +0 -1
  258. package/dist/update/RateLimiter.js +0 -172
  259. package/dist/update/SignatureVerifier.d.ts +0 -71
  260. package/dist/update/SignatureVerifier.d.ts.map +0 -1
  261. package/dist/update/SignatureVerifier.js +0 -214
  262. package/dist/update/UpdateChecker.d.ts +0 -132
  263. package/dist/update/UpdateChecker.d.ts.map +0 -1
  264. package/dist/update/UpdateChecker.js +0 -506
  265. package/dist/update/UpdateManager.d.ts +0 -60
  266. package/dist/update/UpdateManager.d.ts.map +0 -1
  267. package/dist/update/UpdateManager.js +0 -730
  268. package/dist/update/VersionManager.d.ts +0 -31
  269. package/dist/update/VersionManager.d.ts.map +0 -1
  270. package/dist/update/VersionManager.js +0 -181
  271. package/dist/update/index.d.ts +0 -9
  272. package/dist/update/index.d.ts.map +0 -1
  273. package/dist/update/index.js +0 -9
  274. /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"}