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,158 @@
1
+ // src/utils/search.ts
2
+ // Advanced search utilities with fuzzy matching and smart stemming
3
+ import MiniSearch from 'minisearch';
4
+ import natural from 'natural';
5
+ import { normalizeTokens } from './search-terms.js';
6
+ // Porter Stemmer for English
7
+ const stemmer = natural.PorterStemmer;
8
+ // Custom tokenizer with smart hyphen handling and stemming
9
+ function tokenize(text) {
10
+ return normalizeTokens(text, (token) => stemmer.stem(token));
11
+ }
12
+ // Process query with same tokenization for consistent matching
13
+ function processQuery(query) {
14
+ return tokenize(query);
15
+ }
16
+ export class SearchIndex {
17
+ miniSearch;
18
+ documents = new Map();
19
+ constructor(fields = ['title', 'content', 'topics']) {
20
+ this.miniSearch = new MiniSearch({
21
+ fields,
22
+ storeFields: ['id'],
23
+ tokenize, // Uses our new smart tokenizer
24
+ processTerm: (term) => term, // Already processed by tokenize
25
+ searchOptions: {
26
+ boost: { title: 2, topics: 1.5, content: 1 },
27
+ fuzzy: 0.2,
28
+ prefix: true,
29
+ },
30
+ });
31
+ }
32
+ addDocuments(docs) {
33
+ // Clear existing documents
34
+ this.miniSearch.removeAll();
35
+ this.documents.clear();
36
+ // Preprocess documents for indexing
37
+ const processedDocs = docs.map(doc => ({
38
+ ...doc,
39
+ // Join topics array for indexing
40
+ topics: Array.isArray(doc.topics) ? doc.topics.join(' ') : doc.topics,
41
+ }));
42
+ // Add to MiniSearch
43
+ this.miniSearch.addAll(processedDocs);
44
+ // Store original documents for retrieval
45
+ docs.forEach(doc => this.documents.set(doc.id, doc));
46
+ }
47
+ search(query, options = {}) {
48
+ const { fuzzy = 0.2, boost = { title: 2, topics: 1.5, content: 1 }, minScore = 0, } = options;
49
+ // Get stemmed query terms for match highlighting
50
+ const queryTerms = processQuery(query);
51
+ // Search with MiniSearch
52
+ const results = this.miniSearch.search(query, {
53
+ fuzzy,
54
+ prefix: true,
55
+ boost,
56
+ combineWith: 'OR',
57
+ });
58
+ // Map results to original documents with scores
59
+ return results
60
+ .filter(result => result.score >= minScore)
61
+ .map(result => {
62
+ const doc = this.documents.get(result.id);
63
+ if (!doc)
64
+ return null;
65
+ // Find which terms matched
66
+ const matches = this.findMatches(doc, queryTerms);
67
+ return {
68
+ item: doc,
69
+ score: result.score,
70
+ matches,
71
+ };
72
+ })
73
+ .filter((r) => r !== null);
74
+ }
75
+ findMatches(doc, queryTerms) {
76
+ const matches = [];
77
+ const searchText = `${doc.title} ${doc.content} ${doc.topics.join(' ')}`.toLowerCase();
78
+ for (const term of queryTerms) {
79
+ // Check both stemmed and original
80
+ if (searchText.includes(term)) {
81
+ matches.push(term);
82
+ }
83
+ }
84
+ return [...new Set(matches)];
85
+ }
86
+ }
87
+ // Standalone search function for simple use cases
88
+ export function fuzzySearch(documents, query, options = {}) {
89
+ const index = new SearchIndex();
90
+ index.addDocuments(documents);
91
+ return index.search(query, options);
92
+ }
93
+ // Get search relevance score (combines MiniSearch score with static relevance)
94
+ export function combineScores(searchScore, staticRelevance, searchWeight = 0.6) {
95
+ // Normalize search score (MiniSearch scores can vary widely)
96
+ const normalizedSearch = Math.min(searchScore / 10, 1) * 100;
97
+ // Weighted combination
98
+ return Math.round(normalizedSearch * searchWeight +
99
+ staticRelevance * (1 - searchWeight));
100
+ }
101
+ // Suggest similar terms (for "did you mean?" functionality)
102
+ export function suggestSimilar(query, knownTerms, maxSuggestions = 3) {
103
+ const queryLower = query.toLowerCase();
104
+ // Calculate Levenshtein distance
105
+ const suggestions = knownTerms
106
+ .map(term => ({
107
+ term,
108
+ distance: natural.LevenshteinDistance(queryLower, term.toLowerCase()),
109
+ }))
110
+ .filter(({ distance }) => distance <= 3 && distance > 0)
111
+ .sort((a, b) => a.distance - b.distance)
112
+ .slice(0, maxSuggestions)
113
+ .map(({ term }) => term);
114
+ return suggestions;
115
+ }
116
+ /**
117
+ * CachedSearchIndex - Manages a SearchIndex with automatic invalidation based on document changes.
118
+ * Eliminates duplicated search caching logic across pattern sources.
119
+ */
120
+ export class CachedSearchIndex {
121
+ searchIndex = null;
122
+ indexedPatternsHash = null;
123
+ fields;
124
+ constructor(fields = ['title', 'content', 'topics']) {
125
+ this.fields = fields;
126
+ }
127
+ /**
128
+ * Search patterns with automatic index caching.
129
+ * Index is rebuilt only when patterns change (detected via hash).
130
+ */
131
+ search(patterns, query, options = {}) {
132
+ const { fuzzy = 0.2, boost = { title: 2.5, topics: 1.8, content: 1 }, } = options;
133
+ // Simple hash based on length and sorted IDs
134
+ const patternsHash = `${patterns.length}-${patterns.map(p => p.id).sort().join(',')}`;
135
+ // Rebuild index only if patterns changed
136
+ if (!this.searchIndex || this.indexedPatternsHash !== patternsHash) {
137
+ this.searchIndex = new SearchIndex(this.fields);
138
+ this.searchIndex.addDocuments(patterns);
139
+ this.indexedPatternsHash = patternsHash;
140
+ }
141
+ const results = this.searchIndex.search(query, { fuzzy, boost });
142
+ return results
143
+ .map(result => ({
144
+ ...result.item,
145
+ relevanceScore: combineScores(result.score, result.item.relevanceScore),
146
+ }))
147
+ .sort((a, b) => b.relevanceScore - a.relevanceScore);
148
+ }
149
+ /**
150
+ * Invalidate the cached index (call after fetching new patterns)
151
+ */
152
+ invalidate() {
153
+ this.searchIndex = null;
154
+ this.indexedPatternsHash = null;
155
+ }
156
+ }
157
+ export default SearchIndex;
158
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/utils/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../src/utils/search.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,199 @@
1
+ // src/utils/search.test.ts
2
+ import { describe, it, expect } from 'vitest';
3
+ import SearchIndex, { fuzzySearch, combineScores, suggestSimilar } from './search.js';
4
+ // Test documents
5
+ const testDocs = [
6
+ {
7
+ id: 'doc1',
8
+ title: 'Building async SwiftUI apps',
9
+ content: 'Learn how to use async/await with SwiftUI views and state management',
10
+ topics: ['swiftui', 'concurrency'],
11
+ },
12
+ {
13
+ id: 'doc2',
14
+ title: 'Understanding Combine framework',
15
+ content: 'A deep dive into Combine publishers and subscribers',
16
+ topics: ['combine', 'reactive'],
17
+ },
18
+ {
19
+ id: 'doc3',
20
+ title: 'Swift Testing with XCTest',
21
+ content: 'Writing unit tests and UI tests for your iOS apps using XCTest framework',
22
+ topics: ['testing', 'xctest'],
23
+ },
24
+ {
25
+ id: 'doc4',
26
+ title: 'MVVM Architecture in Swift',
27
+ content: 'Implementing the Model-View-ViewModel pattern with protocols and bindings',
28
+ topics: ['architecture', 'mvvm'],
29
+ },
30
+ {
31
+ id: 'doc5',
32
+ title: 'Core Data persistence',
33
+ content: 'Saving and fetching data with CoreData and SwiftUI integration',
34
+ topics: ['coredata', 'persistence'],
35
+ },
36
+ ];
37
+ describe('SearchIndex', () => {
38
+ describe('basic search', () => {
39
+ it('should find documents by title keywords', () => {
40
+ const index = new SearchIndex();
41
+ index.addDocuments(testDocs);
42
+ const results = index.search('SwiftUI');
43
+ expect(results.length).toBeGreaterThan(0);
44
+ expect(results.some(r => r.item.id === 'doc1')).toBe(true);
45
+ });
46
+ it('should find documents by content keywords', () => {
47
+ const index = new SearchIndex();
48
+ index.addDocuments(testDocs);
49
+ const results = index.search('publishers subscribers');
50
+ expect(results.length).toBeGreaterThan(0);
51
+ expect(results.some(r => r.item.id === 'doc2')).toBe(true);
52
+ });
53
+ it('should find documents by topic', () => {
54
+ const index = new SearchIndex();
55
+ index.addDocuments(testDocs);
56
+ const results = index.search('testing');
57
+ expect(results.length).toBeGreaterThan(0);
58
+ expect(results.some(r => r.item.id === 'doc3')).toBe(true);
59
+ });
60
+ it('should return empty array for non-matching query', () => {
61
+ const index = new SearchIndex();
62
+ index.addDocuments(testDocs);
63
+ const results = index.search('nonexistentterm12345');
64
+ expect(results.length).toBe(0);
65
+ });
66
+ });
67
+ describe('fuzzy matching', () => {
68
+ it('should find documents with slight typos', () => {
69
+ const index = new SearchIndex();
70
+ index.addDocuments(testDocs);
71
+ // "swiftui" with typo "swiftiu"
72
+ const results = index.search('swiftiu', { fuzzy: 0.3 });
73
+ expect(results.length).toBeGreaterThan(0);
74
+ });
75
+ it('should respect fuzzy threshold', () => {
76
+ const index = new SearchIndex();
77
+ index.addDocuments(testDocs);
78
+ // Very strict fuzzy - should not match typos
79
+ const strictResults = index.search('swiftiu', { fuzzy: 0 });
80
+ const lenientResults = index.search('swiftiu', { fuzzy: 0.4 });
81
+ expect(lenientResults.length).toBeGreaterThanOrEqual(strictResults.length);
82
+ });
83
+ });
84
+ describe('score filtering', () => {
85
+ it('should filter results by minimum score', () => {
86
+ const index = new SearchIndex();
87
+ index.addDocuments(testDocs);
88
+ const allResults = index.search('swift');
89
+ const filteredResults = index.search('swift', { minScore: 5 });
90
+ expect(allResults.length).toBeGreaterThanOrEqual(filteredResults.length);
91
+ });
92
+ });
93
+ describe('document management', () => {
94
+ it('should clear old documents when adding new ones', () => {
95
+ const index = new SearchIndex();
96
+ index.addDocuments(testDocs);
97
+ const newDocs = [{
98
+ id: 'new1',
99
+ title: 'New document about Kotlin',
100
+ content: 'This is about Kotlin, not Swift',
101
+ topics: ['kotlin'],
102
+ }];
103
+ index.addDocuments(newDocs);
104
+ const swiftResults = index.search('SwiftUI');
105
+ const kotlinResults = index.search('Kotlin');
106
+ expect(swiftResults.length).toBe(0);
107
+ expect(kotlinResults.length).toBe(1);
108
+ });
109
+ });
110
+ });
111
+ describe('fuzzySearch helper', () => {
112
+ it('should provide standalone fuzzy search', () => {
113
+ const results = fuzzySearch(testDocs, 'async await');
114
+ expect(results.length).toBeGreaterThan(0);
115
+ expect(results[0].item.id).toBe('doc1');
116
+ });
117
+ it('should return results with scores', () => {
118
+ const results = fuzzySearch(testDocs, 'SwiftUI');
119
+ expect(results.length).toBeGreaterThan(0);
120
+ expect(results[0]).toHaveProperty('score');
121
+ expect(results[0]).toHaveProperty('matches');
122
+ });
123
+ });
124
+ describe('combineScores', () => {
125
+ it('should combine search and static relevance scores', () => {
126
+ const combined = combineScores(10, 80);
127
+ expect(combined).toBeGreaterThan(0);
128
+ expect(combined).toBeLessThanOrEqual(100);
129
+ });
130
+ it('should respect search weight parameter', () => {
131
+ const highSearchWeight = combineScores(10, 50, 0.9);
132
+ const lowSearchWeight = combineScores(10, 50, 0.1);
133
+ // With high search weight, search score matters more
134
+ // With low search weight, static relevance matters more
135
+ expect(highSearchWeight).not.toBe(lowSearchWeight);
136
+ });
137
+ it('should cap scores at 100', () => {
138
+ const combined = combineScores(100, 100, 0.5);
139
+ expect(combined).toBeLessThanOrEqual(100);
140
+ });
141
+ it('should handle zero scores', () => {
142
+ const combined = combineScores(0, 0);
143
+ expect(combined).toBe(0);
144
+ });
145
+ });
146
+ describe('suggestSimilar', () => {
147
+ const knownTerms = ['swiftui', 'combine', 'async', 'await', 'protocol', 'struct'];
148
+ it('should suggest similar terms for typos', () => {
149
+ const suggestions = suggestSimilar('swiftiu', knownTerms);
150
+ expect(suggestions).toContain('swiftui');
151
+ });
152
+ it('should not suggest exact matches', () => {
153
+ const suggestions = suggestSimilar('swiftui', knownTerms);
154
+ expect(suggestions).not.toContain('swiftui');
155
+ });
156
+ it('should respect max suggestions limit', () => {
157
+ const suggestions = suggestSimilar('s', knownTerms, 2);
158
+ expect(suggestions.length).toBeLessThanOrEqual(2);
159
+ });
160
+ it('should return empty array for very different terms', () => {
161
+ const suggestions = suggestSimilar('xyzabc123', knownTerms);
162
+ expect(suggestions.length).toBe(0);
163
+ });
164
+ it('should sort by similarity (Levenshtein distance)', () => {
165
+ const suggestions = suggestSimilar('async', ['asyncc', 'asyncxx', 'asyn']);
166
+ // 'asyn' has distance 1, 'asyncc' has distance 1, 'asyncxx' has distance 2
167
+ expect(suggestions.length).toBeGreaterThan(0);
168
+ });
169
+ });
170
+ describe('tokenization', () => {
171
+ it('should preserve Swift-specific terms without stemming', () => {
172
+ const index = new SearchIndex();
173
+ const docs = [{
174
+ id: 'test1',
175
+ title: 'SwiftUI and Combine',
176
+ content: 'Using async await with SwiftUI',
177
+ topics: ['swiftui', 'combine'],
178
+ }];
179
+ index.addDocuments(docs);
180
+ // These terms should match exactly without stemming issues
181
+ const swiftuiResults = index.search('swiftui');
182
+ const asyncResults = index.search('async');
183
+ expect(swiftuiResults.length).toBe(1);
184
+ expect(asyncResults.length).toBe(1);
185
+ });
186
+ it('should handle hyphenated terms', () => {
187
+ const index = new SearchIndex();
188
+ const docs = [{
189
+ id: 'test1',
190
+ title: 'Async-await patterns',
191
+ content: 'Learn about async-await in Swift',
192
+ topics: ['concurrency'],
193
+ }];
194
+ index.addDocuments(docs);
195
+ const results = index.search('async await');
196
+ expect(results.length).toBe(1);
197
+ });
198
+ });
199
+ //# sourceMappingURL=search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../src/utils/search.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { BasePattern } from '../sources/free/rssPatternSource.js';
2
+ export interface SemanticRecallConfig {
3
+ enabled: boolean;
4
+ minLexicalScore: number;
5
+ minRelevanceScore: number;
6
+ }
7
+ export declare const DEFAULT_CONFIG: SemanticRecallConfig;
8
+ export declare class SemanticRecallIndex {
9
+ private indexedMap;
10
+ private cache;
11
+ private pipeline;
12
+ private config;
13
+ constructor(config?: SemanticRecallConfig);
14
+ /**
15
+ * Lazy-load the transformer pipeline
16
+ */
17
+ private getEmbeddingPipeline;
18
+ /**
19
+ * Generate embedding for text
20
+ */
21
+ private embed;
22
+ /**
23
+ * Index patterns for semantic search.
24
+ * Filters patterns by minRelevanceScore and caches embeddings.
25
+ * Uses incremental indexing - only processes new/changed patterns.
26
+ */
27
+ index(patterns: BasePattern[]): Promise<void>;
28
+ /**
29
+ * Search indexed patterns by semantic similarity.
30
+ * Returns top-K patterns sorted by cosine similarity.
31
+ */
32
+ search(query: string, limit: number): Promise<BasePattern[]>;
33
+ /**
34
+ * Get the number of indexed patterns (for testing/debugging)
35
+ */
36
+ get size(): number;
37
+ }
38
+ //# sourceMappingURL=semantic-recall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-recall.d.ts","sourceRoot":"","sources":["../../src/utils/semantic-recall.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc,EAAE,oBAI5B,CAAC;AA4BF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,GAAE,oBAAqC;IAKzD;;OAEG;YACW,oBAAoB;IASlC;;OAEG;YACW,KAAK;IAMnB;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyDnD;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAsBlE;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -0,0 +1,134 @@
1
+ // src/utils/semantic-recall.ts
2
+ // Semantic recall fallback for lexical search using embeddings
3
+ import { createHash } from 'crypto';
4
+ import { FileCache } from './cache.js';
5
+ export const DEFAULT_CONFIG = {
6
+ enabled: false,
7
+ minLexicalScore: 0.35,
8
+ minRelevanceScore: 70,
9
+ };
10
+ /**
11
+ * Extract indexable content from pattern (title + excerpt only, not full content)
12
+ */
13
+ function extractIndexableContent(pattern) {
14
+ const title = pattern.title || '';
15
+ const excerpt = pattern.excerpt || pattern.content?.substring(0, 500) || '';
16
+ // Concatenate title and excerpt for embedding
17
+ return `${title} ${excerpt}`.trim();
18
+ }
19
+ /**
20
+ * Generate content hash for cache key
21
+ * Uses extractIndexableContent to ensure hash matches embedding input
22
+ */
23
+ function getContentHash(pattern) {
24
+ const content = extractIndexableContent(pattern);
25
+ return createHash('sha256').update(content).digest('hex').substring(0, 16);
26
+ }
27
+ export class SemanticRecallIndex {
28
+ indexedMap = new Map();
29
+ cache;
30
+ pipeline = null; // Lazy-loaded transformer pipeline
31
+ config;
32
+ constructor(config = DEFAULT_CONFIG) {
33
+ this.config = config;
34
+ this.cache = new FileCache('semantic-embeddings');
35
+ }
36
+ /**
37
+ * Lazy-load the transformer pipeline
38
+ */
39
+ async getEmbeddingPipeline() {
40
+ if (!this.pipeline) {
41
+ const { pipeline, env } = await import('@xenova/transformers');
42
+ env.allowLocalModels = false; // Use remote models only
43
+ this.pipeline = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
44
+ }
45
+ return this.pipeline;
46
+ }
47
+ /**
48
+ * Generate embedding for text
49
+ */
50
+ async embed(text) {
51
+ const pipe = await this.getEmbeddingPipeline();
52
+ const output = await pipe(text, { pooling: 'mean', normalize: true });
53
+ return output.data;
54
+ }
55
+ /**
56
+ * Index patterns for semantic search.
57
+ * Filters patterns by minRelevanceScore and caches embeddings.
58
+ * Uses incremental indexing - only processes new/changed patterns.
59
+ */
60
+ async index(patterns) {
61
+ // Filter patterns by relevance score
62
+ const highQualityPatterns = patterns.filter(p => p.relevanceScore >= this.config.minRelevanceScore);
63
+ // Build set of current cache keys to track what should remain
64
+ const currentKeys = new Set();
65
+ // Index each pattern (incremental - skip unchanged patterns)
66
+ for (const pattern of highQualityPatterns) {
67
+ const contentHash = getContentHash(pattern);
68
+ const cacheKey = `embedding::${pattern.id}::${contentHash}`;
69
+ currentKeys.add(cacheKey);
70
+ // Skip if already indexed with same content hash
71
+ if (this.indexedMap.has(cacheKey)) {
72
+ // Update pattern reference in case metadata changed (but content hash same)
73
+ const existing = this.indexedMap.get(cacheKey);
74
+ existing.pattern = pattern;
75
+ continue;
76
+ }
77
+ // Try to load from file cache
78
+ const embedding = await this.cache.get(cacheKey);
79
+ if (embedding) {
80
+ // File cache hit - use cached embedding
81
+ this.indexedMap.set(cacheKey, {
82
+ pattern,
83
+ embedding: new Float32Array(embedding),
84
+ cacheKey,
85
+ });
86
+ }
87
+ else {
88
+ // Cache miss - compute embedding
89
+ const content = extractIndexableContent(pattern);
90
+ const embeddingArray = await this.embed(content);
91
+ // Store in file cache (convert Float32Array to regular array for JSON serialization)
92
+ await this.cache.set(cacheKey, Array.from(embeddingArray), 86400 * 7); // 7 days TTL
93
+ this.indexedMap.set(cacheKey, {
94
+ pattern,
95
+ embedding: embeddingArray,
96
+ cacheKey,
97
+ });
98
+ }
99
+ }
100
+ // Remove patterns no longer in the input set
101
+ for (const key of this.indexedMap.keys()) {
102
+ if (!currentKeys.has(key)) {
103
+ this.indexedMap.delete(key);
104
+ }
105
+ }
106
+ }
107
+ /**
108
+ * Search indexed patterns by semantic similarity.
109
+ * Returns top-K patterns sorted by cosine similarity.
110
+ */
111
+ async search(query, limit) {
112
+ if (this.indexedMap.size === 0) {
113
+ return [];
114
+ }
115
+ // Generate query embedding
116
+ const queryEmbedding = await this.embed(query);
117
+ // Calculate cosine similarity for each indexed pattern
118
+ const { similarity } = await import('ml-distance');
119
+ const scored = Array.from(this.indexedMap.values()).map(({ pattern, embedding }) => ({
120
+ pattern,
121
+ similarity: similarity.cosine(queryEmbedding, embedding),
122
+ }));
123
+ // Sort by similarity descending and return top-K
124
+ scored.sort((a, b) => b.similarity - a.similarity);
125
+ return scored.slice(0, limit).map(s => s.pattern);
126
+ }
127
+ /**
128
+ * Get the number of indexed patterns (for testing/debugging)
129
+ */
130
+ get size() {
131
+ return this.indexedMap.size;
132
+ }
133
+ }
134
+ //# sourceMappingURL=semantic-recall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-recall.js","sourceRoot":"","sources":["../../src/utils/semantic-recall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=semantic-recall.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-recall.test.d.ts","sourceRoot":"","sources":["../../src/utils/semantic-recall.test.ts"],"names":[],"mappings":""}