abb-opencode-local-rag 0.1.0

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