@ssmeo/mcp-local-rag 0.18.6

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.de.md +441 -0
  3. package/README.es.md +441 -0
  4. package/README.fr.md +441 -0
  5. package/README.md +530 -0
  6. package/README.pt-BR.md +441 -0
  7. package/README.zh-CN.md +441 -0
  8. package/dist/bin/install-skills.d.ts +19 -0
  9. package/dist/bin/install-skills.d.ts.map +1 -0
  10. package/dist/bin/install-skills.js +218 -0
  11. package/dist/bin/install-skills.js.map +1 -0
  12. package/dist/chunker/index.d.ts +24 -0
  13. package/dist/chunker/index.d.ts.map +1 -0
  14. package/dist/chunker/index.js +2 -0
  15. package/dist/chunker/index.js.map +1 -0
  16. package/dist/chunker/semantic-chunker.d.ts +96 -0
  17. package/dist/chunker/semantic-chunker.d.ts.map +1 -0
  18. package/dist/chunker/semantic-chunker.js +362 -0
  19. package/dist/chunker/semantic-chunker.js.map +1 -0
  20. package/dist/chunker/sentence-splitter.d.ts +32 -0
  21. package/dist/chunker/sentence-splitter.d.ts.map +1 -0
  22. package/dist/chunker/sentence-splitter.js +231 -0
  23. package/dist/chunker/sentence-splitter.js.map +1 -0
  24. package/dist/chunker/token-containment.d.ts +39 -0
  25. package/dist/chunker/token-containment.d.ts.map +1 -0
  26. package/dist/chunker/token-containment.js +83 -0
  27. package/dist/chunker/token-containment.js.map +1 -0
  28. package/dist/cli/common.d.ts +34 -0
  29. package/dist/cli/common.d.ts.map +1 -0
  30. package/dist/cli/common.js +121 -0
  31. package/dist/cli/common.js.map +1 -0
  32. package/dist/cli/delete.d.ts +3 -0
  33. package/dist/cli/delete.d.ts.map +1 -0
  34. package/dist/cli/delete.js +169 -0
  35. package/dist/cli/delete.js.map +1 -0
  36. package/dist/cli/file-collection.d.ts +2 -0
  37. package/dist/cli/file-collection.d.ts.map +1 -0
  38. package/dist/cli/file-collection.js +53 -0
  39. package/dist/cli/file-collection.js.map +1 -0
  40. package/dist/cli/ingest.d.ts +69 -0
  41. package/dist/cli/ingest.d.ts.map +1 -0
  42. package/dist/cli/ingest.js +323 -0
  43. package/dist/cli/ingest.js.map +1 -0
  44. package/dist/cli/list.d.ts +27 -0
  45. package/dist/cli/list.d.ts.map +1 -0
  46. package/dist/cli/list.js +207 -0
  47. package/dist/cli/list.js.map +1 -0
  48. package/dist/cli/options.d.ts +89 -0
  49. package/dist/cli/options.d.ts.map +1 -0
  50. package/dist/cli/options.js +244 -0
  51. package/dist/cli/options.js.map +1 -0
  52. package/dist/cli/query.d.ts +17 -0
  53. package/dist/cli/query.d.ts.map +1 -0
  54. package/dist/cli/query.js +194 -0
  55. package/dist/cli/query.js.map +1 -0
  56. package/dist/cli/read-neighbors.d.ts +3 -0
  57. package/dist/cli/read-neighbors.d.ts.map +1 -0
  58. package/dist/cli/read-neighbors.js +192 -0
  59. package/dist/cli/read-neighbors.js.map +1 -0
  60. package/dist/cli/status.d.ts +6 -0
  61. package/dist/cli/status.d.ts.map +1 -0
  62. package/dist/cli/status.js +78 -0
  63. package/dist/cli/status.js.map +1 -0
  64. package/dist/cli/sync.d.ts +6 -0
  65. package/dist/cli/sync.d.ts.map +1 -0
  66. package/dist/cli/sync.js +271 -0
  67. package/dist/cli/sync.js.map +1 -0
  68. package/dist/cli-main.d.ts +9 -0
  69. package/dist/cli-main.d.ts.map +1 -0
  70. package/dist/cli-main.js +60 -0
  71. package/dist/cli-main.js.map +1 -0
  72. package/dist/embedder/index.d.ts +143 -0
  73. package/dist/embedder/index.d.ts.map +1 -0
  74. package/dist/embedder/index.js +429 -0
  75. package/dist/embedder/index.js.map +1 -0
  76. package/dist/embedder/remote.d.ts +51 -0
  77. package/dist/embedder/remote.d.ts.map +1 -0
  78. package/dist/embedder/remote.js +182 -0
  79. package/dist/embedder/remote.js.map +1 -0
  80. package/dist/features/list.d.ts +37 -0
  81. package/dist/features/list.d.ts.map +1 -0
  82. package/dist/features/list.js +41 -0
  83. package/dist/features/list.js.map +1 -0
  84. package/dist/features/sync.d.ts +219 -0
  85. package/dist/features/sync.d.ts.map +1 -0
  86. package/dist/features/sync.js +461 -0
  87. package/dist/features/sync.js.map +1 -0
  88. package/dist/index.d.ts +3 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +56 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/ingest/compute.d.ts +63 -0
  93. package/dist/ingest/compute.d.ts.map +1 -0
  94. package/dist/ingest/compute.js +161 -0
  95. package/dist/ingest/compute.js.map +1 -0
  96. package/dist/ingest/file.d.ts +40 -0
  97. package/dist/ingest/file.d.ts.map +1 -0
  98. package/dist/ingest/file.js +74 -0
  99. package/dist/ingest/file.js.map +1 -0
  100. package/dist/ingest/visual.d.ts +52 -0
  101. package/dist/ingest/visual.d.ts.map +1 -0
  102. package/dist/ingest/visual.js +294 -0
  103. package/dist/ingest/visual.js.map +1 -0
  104. package/dist/parser/docx-parser.d.ts +12 -0
  105. package/dist/parser/docx-parser.d.ts.map +1 -0
  106. package/dist/parser/docx-parser.js +375 -0
  107. package/dist/parser/docx-parser.js.map +1 -0
  108. package/dist/parser/html-parser.d.ts +16 -0
  109. package/dist/parser/html-parser.d.ts.map +1 -0
  110. package/dist/parser/html-parser.js +119 -0
  111. package/dist/parser/html-parser.js.map +1 -0
  112. package/dist/parser/index.d.ts +125 -0
  113. package/dist/parser/index.d.ts.map +1 -0
  114. package/dist/parser/index.js +364 -0
  115. package/dist/parser/index.js.map +1 -0
  116. package/dist/parser/pdf-extract.d.ts +49 -0
  117. package/dist/parser/pdf-extract.d.ts.map +1 -0
  118. package/dist/parser/pdf-extract.js +114 -0
  119. package/dist/parser/pdf-extract.js.map +1 -0
  120. package/dist/parser/pdf-filter.d.ts +91 -0
  121. package/dist/parser/pdf-filter.d.ts.map +1 -0
  122. package/dist/parser/pdf-filter.js +522 -0
  123. package/dist/parser/pdf-filter.js.map +1 -0
  124. package/dist/parser/title-extractor.d.ts +28 -0
  125. package/dist/parser/title-extractor.d.ts.map +1 -0
  126. package/dist/parser/title-extractor.js +105 -0
  127. package/dist/parser/title-extractor.js.map +1 -0
  128. package/dist/pdf-visual/captioner.d.ts +11 -0
  129. package/dist/pdf-visual/captioner.d.ts.map +1 -0
  130. package/dist/pdf-visual/captioner.js +48 -0
  131. package/dist/pdf-visual/captioner.js.map +1 -0
  132. package/dist/pdf-visual/captioners/fast.d.ts +7 -0
  133. package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
  134. package/dist/pdf-visual/captioners/fast.js +108 -0
  135. package/dist/pdf-visual/captioners/fast.js.map +1 -0
  136. package/dist/pdf-visual/captioners/quality.d.ts +7 -0
  137. package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
  138. package/dist/pdf-visual/captioners/quality.js +101 -0
  139. package/dist/pdf-visual/captioners/quality.js.map +1 -0
  140. package/dist/pdf-visual/captioners/shared.d.ts +81 -0
  141. package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
  142. package/dist/pdf-visual/captioners/shared.js +156 -0
  143. package/dist/pdf-visual/captioners/shared.js.map +1 -0
  144. package/dist/pdf-visual/detector.d.ts +9 -0
  145. package/dist/pdf-visual/detector.d.ts.map +1 -0
  146. package/dist/pdf-visual/detector.js +269 -0
  147. package/dist/pdf-visual/detector.js.map +1 -0
  148. package/dist/pdf-visual/index.d.ts +13 -0
  149. package/dist/pdf-visual/index.d.ts.map +1 -0
  150. package/dist/pdf-visual/index.js +53 -0
  151. package/dist/pdf-visual/index.js.map +1 -0
  152. package/dist/pdf-visual/renderer.d.ts +9 -0
  153. package/dist/pdf-visual/renderer.d.ts.map +1 -0
  154. package/dist/pdf-visual/renderer.js +186 -0
  155. package/dist/pdf-visual/renderer.js.map +1 -0
  156. package/dist/pdf-visual/types.d.ts +53 -0
  157. package/dist/pdf-visual/types.d.ts.map +1 -0
  158. package/dist/pdf-visual/types.js +17 -0
  159. package/dist/pdf-visual/types.js.map +1 -0
  160. package/dist/server/error-utils.d.ts +63 -0
  161. package/dist/server/error-utils.d.ts.map +1 -0
  162. package/dist/server/error-utils.js +124 -0
  163. package/dist/server/error-utils.js.map +1 -0
  164. package/dist/server/index.d.ts +216 -0
  165. package/dist/server/index.d.ts.map +1 -0
  166. package/dist/server/index.js +1068 -0
  167. package/dist/server/index.js.map +1 -0
  168. package/dist/server/list-scanner.d.ts +30 -0
  169. package/dist/server/list-scanner.d.ts.map +1 -0
  170. package/dist/server/list-scanner.js +50 -0
  171. package/dist/server/list-scanner.js.map +1 -0
  172. package/dist/server/tool-definitions.d.ts +8 -0
  173. package/dist/server/tool-definitions.d.ts.map +1 -0
  174. package/dist/server/tool-definitions.js +181 -0
  175. package/dist/server/tool-definitions.js.map +1 -0
  176. package/dist/server/tool-input.d.ts +37 -0
  177. package/dist/server/tool-input.d.ts.map +1 -0
  178. package/dist/server/tool-input.js +211 -0
  179. package/dist/server/tool-input.js.map +1 -0
  180. package/dist/server/types.d.ts +307 -0
  181. package/dist/server/types.d.ts.map +1 -0
  182. package/dist/server/types.js +3 -0
  183. package/dist/server/types.js.map +1 -0
  184. package/dist/server-main.d.ts +40 -0
  185. package/dist/server-main.d.ts.map +1 -0
  186. package/dist/server-main.js +254 -0
  187. package/dist/server-main.js.map +1 -0
  188. package/dist/utils/base-dirs.d.ts +145 -0
  189. package/dist/utils/base-dirs.d.ts.map +1 -0
  190. package/dist/utils/base-dirs.js +344 -0
  191. package/dist/utils/base-dirs.js.map +1 -0
  192. package/dist/utils/errors.d.ts +32 -0
  193. package/dist/utils/errors.d.ts.map +1 -0
  194. package/dist/utils/errors.js +61 -0
  195. package/dist/utils/errors.js.map +1 -0
  196. package/dist/utils/limits.d.ts +26 -0
  197. package/dist/utils/limits.d.ts.map +1 -0
  198. package/dist/utils/limits.js +28 -0
  199. package/dist/utils/limits.js.map +1 -0
  200. package/dist/utils/list-sources.d.ts +38 -0
  201. package/dist/utils/list-sources.d.ts.map +1 -0
  202. package/dist/utils/list-sources.js +40 -0
  203. package/dist/utils/list-sources.js.map +1 -0
  204. package/dist/utils/raw-data-utils.d.ts +76 -0
  205. package/dist/utils/raw-data-utils.d.ts.map +1 -0
  206. package/dist/utils/raw-data-utils.js +202 -0
  207. package/dist/utils/raw-data-utils.js.map +1 -0
  208. package/dist/utils/scan.d.ts +114 -0
  209. package/dist/utils/scan.d.ts.map +1 -0
  210. package/dist/utils/scan.js +209 -0
  211. package/dist/utils/scan.js.map +1 -0
  212. package/dist/utils/scope-match.d.ts +38 -0
  213. package/dist/utils/scope-match.d.ts.map +1 -0
  214. package/dist/utils/scope-match.js +86 -0
  215. package/dist/utils/scope-match.js.map +1 -0
  216. package/dist/utils/sensitive-path.d.ts +9 -0
  217. package/dist/utils/sensitive-path.d.ts.map +1 -0
  218. package/dist/utils/sensitive-path.js +78 -0
  219. package/dist/utils/sensitive-path.js.map +1 -0
  220. package/dist/utils/sync-path-key.d.ts +14 -0
  221. package/dist/utils/sync-path-key.d.ts.map +1 -0
  222. package/dist/utils/sync-path-key.js +27 -0
  223. package/dist/utils/sync-path-key.js.map +1 -0
  224. package/dist/utils/type-guards.d.ts +18 -0
  225. package/dist/utils/type-guards.d.ts.map +1 -0
  226. package/dist/utils/type-guards.js +34 -0
  227. package/dist/utils/type-guards.js.map +1 -0
  228. package/dist/utils/visual-profile.d.ts +10 -0
  229. package/dist/utils/visual-profile.d.ts.map +1 -0
  230. package/dist/utils/visual-profile.js +15 -0
  231. package/dist/utils/visual-profile.js.map +1 -0
  232. package/dist/vectordb/index.d.ts +132 -0
  233. package/dist/vectordb/index.d.ts.map +1 -0
  234. package/dist/vectordb/index.js +617 -0
  235. package/dist/vectordb/index.js.map +1 -0
  236. package/dist/vectordb/search-filters.d.ts +15 -0
  237. package/dist/vectordb/search-filters.d.ts.map +1 -0
  238. package/dist/vectordb/search-filters.js +129 -0
  239. package/dist/vectordb/search-filters.js.map +1 -0
  240. package/dist/vectordb/types.d.ts +194 -0
  241. package/dist/vectordb/types.d.ts.map +1 -0
  242. package/dist/vectordb/types.js +237 -0
  243. package/dist/vectordb/types.js.map +1 -0
  244. package/package.json +108 -0
  245. package/skills/mcp-local-rag/SKILL.md +234 -0
  246. package/skills/mcp-local-rag/references/cli-reference.md +190 -0
  247. package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
