swift-skills-mcp 0.0.1

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 (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/build/cli/auth.d.ts +3 -0
  4. package/build/cli/auth.d.ts.map +1 -0
  5. package/build/cli/auth.js +44 -0
  6. package/build/cli/auth.js.map +1 -0
  7. package/build/cli/setup.d.ts +2 -0
  8. package/build/cli/setup.d.ts.map +1 -0
  9. package/build/cli/setup.js +150 -0
  10. package/build/cli/setup.js.map +1 -0
  11. package/build/cli/source-manager.d.ts +3 -0
  12. package/build/cli/source-manager.d.ts.map +1 -0
  13. package/build/cli/source-manager.js +117 -0
  14. package/build/cli/source-manager.js.map +1 -0
  15. package/build/config/creators.d.ts +11 -0
  16. package/build/config/creators.d.ts.map +1 -0
  17. package/build/config/creators.js +32 -0
  18. package/build/config/creators.js.map +1 -0
  19. package/build/config/sources.d.ts +91 -0
  20. package/build/config/sources.d.ts.map +1 -0
  21. package/build/config/sources.js +231 -0
  22. package/build/config/sources.js.map +1 -0
  23. package/build/config/sources.test.d.ts +2 -0
  24. package/build/config/sources.test.d.ts.map +1 -0
  25. package/build/config/sources.test.js +199 -0
  26. package/build/config/sources.test.js.map +1 -0
  27. package/build/config/swift-keywords.d.ts +29 -0
  28. package/build/config/swift-keywords.d.ts.map +1 -0
  29. package/build/config/swift-keywords.js +77 -0
  30. package/build/config/swift-keywords.js.map +1 -0
  31. package/build/index.d.ts +3 -0
  32. package/build/index.d.ts.map +1 -0
  33. package/build/index.js +181 -0
  34. package/build/index.js.map +1 -0
  35. package/build/integration/cache-behavior.test.d.ts +2 -0
  36. package/build/integration/cache-behavior.test.d.ts.map +1 -0
  37. package/build/integration/cache-behavior.test.js +521 -0
  38. package/build/integration/cache-behavior.test.js.map +1 -0
  39. package/build/integration/mcp-client.test.d.ts +2 -0
  40. package/build/integration/mcp-client.test.d.ts.map +1 -0
  41. package/build/integration/mcp-client.test.js +82 -0
  42. package/build/integration/mcp-client.test.js.map +1 -0
  43. package/build/integration/response-quality.test.d.ts +2 -0
  44. package/build/integration/response-quality.test.d.ts.map +1 -0
  45. package/build/integration/response-quality.test.js +230 -0
  46. package/build/integration/response-quality.test.js.map +1 -0
  47. package/build/integration/test-client.d.ts +25 -0
  48. package/build/integration/test-client.d.ts.map +1 -0
  49. package/build/integration/test-client.js +93 -0
  50. package/build/integration/test-client.js.map +1 -0
  51. package/build/sources/free/nilcoalescing.d.ts +8 -0
  52. package/build/sources/free/nilcoalescing.d.ts.map +1 -0
  53. package/build/sources/free/nilcoalescing.js +26 -0
  54. package/build/sources/free/nilcoalescing.js.map +1 -0
  55. package/build/sources/free/nilcoalescing.test.d.ts +2 -0
  56. package/build/sources/free/nilcoalescing.test.d.ts.map +1 -0
  57. package/build/sources/free/nilcoalescing.test.js +63 -0
  58. package/build/sources/free/nilcoalescing.test.js.map +1 -0
  59. package/build/sources/free/pointfree.d.ts +15 -0
  60. package/build/sources/free/pointfree.d.ts.map +1 -0
  61. package/build/sources/free/pointfree.js +175 -0
  62. package/build/sources/free/pointfree.js.map +1 -0
  63. package/build/sources/free/pointfree.test.d.ts +2 -0
  64. package/build/sources/free/pointfree.test.d.ts.map +1 -0
  65. package/build/sources/free/pointfree.test.js +86 -0
  66. package/build/sources/free/pointfree.test.js.map +1 -0
  67. package/build/sources/free/rssPatternSource.d.ts +42 -0
  68. package/build/sources/free/rssPatternSource.d.ts.map +1 -0
  69. package/build/sources/free/rssPatternSource.js +109 -0
  70. package/build/sources/free/rssPatternSource.js.map +1 -0
  71. package/build/sources/free/rssPatternSource.test.d.ts +2 -0
  72. package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
  73. package/build/sources/free/rssPatternSource.test.js +89 -0
  74. package/build/sources/free/rssPatternSource.test.js.map +1 -0
  75. package/build/sources/free/sundell.d.ts +8 -0
  76. package/build/sources/free/sundell.d.ts.map +1 -0
  77. package/build/sources/free/sundell.js +17 -0
  78. package/build/sources/free/sundell.js.map +1 -0
  79. package/build/sources/free/sundell.test.d.ts +2 -0
  80. package/build/sources/free/sundell.test.d.ts.map +1 -0
  81. package/build/sources/free/sundell.test.js +63 -0
  82. package/build/sources/free/sundell.test.js.map +1 -0
  83. package/build/sources/free/vanderlee.d.ts +8 -0
  84. package/build/sources/free/vanderlee.d.ts.map +1 -0
  85. package/build/sources/free/vanderlee.js +63 -0
  86. package/build/sources/free/vanderlee.js.map +1 -0
  87. package/build/sources/free/vanderlee.test.d.ts +2 -0
  88. package/build/sources/free/vanderlee.test.d.ts.map +1 -0
  89. package/build/sources/free/vanderlee.test.js +77 -0
  90. package/build/sources/free/vanderlee.test.js.map +1 -0
  91. package/build/sources/premium/patreon-dl.d.ts +45 -0
  92. package/build/sources/premium/patreon-dl.d.ts.map +1 -0
  93. package/build/sources/premium/patreon-dl.js +189 -0
  94. package/build/sources/premium/patreon-dl.js.map +1 -0
  95. package/build/sources/premium/patreon-fetch.d.ts +3 -0
  96. package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
  97. package/build/sources/premium/patreon-fetch.js +18 -0
  98. package/build/sources/premium/patreon-fetch.js.map +1 -0
  99. package/build/sources/premium/patreon-oauth.d.ts +24 -0
  100. package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
  101. package/build/sources/premium/patreon-oauth.js +208 -0
  102. package/build/sources/premium/patreon-oauth.js.map +1 -0
  103. package/build/sources/premium/patreon-zip.d.ts +17 -0
  104. package/build/sources/premium/patreon-zip.d.ts.map +1 -0
  105. package/build/sources/premium/patreon-zip.js +127 -0
  106. package/build/sources/premium/patreon-zip.js.map +1 -0
  107. package/build/sources/premium/patreon.d.ts +48 -0
  108. package/build/sources/premium/patreon.d.ts.map +1 -0
  109. package/build/sources/premium/patreon.js +221 -0
  110. package/build/sources/premium/patreon.js.map +1 -0
  111. package/build/sources/premium/youtube.d.ts +14 -0
  112. package/build/sources/premium/youtube.d.ts.map +1 -0
  113. package/build/sources/premium/youtube.js +92 -0
  114. package/build/sources/premium/youtube.js.map +1 -0
  115. package/build/tools/extract-cookie.d.ts +2 -0
  116. package/build/tools/extract-cookie.d.ts.map +1 -0
  117. package/build/tools/extract-cookie.js +40 -0
  118. package/build/tools/extract-cookie.js.map +1 -0
  119. package/build/tools/handlers/enableSource.d.ts +3 -0
  120. package/build/tools/handlers/enableSource.d.ts.map +1 -0
  121. package/build/tools/handlers/enableSource.js +25 -0
  122. package/build/tools/handlers/enableSource.js.map +1 -0
  123. package/build/tools/handlers/getPatreonPatterns.d.ts +3 -0
  124. package/build/tools/handlers/getPatreonPatterns.d.ts.map +1 -0
  125. package/build/tools/handlers/getPatreonPatterns.js +43 -0
  126. package/build/tools/handlers/getPatreonPatterns.js.map +1 -0
  127. package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
  128. package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
  129. package/build/tools/handlers/getSwiftPattern.js +72 -0
  130. package/build/tools/handlers/getSwiftPattern.js.map +1 -0
  131. package/build/tools/handlers/handlers.test.d.ts +2 -0
  132. package/build/tools/handlers/handlers.test.d.ts.map +1 -0
  133. package/build/tools/handlers/handlers.test.js +359 -0
  134. package/build/tools/handlers/handlers.test.js.map +1 -0
  135. package/build/tools/handlers/listContentSources.d.ts +3 -0
  136. package/build/tools/handlers/listContentSources.d.ts.map +1 -0
  137. package/build/tools/handlers/listContentSources.js +34 -0
  138. package/build/tools/handlers/listContentSources.js.map +1 -0
  139. package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
  140. package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
  141. package/build/tools/handlers/searchSwiftContent.js +121 -0
  142. package/build/tools/handlers/searchSwiftContent.js.map +1 -0
  143. package/build/tools/handlers/setupPatreon.d.ts +3 -0
  144. package/build/tools/handlers/setupPatreon.d.ts.map +1 -0
  145. package/build/tools/handlers/setupPatreon.js +40 -0
  146. package/build/tools/handlers/setupPatreon.js.map +1 -0
  147. package/build/tools/index.d.ts +3 -0
  148. package/build/tools/index.d.ts.map +1 -0
  149. package/build/tools/index.js +18 -0
  150. package/build/tools/index.js.map +1 -0
  151. package/build/tools/registry.d.ts +14 -0
  152. package/build/tools/registry.d.ts.map +1 -0
  153. package/build/tools/registry.js +21 -0
  154. package/build/tools/registry.js.map +1 -0
  155. package/build/tools/registry.test.d.ts +2 -0
  156. package/build/tools/registry.test.d.ts.map +1 -0
  157. package/build/tools/registry.test.js +54 -0
  158. package/build/tools/registry.test.js.map +1 -0
  159. package/build/tools/types.d.ts +67 -0
  160. package/build/tools/types.d.ts.map +1 -0
  161. package/build/tools/types.js +3 -0
  162. package/build/tools/types.js.map +1 -0
  163. package/build/utils/cache.d.ts +20 -0
  164. package/build/utils/cache.d.ts.map +1 -0
  165. package/build/utils/cache.js +186 -0
  166. package/build/utils/cache.js.map +1 -0
  167. package/build/utils/concurrency.d.ts +13 -0
  168. package/build/utils/concurrency.d.ts.map +1 -0
  169. package/build/utils/concurrency.js +33 -0
  170. package/build/utils/concurrency.js.map +1 -0
  171. package/build/utils/errors.d.ts +19 -0
  172. package/build/utils/errors.d.ts.map +1 -0
  173. package/build/utils/errors.js +35 -0
  174. package/build/utils/errors.js.map +1 -0
  175. package/build/utils/fetch.d.ts +6 -0
  176. package/build/utils/fetch.d.ts.map +1 -0
  177. package/build/utils/fetch.js +6 -0
  178. package/build/utils/fetch.js.map +1 -0
  179. package/build/utils/http.d.ts +21 -0
  180. package/build/utils/http.d.ts.map +1 -0
  181. package/build/utils/http.js +53 -0
  182. package/build/utils/http.js.map +1 -0
  183. package/build/utils/intent-cache.d.ts +94 -0
  184. package/build/utils/intent-cache.d.ts.map +1 -0
  185. package/build/utils/intent-cache.js +164 -0
  186. package/build/utils/intent-cache.js.map +1 -0
  187. package/build/utils/intent-cache.test.d.ts +2 -0
  188. package/build/utils/intent-cache.test.d.ts.map +1 -0
  189. package/build/utils/intent-cache.test.js +290 -0
  190. package/build/utils/intent-cache.test.js.map +1 -0
  191. package/build/utils/logger.d.ts +4 -0
  192. package/build/utils/logger.d.ts.map +1 -0
  193. package/build/utils/logger.js +9 -0
  194. package/build/utils/logger.js.map +1 -0
  195. package/build/utils/paths.d.ts +27 -0
  196. package/build/utils/paths.d.ts.map +1 -0
  197. package/build/utils/paths.js +43 -0
  198. package/build/utils/paths.js.map +1 -0
  199. package/build/utils/pattern-formatter.d.ts +40 -0
  200. package/build/utils/pattern-formatter.d.ts.map +1 -0
  201. package/build/utils/pattern-formatter.js +124 -0
  202. package/build/utils/pattern-formatter.js.map +1 -0
  203. package/build/utils/response-helpers.d.ts +17 -0
  204. package/build/utils/response-helpers.d.ts.map +1 -0
  205. package/build/utils/response-helpers.js +34 -0
  206. package/build/utils/response-helpers.js.map +1 -0
  207. package/build/utils/search-terms.d.ts +17 -0
  208. package/build/utils/search-terms.d.ts.map +1 -0
  209. package/build/utils/search-terms.js +71 -0
  210. package/build/utils/search-terms.js.map +1 -0
  211. package/build/utils/search-terms.test.d.ts +2 -0
  212. package/build/utils/search-terms.test.d.ts.map +1 -0
  213. package/build/utils/search-terms.test.js +107 -0
  214. package/build/utils/search-terms.test.js.map +1 -0
  215. package/build/utils/search.d.ts +48 -0
  216. package/build/utils/search.d.ts.map +1 -0
  217. package/build/utils/search.js +158 -0
  218. package/build/utils/search.js.map +1 -0
  219. package/build/utils/search.test.d.ts +2 -0
  220. package/build/utils/search.test.d.ts.map +1 -0
  221. package/build/utils/search.test.js +199 -0
  222. package/build/utils/search.test.js.map +1 -0
  223. package/build/utils/semantic-recall.d.ts +38 -0
  224. package/build/utils/semantic-recall.d.ts.map +1 -0
  225. package/build/utils/semantic-recall.js +134 -0
  226. package/build/utils/semantic-recall.js.map +1 -0
  227. package/build/utils/semantic-recall.test.d.ts +2 -0
  228. package/build/utils/semantic-recall.test.d.ts.map +1 -0
  229. package/build/utils/semantic-recall.test.js +326 -0
  230. package/build/utils/semantic-recall.test.js.map +1 -0
  231. package/build/utils/source-registry.d.ts +45 -0
  232. package/build/utils/source-registry.d.ts.map +1 -0
  233. package/build/utils/source-registry.js +113 -0
  234. package/build/utils/source-registry.js.map +1 -0
  235. package/build/utils/source-registry.test.d.ts +2 -0
  236. package/build/utils/source-registry.test.d.ts.map +1 -0
  237. package/build/utils/source-registry.test.js +206 -0
  238. package/build/utils/source-registry.test.js.map +1 -0
  239. package/build/utils/swift-analysis.d.ts +61 -0
  240. package/build/utils/swift-analysis.d.ts.map +1 -0
  241. package/build/utils/swift-analysis.js +339 -0
  242. package/build/utils/swift-analysis.js.map +1 -0
  243. package/build/utils/swift-analysis.test.d.ts +2 -0
  244. package/build/utils/swift-analysis.test.d.ts.map +1 -0
  245. package/build/utils/swift-analysis.test.js +473 -0
  246. package/build/utils/swift-analysis.test.js.map +1 -0
  247. package/package.json +85 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared HTTP utilities for making requests with timeouts and error handling
3
+ */
4
+ import { fetch } from './fetch.js';
5
+ const DEFAULT_TIMEOUT = 10000; // 10 seconds
6
+ /**
7
+ * Build headers with optional authorization token
8
+ */
9
+ export function buildHeaders(userAgent, authToken) {
10
+ const headers = {
11
+ 'User-Agent': userAgent,
12
+ };
13
+ if (authToken) {
14
+ headers.Authorization = `Bearer ${authToken}`;
15
+ }
16
+ return headers;
17
+ }
18
+ /**
19
+ * Fetch with timeout and error handling
20
+ */
21
+ async function fetchWithTimeout(url, options = {}) {
22
+ const { timeout = DEFAULT_TIMEOUT, headers = {}, signal } = options;
23
+ const controller = new AbortController();
24
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
25
+ try {
26
+ const response = await fetch(url, {
27
+ signal: signal || controller.signal,
28
+ headers,
29
+ });
30
+ if (!response.ok) {
31
+ throw new Error(`HTTP ${response.status}`);
32
+ }
33
+ return response;
34
+ }
35
+ finally {
36
+ clearTimeout(timeoutId);
37
+ }
38
+ }
39
+ /**
40
+ * Fetch JSON data with timeout
41
+ */
42
+ export async function fetchJson(url, options = {}) {
43
+ const response = await fetchWithTimeout(url, options);
44
+ return await response.json();
45
+ }
46
+ /**
47
+ * Fetch text content with timeout
48
+ */
49
+ export async function fetchText(url, options = {}) {
50
+ const response = await fetchWithTimeout(url, options);
51
+ return await response.text();
52
+ }
53
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQnC,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;AAE5C;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,SAAkB;IAChE,MAAM,OAAO,GAA2B;QACtC,YAAY,EAAE,SAAS;KACxB,CAAC;IACF,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CAAC,aAAa,GAAG,UAAU,SAAS,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,EAAE,OAAO,GAAG,eAAe,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEpE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM,IAAI,UAAU,CAAC,MAAM;YACnC,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Components used to build a cache key
3
+ */
4
+ export interface IntentKey {
5
+ tool: string;
6
+ query: string;
7
+ minQuality: number;
8
+ sources: string[];
9
+ requireCode?: boolean;
10
+ }
11
+ /**
12
+ * Cached search result with all required fields
13
+ */
14
+ export interface CachedIntentResult {
15
+ patternIds: string[];
16
+ scores: Record<string, number>;
17
+ sourceFingerprint: string;
18
+ timestamp: number;
19
+ totalCount: number;
20
+ patterns?: unknown[];
21
+ }
22
+ /**
23
+ * Storable cached search result (without immutable metadata fields)
24
+ * Handlers use this to set cache values with complete type safety
25
+ */
26
+ export interface StorableCachedSearchResult {
27
+ patternIds: string[];
28
+ scores: Record<string, number>;
29
+ totalCount: number;
30
+ patterns?: unknown[];
31
+ }
32
+ /**
33
+ * IntentCache - Caches tool handler results by normalized query intent
34
+ *
35
+ * Key features:
36
+ * - SHA-256 hashing for cache keys
37
+ * - Query normalization (lowercase, stopwords, sorted)
38
+ * - Source fingerprinting for invalidation
39
+ * - Stores metadata only (IDs + scores), not full patterns
40
+ */
41
+ export declare class IntentCache {
42
+ private cache;
43
+ private pendingFetches;
44
+ private hits;
45
+ private misses;
46
+ constructor(maxMemoryEntries?: number, namespace?: string);
47
+ /**
48
+ * Normalize a query for consistent cache key generation
49
+ * - Lowercase
50
+ * - Remove stopwords (except Swift terms)
51
+ * - Sort alphabetically (order-independent)
52
+ */
53
+ normalizeQuery(query: string): string;
54
+ /**
55
+ * Generate a fingerprint from enabled source IDs
56
+ * Used to detect when sources change (invalidating cached results)
57
+ */
58
+ getSourceFingerprint(sources: string[]): string;
59
+ /**
60
+ * Build a cache key from intent components
61
+ * Format: tool::normalizedQuery::qN::fingerprint[::code]
62
+ */
63
+ buildCacheKey(intent: IntentKey): string;
64
+ /**
65
+ * Get cached result, validating source fingerprint
66
+ * Returns null if no valid cache entry exists
67
+ */
68
+ get(intent: IntentKey): Promise<CachedIntentResult | null>;
69
+ /**
70
+ * Store result in cache
71
+ * Accepts both basic CachedIntentResult and extended CachedIntentResultWithPatterns
72
+ */
73
+ set(intent: IntentKey, result: StorableCachedSearchResult, ttl?: number): Promise<void>;
74
+ /**
75
+ * Get cached result or fetch if not cached
76
+ * Includes in-flight deduplication to prevent cache stampede
77
+ */
78
+ getOrFetch(intent: IntentKey, fetcher: () => Promise<StorableCachedSearchResult>, ttl?: number): Promise<CachedIntentResult>;
79
+ /**
80
+ * Clear all cached intents
81
+ */
82
+ clear(): void;
83
+ /**
84
+ * Get cache statistics
85
+ */
86
+ getStats(): {
87
+ hits: number;
88
+ misses: number;
89
+ hitRate: number;
90
+ };
91
+ }
92
+ export declare const intentCache: IntentCache;
93
+ export default IntentCache;
94
+ //# sourceMappingURL=intent-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-cache.d.ts","sourceRoot":"","sources":["../../src/utils/intent-cache.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,cAAc,CAA4C;IAGlE,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAGjB,gBAAgB,GAAE,MAAmC,EACrD,SAAS,GAAE,MAAiB;IAK9B;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAQrC;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAQ/C;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM;IAqBxC;;;OAGG;IACG,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAoBhE;;;OAGG;IACG,GAAG,CACP,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,0BAA0B,EAClC,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,IAAI,CAAC;IAahB;;;OAGG;IACG,UAAU,CACd,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,MAAM,OAAO,CAAC,0BAA0B,CAAC,EAClD,GAAG,GAAE,MAA2B,GAC/B,OAAO,CAAC,kBAAkB,CAAC;IAuC9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAQ9D;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC;AAE7C,eAAe,WAAW,CAAC"}
@@ -0,0 +1,164 @@
1
+ // src/utils/intent-cache.ts
2
+ // Intent-aware response caching for MCP tool handlers
3
+ import { createHash } from 'crypto';
4
+ import { FileCache } from './cache.js';
5
+ import { normalizeTokens } from './search-terms.js';
6
+ // 12 hours in seconds (longer than RSS cache, shorter than article cache)
7
+ const DEFAULT_INTENT_TTL = 43200;
8
+ const DEFAULT_MAX_MEMORY_ENTRIES = 200;
9
+ /**
10
+ * IntentCache - Caches tool handler results by normalized query intent
11
+ *
12
+ * Key features:
13
+ * - SHA-256 hashing for cache keys
14
+ * - Query normalization (lowercase, stopwords, sorted)
15
+ * - Source fingerprinting for invalidation
16
+ * - Stores metadata only (IDs + scores), not full patterns
17
+ */
18
+ export class IntentCache {
19
+ cache;
20
+ pendingFetches = new Map();
21
+ // Simple metrics
22
+ hits = 0;
23
+ misses = 0;
24
+ constructor(maxMemoryEntries = DEFAULT_MAX_MEMORY_ENTRIES, namespace = 'intent') {
25
+ this.cache = new FileCache(namespace, maxMemoryEntries);
26
+ }
27
+ /**
28
+ * Normalize a query for consistent cache key generation
29
+ * - Lowercase
30
+ * - Remove stopwords (except Swift terms)
31
+ * - Sort alphabetically (order-independent)
32
+ */
33
+ normalizeQuery(query) {
34
+ // Use shared normalization without stemming (cache keys shouldn't stem)
35
+ const processed = normalizeTokens(query);
36
+ // Sort for order-independent matching
37
+ return processed.sort().join(' ');
38
+ }
39
+ /**
40
+ * Generate a fingerprint from enabled source IDs
41
+ * Used to detect when sources change (invalidating cached results)
42
+ */
43
+ getSourceFingerprint(sources) {
44
+ const sorted = [...sources].sort().join(',');
45
+ return createHash('sha256')
46
+ .update(sorted)
47
+ .digest('hex')
48
+ .substring(0, 12); // 12 chars sufficient for source combos
49
+ }
50
+ /**
51
+ * Build a cache key from intent components
52
+ * Format: tool::normalizedQuery::qN::fingerprint[::code]
53
+ */
54
+ buildCacheKey(intent) {
55
+ const normalized = this.normalizeQuery(intent.query);
56
+ const fingerprint = this.getSourceFingerprint(intent.sources);
57
+ const parts = [
58
+ intent.tool,
59
+ normalized,
60
+ `q${intent.minQuality}`,
61
+ fingerprint,
62
+ ];
63
+ if (intent.requireCode) {
64
+ parts.push('code');
65
+ }
66
+ const key = parts.join('::');
67
+ // Always hash for filesystem safety and consistent length
68
+ return createHash('sha256').update(key).digest('hex');
69
+ }
70
+ /**
71
+ * Get cached result, validating source fingerprint
72
+ * Returns null if no valid cache entry exists
73
+ */
74
+ async get(intent) {
75
+ const key = this.buildCacheKey(intent);
76
+ const cached = await this.cache.get(key);
77
+ if (!cached) {
78
+ this.misses++;
79
+ return null;
80
+ }
81
+ // Validate source fingerprint hasn't changed
82
+ const currentFingerprint = this.getSourceFingerprint(intent.sources);
83
+ if (cached.sourceFingerprint !== currentFingerprint) {
84
+ this.misses++;
85
+ return null; // Sources changed, treat as miss
86
+ }
87
+ this.hits++;
88
+ return cached;
89
+ }
90
+ /**
91
+ * Store result in cache
92
+ * Accepts both basic CachedIntentResult and extended CachedIntentResultWithPatterns
93
+ */
94
+ async set(intent, result, ttl = DEFAULT_INTENT_TTL) {
95
+ const key = this.buildCacheKey(intent);
96
+ const fingerprint = this.getSourceFingerprint(intent.sources);
97
+ const entry = {
98
+ ...result,
99
+ sourceFingerprint: fingerprint,
100
+ timestamp: Date.now(),
101
+ };
102
+ await this.cache.set(key, entry, ttl);
103
+ }
104
+ /**
105
+ * Get cached result or fetch if not cached
106
+ * Includes in-flight deduplication to prevent cache stampede
107
+ */
108
+ async getOrFetch(intent, fetcher, ttl = DEFAULT_INTENT_TTL) {
109
+ // Check cache first
110
+ const cached = await this.get(intent);
111
+ if (cached) {
112
+ return cached;
113
+ }
114
+ // Build key for deduplication
115
+ const key = this.buildCacheKey(intent);
116
+ // Check if fetch already in progress (stampede prevention)
117
+ const pending = this.pendingFetches.get(key);
118
+ if (pending) {
119
+ return pending;
120
+ }
121
+ // Start fetch and track it
122
+ const fetchPromise = (async () => {
123
+ try {
124
+ const result = await fetcher();
125
+ const fingerprint = this.getSourceFingerprint(intent.sources);
126
+ const entry = {
127
+ ...result,
128
+ sourceFingerprint: fingerprint,
129
+ timestamp: Date.now(),
130
+ };
131
+ await this.cache.set(key, entry, ttl);
132
+ return entry;
133
+ }
134
+ finally {
135
+ this.pendingFetches.delete(key);
136
+ }
137
+ })();
138
+ this.pendingFetches.set(key, fetchPromise);
139
+ return fetchPromise;
140
+ }
141
+ /**
142
+ * Clear all cached intents
143
+ */
144
+ clear() {
145
+ this.cache.clear();
146
+ this.hits = 0;
147
+ this.misses = 0;
148
+ }
149
+ /**
150
+ * Get cache statistics
151
+ */
152
+ getStats() {
153
+ const total = this.hits + this.misses;
154
+ return {
155
+ hits: this.hits,
156
+ misses: this.misses,
157
+ hitRate: total > 0 ? this.hits / total : 0,
158
+ };
159
+ }
160
+ }
161
+ // Shared instance for tool handlers
162
+ export const intentCache = new IntentCache();
163
+ export default IntentCache;
164
+ //# sourceMappingURL=intent-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-cache.js","sourceRoot":"","sources":["../../src/utils/intent-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=intent-cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-cache.test.d.ts","sourceRoot":"","sources":["../../src/utils/intent-cache.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,290 @@
1
+ // src/utils/intent-cache.test.ts
2
+ import { describe, it, expect, beforeEach } from 'vitest';
3
+ import { IntentCache } from './intent-cache.js';
4
+ describe('IntentCache', () => {
5
+ let cache;
6
+ beforeEach(() => {
7
+ // Use test-specific namespace to avoid cache pollution from build/ tests
8
+ cache = new IntentCache(50, `test-${Date.now()}-${Math.random()}`);
9
+ cache.clear();
10
+ });
11
+ describe('normalizeQuery', () => {
12
+ it('should lowercase queries', () => {
13
+ expect(cache.normalizeQuery('SwiftUI Navigation')).toBe('navigation swiftui');
14
+ });
15
+ it('should trim whitespace', () => {
16
+ expect(cache.normalizeQuery(' async await ')).toBe('async await');
17
+ });
18
+ it('should collapse multiple spaces', () => {
19
+ expect(cache.normalizeQuery('async await')).toBe('async await');
20
+ });
21
+ it('should remove stopwords', () => {
22
+ // "how" and "to" are stopwords, but "use" is not
23
+ expect(cache.normalizeQuery('how to use async await')).toBe('async await use');
24
+ });
25
+ it('should preserve Swift technical terms', () => {
26
+ const result = cache.normalizeQuery('swiftui combine async await');
27
+ expect(result).toContain('swiftui');
28
+ expect(result).toContain('combine');
29
+ expect(result).toContain('async');
30
+ expect(result).toContain('await');
31
+ });
32
+ it('should sort tokens alphabetically', () => {
33
+ expect(cache.normalizeQuery('zeta alpha beta')).toBe('alpha beta zeta');
34
+ });
35
+ it('should handle hyphenated terms', () => {
36
+ const result = cache.normalizeQuery('async-await patterns');
37
+ expect(result).toContain('async');
38
+ expect(result).toContain('await');
39
+ expect(result).toContain('pattern');
40
+ });
41
+ it('should produce consistent output for semantically similar queries', () => {
42
+ const q1 = cache.normalizeQuery('How to use SwiftUI navigation');
43
+ const q2 = cache.normalizeQuery('swiftui navigation usage');
44
+ const q3 = cache.normalizeQuery('Navigation in SwiftUI');
45
+ // All should normalize similarly (containing same key terms)
46
+ expect(q1).toContain('navigation');
47
+ expect(q1).toContain('swiftui');
48
+ expect(q2).toContain('navigation');
49
+ expect(q2).toContain('swiftui');
50
+ expect(q3).toContain('navigation');
51
+ expect(q3).toContain('swiftui');
52
+ });
53
+ });
54
+ describe('getSourceFingerprint', () => {
55
+ it('should produce deterministic fingerprint for same sources', () => {
56
+ const sources = ['sundell', 'vanderlee', 'pointfree'];
57
+ const fp1 = cache.getSourceFingerprint(sources);
58
+ const fp2 = cache.getSourceFingerprint(sources);
59
+ expect(fp1).toBe(fp2);
60
+ });
61
+ it('should produce same fingerprint regardless of source order', () => {
62
+ const fp1 = cache.getSourceFingerprint(['sundell', 'vanderlee']);
63
+ const fp2 = cache.getSourceFingerprint(['vanderlee', 'sundell']);
64
+ expect(fp1).toBe(fp2);
65
+ });
66
+ it('should produce different fingerprint for different sources', () => {
67
+ const fp1 = cache.getSourceFingerprint(['sundell']);
68
+ const fp2 = cache.getSourceFingerprint(['sundell', 'vanderlee']);
69
+ expect(fp1).not.toBe(fp2);
70
+ });
71
+ it('should return 12-character fingerprint', () => {
72
+ const fp = cache.getSourceFingerprint(['sundell', 'vanderlee']);
73
+ expect(fp.length).toBe(12);
74
+ });
75
+ });
76
+ describe('buildCacheKey', () => {
77
+ it('should produce deterministic key for same intent', () => {
78
+ const intent = {
79
+ tool: 'get_swift_pattern',
80
+ query: 'SwiftUI Navigation',
81
+ minQuality: 60,
82
+ sources: ['sundell', 'vanderlee'],
83
+ };
84
+ const key1 = cache.buildCacheKey(intent);
85
+ const key2 = cache.buildCacheKey(intent);
86
+ expect(key1).toBe(key2);
87
+ });
88
+ it('should produce same key for different query orderings', () => {
89
+ const intent1 = {
90
+ tool: 'get_swift_pattern',
91
+ query: 'async await SwiftUI',
92
+ minQuality: 60,
93
+ sources: ['sundell'],
94
+ };
95
+ const intent2 = {
96
+ tool: 'get_swift_pattern',
97
+ query: 'SwiftUI async await',
98
+ minQuality: 60,
99
+ sources: ['sundell'],
100
+ };
101
+ expect(cache.buildCacheKey(intent1)).toBe(cache.buildCacheKey(intent2));
102
+ });
103
+ it('should produce different key for different tools', () => {
104
+ const base = { query: 'testing', minQuality: 60, sources: ['sundell'] };
105
+ const key1 = cache.buildCacheKey({ ...base, tool: 'get_swift_pattern' });
106
+ const key2 = cache.buildCacheKey({ ...base, tool: 'search_swift_content' });
107
+ expect(key1).not.toBe(key2);
108
+ });
109
+ it('should produce different key for different minQuality', () => {
110
+ const base = { tool: 'get_swift_pattern', query: 'testing', sources: ['sundell'] };
111
+ const key1 = cache.buildCacheKey({ ...base, minQuality: 60 });
112
+ const key2 = cache.buildCacheKey({ ...base, minQuality: 80 });
113
+ expect(key1).not.toBe(key2);
114
+ });
115
+ it('should produce different key for different sources', () => {
116
+ const base = { tool: 'get_swift_pattern', query: 'testing', minQuality: 60 };
117
+ const key1 = cache.buildCacheKey({ ...base, sources: ['sundell'] });
118
+ const key2 = cache.buildCacheKey({ ...base, sources: ['sundell', 'vanderlee'] });
119
+ expect(key1).not.toBe(key2);
120
+ });
121
+ it('should produce different key when requireCode differs', () => {
122
+ const base = { tool: 'search_swift_content', query: 'testing', minQuality: 60, sources: ['sundell'] };
123
+ const key1 = cache.buildCacheKey({ ...base, requireCode: false });
124
+ const key2 = cache.buildCacheKey({ ...base, requireCode: true });
125
+ expect(key1).not.toBe(key2);
126
+ });
127
+ it('should return 64-character SHA-256 hash', () => {
128
+ const key = cache.buildCacheKey({
129
+ tool: 'get_swift_pattern',
130
+ query: 'testing',
131
+ minQuality: 60,
132
+ sources: ['sundell'],
133
+ });
134
+ expect(key.length).toBe(64);
135
+ expect(/^[a-f0-9]+$/.test(key)).toBe(true);
136
+ });
137
+ });
138
+ describe('get and set', () => {
139
+ const testIntent = {
140
+ tool: 'get_swift_pattern',
141
+ query: 'SwiftUI navigation',
142
+ minQuality: 60,
143
+ sources: ['sundell', 'vanderlee'],
144
+ };
145
+ const testResult = {
146
+ patternIds: ['pattern-1', 'pattern-2'],
147
+ scores: { 'pattern-1': 95, 'pattern-2': 87 },
148
+ totalCount: 2,
149
+ };
150
+ it('should return null for non-existent key', async () => {
151
+ const result = await cache.get(testIntent);
152
+ expect(result).toBeNull();
153
+ });
154
+ it('should store and retrieve cached result', async () => {
155
+ await cache.set(testIntent, testResult);
156
+ const retrieved = await cache.get(testIntent);
157
+ expect(retrieved).not.toBeNull();
158
+ expect(retrieved?.patternIds).toEqual(testResult.patternIds);
159
+ expect(retrieved?.scores).toEqual(testResult.scores);
160
+ expect(retrieved?.totalCount).toBe(testResult.totalCount);
161
+ });
162
+ it('should include sourceFingerprint in stored result', async () => {
163
+ await cache.set(testIntent, testResult);
164
+ const retrieved = await cache.get(testIntent);
165
+ expect(retrieved?.sourceFingerprint).toBe(cache.getSourceFingerprint(testIntent.sources));
166
+ });
167
+ it('should include timestamp in stored result', async () => {
168
+ const beforeSet = Date.now();
169
+ await cache.set(testIntent, testResult);
170
+ const afterSet = Date.now();
171
+ const retrieved = await cache.get(testIntent);
172
+ expect(retrieved?.timestamp).toBeGreaterThanOrEqual(beforeSet);
173
+ expect(retrieved?.timestamp).toBeLessThanOrEqual(afterSet);
174
+ });
175
+ it('should return null when sources change (fingerprint mismatch)', async () => {
176
+ await cache.set(testIntent, testResult);
177
+ // Query with different sources
178
+ const differentSources = {
179
+ ...testIntent,
180
+ sources: ['sundell'], // Different from original
181
+ };
182
+ // Should miss due to fingerprint validation
183
+ const result = await cache.get(differentSources);
184
+ expect(result).toBeNull();
185
+ });
186
+ });
187
+ describe('getOrFetch', () => {
188
+ const testIntent = {
189
+ tool: 'get_swift_pattern',
190
+ query: 'combine reactive',
191
+ minQuality: 60,
192
+ sources: ['sundell'],
193
+ };
194
+ it('should call fetcher on cache miss', async () => {
195
+ let fetcherCalled = false;
196
+ const fetcher = async () => {
197
+ fetcherCalled = true;
198
+ return {
199
+ patternIds: ['p1'],
200
+ scores: { 'p1': 90 },
201
+ totalCount: 1,
202
+ };
203
+ };
204
+ await cache.getOrFetch(testIntent, fetcher);
205
+ expect(fetcherCalled).toBe(true);
206
+ });
207
+ it('should not call fetcher on cache hit', async () => {
208
+ // Pre-populate cache
209
+ await cache.set(testIntent, {
210
+ patternIds: ['cached'],
211
+ scores: { 'cached': 80 },
212
+ totalCount: 1,
213
+ });
214
+ let fetcherCalled = false;
215
+ const fetcher = async () => {
216
+ fetcherCalled = true;
217
+ return {
218
+ patternIds: ['fresh'],
219
+ scores: { 'fresh': 90 },
220
+ totalCount: 1,
221
+ };
222
+ };
223
+ const result = await cache.getOrFetch(testIntent, fetcher);
224
+ expect(fetcherCalled).toBe(false);
225
+ expect(result.patternIds).toEqual(['cached']);
226
+ });
227
+ it('should cache fetched results', async () => {
228
+ const fetcher = async () => ({
229
+ patternIds: ['fetched'],
230
+ scores: { 'fetched': 85 },
231
+ totalCount: 1,
232
+ });
233
+ await cache.getOrFetch(testIntent, fetcher);
234
+ // Second call should hit cache
235
+ const cached = await cache.get(testIntent);
236
+ expect(cached?.patternIds).toEqual(['fetched']);
237
+ });
238
+ // Note: Stampede prevention (concurrent request deduplication) is tested
239
+ // in src/integration/cache-behavior.test.ts with more comprehensive scenarios
240
+ });
241
+ describe('stats', () => {
242
+ const testIntent = {
243
+ tool: 'get_swift_pattern',
244
+ query: 'testing',
245
+ minQuality: 60,
246
+ sources: ['sundell'],
247
+ };
248
+ it('should track cache hits', async () => {
249
+ await cache.set(testIntent, {
250
+ patternIds: ['p1'],
251
+ scores: { 'p1': 90 },
252
+ totalCount: 1,
253
+ });
254
+ await cache.get(testIntent);
255
+ await cache.get(testIntent);
256
+ const stats = cache.getStats();
257
+ expect(stats.hits).toBe(2);
258
+ });
259
+ it('should track cache misses', async () => {
260
+ await cache.get(testIntent);
261
+ await cache.get({ ...testIntent, query: 'different' });
262
+ const stats = cache.getStats();
263
+ expect(stats.misses).toBe(2);
264
+ });
265
+ it('should calculate hit rate correctly', async () => {
266
+ await cache.set(testIntent, {
267
+ patternIds: ['p1'],
268
+ scores: { 'p1': 90 },
269
+ totalCount: 1,
270
+ });
271
+ await cache.get(testIntent); // hit
272
+ await cache.get({ ...testIntent, query: 'miss1' }); // miss
273
+ await cache.get(testIntent); // hit
274
+ await cache.get({ ...testIntent, query: 'miss2' }); // miss
275
+ const stats = cache.getStats();
276
+ expect(stats.hits).toBe(2);
277
+ expect(stats.misses).toBe(2);
278
+ expect(stats.hitRate).toBe(0.5);
279
+ });
280
+ it('should reset stats on clear', async () => {
281
+ await cache.get(testIntent); // miss
282
+ cache.clear();
283
+ const stats = cache.getStats();
284
+ expect(stats.hits).toBe(0);
285
+ expect(stats.misses).toBe(0);
286
+ expect(stats.hitRate).toBe(0);
287
+ });
288
+ });
289
+ });
290
+ //# sourceMappingURL=intent-cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-cache.test.js","sourceRoot":"","sources":["../../src/utils/intent-cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import pino from 'pino';
2
+ declare const logger: pino.Logger<never, boolean>;
3
+ export default logger;
4
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,QAAA,MAAM,MAAM,6BAKV,CAAC;AAEH,eAAe,MAAM,CAAC"}