@@ -0,0 +1,522 @@
1
+ // PDF Header/Footer Filter
2
+ // - Detects and removes repeating patterns across pages
3
+ // - Semantic similarity-based header/footer detection (sentence-level)
4
+ import { splitIntoSentences } from '../chunker/sentence-splitter.js';
5
+ function buildPageLayout(pageNum, items) {
6
+ let rawText = '';
7
+ let previousItem;
8
+ const rawFragments = [];
9
+ const fragmentCounts = new Map();
10
+ const orderedItems = [...items].sort((left, right) => Math.round(right.y) - Math.round(left.y) || left.x - right.x);
11
+ for (let itemIndex = 0; itemIndex < orderedItems.length; itemIndex++) {
12
+ const item = orderedItems[itemIndex];
13
+ if (!item || item.text.trim().length === 0) {
14
+ continue;
15
+ }
16
+ if (previousItem) {
17
+ rawText += Math.round(previousItem.y) === Math.round(item.y) ? ' ' : '\n';
18
+ }
19
+ const rawStart = rawText.length;
20
+ rawText += item.text;
21
+ const rawEnd = rawText.length;
22
+ const blockOrdinal = item.blockOrdinal ?? 0;
23
+ const lineOrdinal = item.lineOrdinal ?? itemIndex;
24
+ const lineKey = `${blockOrdinal}:${lineOrdinal}`;
25
+ const fragmentOrdinal = fragmentCounts.get(lineKey) ?? 0;
26
+ fragmentCounts.set(lineKey, fragmentOrdinal + 1);
27
+ rawFragments.push({
28
+ pageNum,
29
+ blockOrdinal,
30
+ lineOrdinal,
31
+ fragmentOrdinal,
32
+ bbox: item.bbox ?? [item.x, item.y, item.x, item.y],
33
+ rawStart,
34
+ rawEnd,
35
+ });
36
+ previousItem = item;
37
+ }
38
+ return trimToPageText(rawText, rawFragments);
39
+ }
40
+ /**
41
+ * Trim the page's raw text and rebase every fragment onto it, dropping any
42
+ * fragment that consisted only of the trimmed whitespace.
43
+ */
44
+ function trimToPageText(rawText, rawFragments) {
45
+ const leadingWhitespace = rawText.length - rawText.trimStart().length;
46
+ const trailingBoundary = rawText.trimEnd().length;
47
+ const text = rawText.slice(leadingWhitespace, trailingBoundary);
48
+ const textFragments = [];
49
+ for (const fragment of rawFragments) {
50
+ const clippedStart = Math.max(fragment.rawStart, leadingWhitespace);
51
+ const clippedEnd = Math.min(fragment.rawEnd, trailingBoundary);
52
+ if (clippedStart >= clippedEnd) {
53
+ continue;
54
+ }
55
+ const pageTextStart = clippedStart - leadingWhitespace;
56
+ const pageTextEnd = clippedEnd - leadingWhitespace;
57
+ textFragments.push({
58
+ pageNum: fragment.pageNum,
59
+ blockOrdinal: fragment.blockOrdinal,
60
+ lineOrdinal: fragment.lineOrdinal,
61
+ fragmentOrdinal: fragment.fragmentOrdinal,
62
+ bbox: fragment.bbox,
63
+ text: text.slice(pageTextStart, pageTextEnd),
64
+ pageTextStart,
65
+ pageTextEnd,
66
+ });
67
+ }
68
+ return { text, textFragments };
69
+ }
70
+ function buildSentenceLayout(pageNum, sentences, items) {
71
+ let text = '';
72
+ const textFragments = [];
73
+ for (const sentence of sentences) {
74
+ if (text) {
75
+ text += ' ';
76
+ }
77
+ const start = text.length;
78
+ text += sentence.text;
79
+ const matchingItems = items.filter((item) => Math.round(item.y) === Math.round(sentence.y));
80
+ const first = matchingItems[0];
81
+ const boxes = matchingItems.map((item) => item.bbox ?? [item.x, item.y, item.x, item.y]);
82
+ const bbox = boxes.length
83
+ ? [
84
+ Math.min(...boxes.map((box) => box[0])),
85
+ Math.min(...boxes.map((box) => box[1])),
86
+ Math.max(...boxes.map((box) => box[2])),
87
+ Math.max(...boxes.map((box) => box[3])),
88
+ ]
89
+ : [0, 0, 0, 0];
90
+ textFragments.push({
91
+ pageNum,
92
+ blockOrdinal: first?.blockOrdinal ?? 0,
93
+ lineOrdinal: first?.lineOrdinal ?? textFragments.length,
94
+ fragmentOrdinal: 0,
95
+ bbox,
96
+ text: sentence.text,
97
+ pageTextStart: start,
98
+ pageTextEnd: text.length,
99
+ });
100
+ }
101
+ return { text, textFragments };
102
+ }
103
+ function joinPageItems(items) {
104
+ return buildPageLayout(0, items).text;
105
+ }
106
+ /** Join filtered pages into one text. */
107
+ export function joinFilteredPages(pages) {
108
+ return pages
109
+ .map((page) => joinPageItems(page.items))
110
+ .filter((text) => text.length > 0)
111
+ .join('\n\n');
112
+ }
113
+ /**
114
+ * Split page items into sentences, each mapped to the Y of its first item, and
115
+ * merged when they share a Y.
116
+ */
117
+ function splitItemsIntoSentencesWithY(items) {
118
+ if (items.length === 0) {
119
+ return [];
120
+ }
121
+ // Sort items by Y descending, then X ascending (reading order)
122
+ const sortedItems = [...items].sort((a, b) => {
123
+ const yDiff = b.y - a.y;
124
+ if (Math.abs(yDiff) > 1) {
125
+ return yDiff;
126
+ }
127
+ return a.x - b.x;
128
+ });
129
+ // Build text and track character positions to item mapping
130
+ const charToItem = [];
131
+ let fullText = '';
132
+ let prevY = null;
133
+ for (const item of sortedItems) {
134
+ // Insert newline when Y coordinate changes (different line)
135
+ // This matches joinPageItems behavior: same Y = space, different Y = newline
136
+ if (prevY !== null && Math.abs(prevY - item.y) > 1) {
137
+ fullText = `${fullText.trimEnd()}\n`;
138
+ }
139
+ charToItem.push({ start: fullText.length, item });
140
+ fullText += `${item.text} `;
141
+ prevY = item.y;
142
+ }
143
+ // Split into sentences
144
+ const sentences = splitIntoSentences(fullText);
145
+ // Map each sentence to Y coordinate of its first character's item
146
+ const sentencesWithY = [];
147
+ let searchStart = 0;
148
+ for (const sentence of sentences) {
149
+ // Find where this sentence starts in fullText
150
+ const sentenceStart = fullText.indexOf(sentence.trim(), searchStart);
151
+ // Benign skip (not error masking): this builds the Y-coordinate map used
152
+ // only for header/footer boundary detection. A miss means this sentence
153
+ // is omitted from boundary detection — it does NOT drop the sentence from
154
+ // the document body (that text comes from `fullText`). Misses are expected
155
+ // when `splitIntoSentences` normalizes whitespace differently than the
156
+ // reconstructed `fullText`, so logging here would be noise, not signal.
157
+ if (sentenceStart === -1) {
158
+ continue;
159
+ }
160
+ // Find the item that contains this position
161
+ let firstItemY = sortedItems[0]?.y ?? 0;
162
+ for (let i = charToItem.length - 1; i >= 0; i--) {
163
+ const entry = charToItem[i];
164
+ if (entry && entry.start <= sentenceStart) {
165
+ firstItemY = Math.round(entry.item.y);
166
+ break;
167
+ }
168
+ }
169
+ sentencesWithY.push({ text: sentence, y: firstItemY });
170
+ searchStart = sentenceStart + sentence.length;
171
+ }
172
+ // Merge sentences with same Y coordinate
173
+ return mergeSentencesByY(sentencesWithY);
174
+ }
175
+ /** Sentences sharing a Y coordinate are one sentence. */
176
+ function mergeSentencesByY(sentences) {
177
+ if (sentences.length === 0) {
178
+ return [];
179
+ }
180
+ const merged = [];
181
+ let current = null;
182
+ for (const sentence of sentences) {
183
+ if (current === null) {
184
+ current = { ...sentence };
185
+ }
186
+ else if (current.y === sentence.y) {
187
+ // Same Y: merge text
188
+ current.text += ` ${sentence.text}`;
189
+ }
190
+ else {
191
+ // Different Y: push current and start new
192
+ merged.push(current);
193
+ current = { ...sentence };
194
+ }
195
+ }
196
+ if (current !== null) {
197
+ merged.push(current);
198
+ }
199
+ return merged;
200
+ }
201
+ // ============================================
202
+ // Sentence-Level Header/Footer Detection
203
+ // ============================================
204
+ /**
205
+ * Calculate cosine similarity between two vectors
206
+ */
207
+ function cosineSimilarity(vec1, vec2) {
208
+ if (vec1.length !== vec2.length || vec1.length === 0) {
209
+ return 0;
210
+ }
211
+ let dotProduct = 0;
212
+ let norm1 = 0;
213
+ let norm2 = 0;
214
+ for (let i = 0; i < vec1.length; i++) {
215
+ const v1 = vec1[i] ?? 0;
216
+ const v2 = vec2[i] ?? 0;
217
+ dotProduct += v1 * v2;
218
+ norm1 += v1 * v1;
219
+ norm2 += v2 * v2;
220
+ }
221
+ const denominator = Math.sqrt(norm1) * Math.sqrt(norm2);
222
+ if (denominator === 0) {
223
+ return 0;
224
+ }
225
+ return dotProduct / denominator;
226
+ }
227
+ /**
228
+ * Median pairwise similarity — median rather than mean so one page with
229
+ * different header content (a chapter title change) cannot drag it down.
230
+ */
231
+ function medianPairwiseSimilarity(embeddings) {
232
+ if (embeddings.length < 2) {
233
+ return 1.0;
234
+ }
235
+ const similarities = [];
236
+ for (let i = 0; i < embeddings.length; i++) {
237
+ for (let j = i + 1; j < embeddings.length; j++) {
238
+ const embI = embeddings[i];
239
+ const embJ = embeddings[j];
240
+ if (embI && embJ) {
241
+ similarities.push(cosineSimilarity(embI, embJ));
242
+ }
243
+ }
244
+ }
245
+ if (similarities.length === 0) {
246
+ return 0;
247
+ }
248
+ // Sort and find median
249
+ similarities.sort((a, b) => a - b);
250
+ const mid = Math.floor(similarities.length / 2);
251
+ if (similarities.length % 2 === 0) {
252
+ // Even: average of two middle values
253
+ return ((similarities[mid - 1] ?? 0) + (similarities[mid] ?? 0)) / 2;
254
+ }
255
+ // Odd: middle value
256
+ return similarities[mid] ?? 0;
257
+ }
258
+ /** The sentence at the requested edge of a page's sampled sentences. */
259
+ function sentenceAtEdge(sentences, edge) {
260
+ if (edge === 'first') {
261
+ return sentences[0];
262
+ }
263
+ return sentences.length > 1 ? sentences.at(-1) : undefined;
264
+ }
265
+ /**
266
+ * Sample pages from the center of the document
267
+ *
268
+ * Center pages are guaranteed to be content (not cover, TOC, or index).
269
+ */
270
+ function sampleCenterPages(pages, sampleSize) {
271
+ const centerIndex = Math.floor(pages.length / 2);
272
+ const halfSample = Math.floor(sampleSize / 2);
273
+ const startIndex = Math.max(0, centerIndex - halfSample);
274
+ const endIndex = Math.min(pages.length, startIndex + sampleSize);
275
+ return pages.slice(startIndex, endIndex);
276
+ }
277
+ /** Default configuration for sentence-level pattern detection */
278
+ const DEFAULT_SENTENCE_PATTERN_CONFIG = {
279
+ similarityThreshold: 0.85,
280
+ minPages: 3,
281
+ samplePages: 5,
282
+ boostedThreshold: 0.75,
283
+ };
284
+ /**
285
+ * Stage 1 of header/footer detection: on the sampled center pages, a small
286
+ * font near the top or bottom 10% of the page marks a candidate Y position.
287
+ */
288
+ /** Median font size across the sampled pages; 0 when nothing has a size. */
289
+ function medianFontSizeOf(samplePages) {
290
+ const fontSizes = [];
291
+ for (const page of samplePages) {
292
+ for (const item of page.items) {
293
+ if (item.fontSize > 0) {
294
+ fontSizes.push(item.fontSize);
295
+ }
296
+ }
297
+ }
298
+ if (fontSizes.length === 0) {
299
+ return 0;
300
+ }
301
+ fontSizes.sort((a, b) => a - b);
302
+ const mid = Math.floor(fontSizes.length / 2);
303
+ const lower = fontSizes[mid - 1] ?? 0;
304
+ const upper = fontSizes[mid] ?? 0;
305
+ return fontSizes.length % 2 === 0 ? (lower + upper) / 2 : upper;
306
+ }
307
+ /** Actual page height when a sampled page reports one, else the largest Y seen. */
308
+ function pageHeightOf(samplePages) {
309
+ const reported = samplePages.find((page) => page.pageHeight != null)?.pageHeight;
310
+ if (reported) {
311
+ return reported;
312
+ }
313
+ let maxY = 0;
314
+ for (const page of samplePages) {
315
+ for (const item of page.items) {
316
+ if (item.y > maxY) {
317
+ maxY = item.y;
318
+ }
319
+ }
320
+ }
321
+ return maxY;
322
+ }
323
+ /** Small-font items sitting in the top or bottom 10% of the page. */
324
+ function collectEdgeCandidateYs(samplePages, fontSizeThreshold, pageHeight) {
325
+ const headerCandidateYs = new Set();
326
+ const footerCandidateYs = new Set();
327
+ for (const page of samplePages) {
328
+ for (const item of page.items) {
329
+ if (item.fontSize >= fontSizeThreshold) {
330
+ continue;
331
+ }
332
+ const roundedY = Math.round(item.y);
333
+ // Header: top 10% of page (large Y values, since Y is inverted)
334
+ if (item.y > pageHeight * 0.9) {
335
+ headerCandidateYs.add(roundedY);
336
+ }
337
+ // Footer: bottom 10% of page (small Y values)
338
+ if (item.y < pageHeight * 0.1) {
339
+ footerCandidateYs.add(roundedY);
340
+ }
341
+ }
342
+ }
343
+ return { headerCandidateYs, footerCandidateYs };
344
+ }
345
+ export function detectBlockAttributeCandidates(pages, config = {}) {
346
+ const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
347
+ const emptyResult = {
348
+ medianFontSize: 0,
349
+ headerCandidateYs: new Set(),
350
+ footerCandidateYs: new Set(),
351
+ };
352
+ if (pages.length < cfg.minPages) {
353
+ return emptyResult;
354
+ }
355
+ const samplePages = sampleCenterPages(pages, cfg.samplePages);
356
+ const medianFontSize = medianFontSizeOf(samplePages);
357
+ if (medianFontSize === 0) {
358
+ return emptyResult;
359
+ }
360
+ const pageHeight = pageHeightOf(samplePages);
361
+ if (pageHeight === 0) {
362
+ return { ...emptyResult, medianFontSize };
363
+ }
364
+ return {
365
+ medianFontSize,
366
+ ...collectEdgeCandidateYs(samplePages, medianFontSize * 0.7, pageHeight),
367
+ };
368
+ }
369
+ /**
370
+ * Detect header/footer patterns at sentence level.
371
+ *
372
+ * Center pages are sampled because cover, TOC and index sit at the edges, and
373
+ * the median pairwise similarity resists an outlier page. Semantic similarity
374
+ * rather than exact matching is what makes variable text like "7 of 75" match.
375
+ */
376
+ /**
377
+ * Shared boundary-pattern detection for the header and footer cases of
378
+ * {@link detectSentencePatterns}. The divergent part — which sentence each page
379
+ * contributes and how its Y is derived — is passed in, so this helper is
380
+ * identical for both boundaries.
381
+ */
382
+ async function detectBoundaryPattern(params) {
383
+ const { label, sentences, sentenceYs, candidateYs, similarityThreshold, boostedThreshold, embedder, startIndex, endIndex, } = params;
384
+ const embeddings = await embedder.embedBatch(sentences);
385
+ const medianSim = medianPairwiseSimilarity(embeddings);
386
+ // Determine effective threshold (boosted if block hints match)
387
+ let threshold = similarityThreshold;
388
+ if (candidateYs && sentenceYs.some((y) => candidateYs.has(y))) {
389
+ threshold = boostedThreshold ?? 0.75;
390
+ }
391
+ const detected = medianSim >= threshold;
392
+ if (detected) {
393
+ console.error(`Sentence ${label} detected: sampled ${sentences.length} center pages (${startIndex + 1}-${endIndex}), median similarity: ${medianSim.toFixed(3)}`);
394
+ }
395
+ return { similarity: medianSim, detected };
396
+ }
397
+ export async function detectSentencePatterns(pages, embedder, config = {}) {
398
+ const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
399
+ const result = {
400
+ removeFirstSentence: false,
401
+ removeLastSentence: false,
402
+ headerSimilarity: 0,
403
+ footerSimilarity: 0,
404
+ };
405
+ // Need minimum pages to detect patterns reliably
406
+ if (pages.length < cfg.minPages) {
407
+ return result;
408
+ }
409
+ // 1. Sample pages from the CENTER of the document
410
+ const samplePages = sampleCenterPages(pages, cfg.samplePages);
411
+ const firstSamplePage = samplePages[0];
412
+ const startIndex = firstSamplePage === undefined ? 0 : pages.indexOf(firstSamplePage);
413
+ const endIndex = startIndex + samplePages.length;
414
+ // 2. Split each page into sentences with Y coordinate (merged by Y)
415
+ const pageSentences = samplePages.map((page) => splitItemsIntoSentencesWithY(page.items));
416
+ // 3. Collect first and last sentences from sampled pages
417
+ const firstSentences = [];
418
+ const lastSentences = [];
419
+ for (const sentences of pageSentences) {
420
+ const first = sentences[0];
421
+ if (first === undefined) {
422
+ continue;
423
+ }
424
+ firstSentences.push(first.text);
425
+ const last = sentences.length > 1 ? sentences.at(-1) : undefined;
426
+ if (last !== undefined) {
427
+ lastSentences.push(last.text);
428
+ }
429
+ }
430
+ // 5. Detect header pattern (sampled first sentences are semantically similar)
431
+ if (firstSentences.length >= cfg.minPages) {
432
+ const firstSentenceYs = pageSentences
433
+ .filter((s) => s.length > 0)
434
+ .map((s) => Math.round(s[0]?.y ?? 0));
435
+ const { similarity, detected } = await detectBoundaryPattern({
436
+ label: 'header',
437
+ sentences: firstSentences,
438
+ sentenceYs: firstSentenceYs,
439
+ candidateYs: cfg.blockHints?.headerCandidateYs,
440
+ similarityThreshold: cfg.similarityThreshold,
441
+ boostedThreshold: cfg.boostedThreshold,
442
+ embedder,
443
+ startIndex,
444
+ endIndex,
445
+ });
446
+ result.headerSimilarity = similarity;
447
+ result.removeFirstSentence = detected;
448
+ }
449
+ // 6. Detect footer pattern (sampled last sentences are semantically similar)
450
+ if (lastSentences.length >= cfg.minPages) {
451
+ const lastSentenceYs = pageSentences
452
+ .filter((s) => s.length > 1)
453
+ .map((s) => Math.round(s.at(-1)?.y ?? 0));
454
+ const { similarity, detected } = await detectBoundaryPattern({
455
+ label: 'footer',
456
+ sentences: lastSentences,
457
+ sentenceYs: lastSentenceYs,
458
+ candidateYs: cfg.blockHints?.footerCandidateYs,
459
+ similarityThreshold: cfg.similarityThreshold,
460
+ boostedThreshold: cfg.boostedThreshold,
461
+ embedder,
462
+ startIndex,
463
+ endIndex,
464
+ });
465
+ result.footerSimilarity = similarity;
466
+ result.removeLastSentence = detected;
467
+ }
468
+ return result;
469
+ }
470
+ /**
471
+ * Main entry point for sentence-level header/footer filtering: removes
472
+ * repeating boundary sentences and returns one filtered text per page.
473
+ *
474
+ * Use this rather than {@link joinFilteredPages} when an embedder is available.
475
+ */
476
+ export async function filterPageBoundarySentences(pages, embedder, config = {}) {
477
+ return (await filterPageBoundaryLayouts(pages, embedder, config)).map((page) => page.text);
478
+ }
479
+ /**
480
+ * Filter page boundaries while retaining native provenance for every survivor.
481
+ */
482
+ export async function filterPageBoundaryLayouts(pages, embedder, config = {}) {
483
+ const cfg = { ...DEFAULT_SENTENCE_PATTERN_CONFIG, ...config };
484
+ // Need minimum pages to detect patterns
485
+ if (pages.length < cfg.minPages) {
486
+ return pages.map((page) => buildPageLayout(page.pageNum, page.items));
487
+ }
488
+ // Detect block attribute candidates for boosted threshold
489
+ const blockHints = detectBlockAttributeCandidates(pages, cfg);
490
+ // Detect patterns (with block hints for boosted threshold)
491
+ const patterns = await detectSentencePatterns(pages, embedder, { ...cfg, blockHints });
492
+ // If no patterns detected, return normally joined text per page
493
+ if (!patterns.removeFirstSentence && !patterns.removeLastSentence) {
494
+ return pages.map((page) => buildPageLayout(page.pageNum, page.items));
495
+ }
496
+ // Split each page into sentences with Y coordinate (merged by Y)
497
+ const pageSentences = pages.map((page) => splitItemsIntoSentencesWithY(page.items));
498
+ const sampledSentences = sampleCenterPages(pages, cfg.samplePages).map((page) => pageSentences[pages.indexOf(page)] ?? []);
499
+ const matchesRepeatedBoundary = (sentence, edge) => {
500
+ if (!sentence) {
501
+ return false;
502
+ }
503
+ // Page numbers may vary; other text and rounded position must repeat.
504
+ const key = (value) => `${Math.round(value.y)}:${value.text.replace(/\d+/g, '#').replace(/\s+/g, ' ').trim()}`;
505
+ const target = key(sentence);
506
+ return (sampledSentences.filter((sentences) => {
507
+ const candidate = sentenceAtEdge(sentences, edge);
508
+ return candidate !== undefined && key(candidate) === target;
509
+ }).length >= 2);
510
+ };
511
+ return pages.map((page, pageIndex) => {
512
+ let cleaned = [...(pageSentences[pageIndex] ?? [])];
513
+ if (patterns.removeFirstSentence && matchesRepeatedBoundary(cleaned[0], 'first')) {
514
+ cleaned = cleaned.slice(1);
515
+ }
516
+ if (patterns.removeLastSentence && matchesRepeatedBoundary(cleaned.at(-1), 'last')) {
517
+ cleaned = cleaned.slice(0, -1);
518
+ }
519
+ return buildSentenceLayout(page.pageNum, cleaned, page.items);
520
+ });
521
+ }
522
+ //# sourceMappingURL=pdf-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-filter.js","sourceRoot":"","sources":["../../src/parser/pdf-filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Result of title extraction, including how the title was determined
3
+ */
4
+ export interface TitleExtractionResult {
5
+ title: string;
6
+ source: 'metadata' | 'content' | 'filename';
7
+ }
8
+ /** `2024-annual-report.pdf` -> `2024 annual report`. */
9
+ export declare function fileNameToTitle(fileName: string): string;
10
+ /** Priority: YAML frontmatter title -> first `#` H1 -> file name. */
11
+ export declare function extractMarkdownTitle(text: string, fileName: string): TitleExtractionResult;
12
+ /** Priority: a first line followed by a blank line -> file name. */
13
+ export declare function extractTxtTitle(text: string, fileName: string): TitleExtractionResult;
14
+ /** Priority: Readability title -> file name. */
15
+ export declare function extractHtmlTitle(readabilityTitle: string, fileName: string): TitleExtractionResult;
16
+ /**
17
+ * Priority: PDF metadata `/Title` -> page-1 chunk 0 -> file name.
18
+ *
19
+ * A metadata title that looks like a file path (contains `/` or `\`) is
20
+ * rejected, since some producers write the source path there.
21
+ */
22
+ export declare function extractPdfTitle(metadataTitle: string | undefined, firstPageChunkText: string | undefined, fileName: string, firstPageFontHint?: {
23
+ text: string;
24
+ fontSize: number;
25
+ }): TitleExtractionResult;
26
+ /** Priority: DOCX core title -> first non-empty `<h1>` -> file name. */
27
+ export declare function extractDocxTitle(document: Document, fileName: string, metadataTitle?: string): TitleExtractionResult;
28
+ //# sourceMappingURL=title-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title-extractor.d.ts","sourceRoot":"","sources":["../../src/parser/title-extractor.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;CAC5C;AAMD,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMxD;AAMD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAe1F;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CAkBrF;AAED,gDAAgD;AAChD,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,MAAM,GACf,qBAAqB,CAOvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD,qBAAqB,CA0BvB;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GACrB,qBAAqB,CAevB"}