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,363 @@
1
+ // CLI ingest subcommand — bulk file ingestion with single optimize() at end
2
+ import { stat } from 'node:fs/promises';
3
+ import { resolve, sep } from 'node:path';
4
+ import { SemanticChunker } from '../chunker/index.js';
5
+ import { buildPreparedFileVectorChunks, prepareFileForIngest } from '../ingest/file.js';
6
+ import { DocumentParser } from '../parser/index.js';
7
+ import { QUALITY_PROFILES } from '../pdf-visual/types.js';
8
+ import { DEFAULT_MAX_FILE_SIZE, MAX_CHUNK_MIN_LENGTH } from '../utils/limits.js';
9
+ import { createEmbedder, createVectorStore, formatCliError, resolveCliBaseDirsOrExit, } from './common.js';
10
+ import { collectFiles } from './file-collection.js';
11
+ import { consumeBaseDirArg, requireFlagValue, resolveDevice, resolveGlobalConfig, validateChunkMinLength, validateMaxFileSize, validatePath, } from './options.js';
12
+ function isQualityProfile(value) {
13
+ return QUALITY_PROFILES.some((profile) => profile === value);
14
+ }
15
+ // ============================================
16
+ // Defaults
17
+ // ============================================
18
+ const INGEST_DEFAULTS = {
19
+ maxFileSize: DEFAULT_MAX_FILE_SIZE,
20
+ };
21
+ // ============================================
22
+ // Help
23
+ // ============================================
24
+ const HELP_TEXT = `Usage: mcp-local-rag [global-options] ingest [options] <path>
25
+
26
+ Ingest a single file or all supported files under a directory.
27
+
28
+ Options:
29
+ --base-dir <path> Base directory for documents (repeatable: pass once per root; default: BASE_DIRS/BASE_DIR env or cwd)
30
+ --max-file-size <n> Max file size in bytes (default: ${INGEST_DEFAULTS.maxFileSize})
31
+ --chunk-min-length <n> Minimum chunk length in characters (default: 50, range: 1-${MAX_CHUNK_MIN_LENGTH})
32
+ --visual Enable VLM captioning for PDF figure pages (PDFs only; no effect on other types)
33
+ --images Store bounded PDF figures/tables and Mammoth DOCX images
34
+ --visual-quality <profile> VLM profile when --visual is set: fast (default, lightweight) or quality (Qwen2.5-VL-3B, ~10x cache, ~2x inference)
35
+ -h, --help Show this help
36
+
37
+ Global options (must appear before "ingest"):
38
+ --db-path <path> LanceDB database path
39
+ --cache-dir <path> Model cache directory
40
+ --model-name <name> Embedding model`;
41
+ // ============================================
42
+ // Arg Parsing
43
+ // ============================================
44
+ /**
45
+ * Parse ingest-specific CLI arguments into options and a positional path.
46
+ * Flags: --base-dir, --max-file-size, -h/--help
47
+ * Unknown flags (including global flags passed after subcommand) cause an error.
48
+ */
49
+ export function parseArgs(args) {
50
+ const options = {};
51
+ let positional;
52
+ let help = false;
53
+ let i = 0;
54
+ while (i < args.length) {
55
+ const arg = args[i];
56
+ switch (arg) {
57
+ case '-h':
58
+ case '--help':
59
+ help = true;
60
+ i++;
61
+ break;
62
+ case '--base-dir': {
63
+ // Repeatable: each `--base-dir <path>` occurrence appends one entry
64
+ // to `options.baseDirs`. The accumulator is lazily initialized so
65
+ // an absent flag leaves `options.baseDirs` as `undefined`, which
66
+ // the resolver treats as "fall through to env / cwd".
67
+ if (options.baseDirs === undefined) {
68
+ options.baseDirs = [];
69
+ }
70
+ const valueIndex = consumeBaseDirArg(args, i, options.baseDirs);
71
+ i = valueIndex + 1;
72
+ break;
73
+ }
74
+ case '--max-file-size': {
75
+ const raw = requireFlagValue(args, i, '--max-file-size');
76
+ if (!/^\d+$/.test(raw)) {
77
+ console.error(`Invalid value for --max-file-size: "${raw.slice(0, 100)}"`);
78
+ process.exit(1);
79
+ }
80
+ options.maxFileSize = Number.parseInt(raw, 10);
81
+ i += 2;
82
+ break;
83
+ }
84
+ case '--chunk-min-length': {
85
+ const raw = requireFlagValue(args, i, '--chunk-min-length');
86
+ if (!/^\d+$/.test(raw)) {
87
+ console.error(`Invalid value for --chunk-min-length: "${raw.slice(0, 100)}"`);
88
+ process.exit(1);
89
+ }
90
+ options.chunkMinLength = Number.parseInt(raw, 10);
91
+ i += 2;
92
+ break;
93
+ }
94
+ case '--visual':
95
+ // Boolean toggle: no value consumed. Mirrors the -h/--help pattern.
96
+ options.visual = true;
97
+ i++;
98
+ break;
99
+ case '--images':
100
+ options.images = true;
101
+ i++;
102
+ break;
103
+ case '--visual-quality': {
104
+ const value = requireFlagValue(args, i, '--visual-quality');
105
+ if (!isQualityProfile(value)) {
106
+ console.error(`Invalid value for --visual-quality: "${value.slice(0, 100)}". Expected "fast" or "quality".`);
107
+ process.exit(1);
108
+ }
109
+ options.visualQuality = value;
110
+ i += 2;
111
+ break;
112
+ }
113
+ default:
114
+ if (arg.startsWith('-')) {
115
+ console.error(`Unknown option: ${arg}`);
116
+ console.error(HELP_TEXT);
117
+ process.exit(1);
118
+ }
119
+ if (positional !== undefined) {
120
+ console.error(`Unexpected argument: ${arg}`);
121
+ console.error('Only one path is accepted. Use a directory to ingest multiple files.');
122
+ process.exit(1);
123
+ }
124
+ positional = arg;
125
+ i++;
126
+ break;
127
+ }
128
+ }
129
+ return { positional, options, help };
130
+ }
131
+ // ============================================
132
+ // Config Resolution
133
+ // ============================================
134
+ /**
135
+ * Resolve ingest config by merging global config with ingest-specific options.
136
+ *
137
+ * Base directories are resolved via the shared CLI resolver
138
+ * ({@link resolveCliBaseDirsOrExit}) which applies the documented precedence
139
+ * (CLI roots > `BASE_DIRS` > `BASE_DIR` > `cwd`), realpath-normalizes every
140
+ * effective root, dedupes exact duplicates, and prunes nested roots. CLI
141
+ * roots are pre-validated against the sensitive-path policy here so the
142
+ * user sees `--base-dir`-attributed errors before the resolver touches the
143
+ * filesystem.
144
+ *
145
+ * Other ingest-specific values (maxFileSize, chunkMinLength) follow the
146
+ * existing CLI > env > defaults order and are validated against the same
147
+ * ranges as before.
148
+ */
149
+ export async function resolveConfig(globalConfig, ingestOptions = {}) {
150
+ const cliBaseDirs = ingestOptions.baseDirs ?? [];
151
+ // Validate CLI-supplied paths against the sensitive-path policy before
152
+ // calling the resolver. Doing this here (rather than relying on the
153
+ // resolver) keeps the error message attributed to `--base-dir` and avoids
154
+ // an unnecessary realpath round-trip on a path we will reject anyway.
155
+ for (const root of cliBaseDirs) {
156
+ const baseDirError = validatePath(root, '--base-dir');
157
+ if (baseDirError) {
158
+ console.error(baseDirError);
159
+ process.exit(1);
160
+ }
161
+ }
162
+ const { config: baseDirs, warnings: baseDirsWarnings } = await resolveCliBaseDirsOrExit(cliBaseDirs);
163
+ const maxFileSize = ingestOptions.maxFileSize ??
164
+ (process.env['MAX_FILE_SIZE']
165
+ ? Number.parseInt(process.env['MAX_FILE_SIZE'], 10)
166
+ : INGEST_DEFAULTS.maxFileSize);
167
+ const chunkMinLength = ingestOptions.chunkMinLength ??
168
+ (process.env['CHUNK_MIN_LENGTH']
169
+ ? Number.parseInt(process.env['CHUNK_MIN_LENGTH'], 10)
170
+ : undefined);
171
+ // Validate maxFileSize range
172
+ const maxFileSizeError = validateMaxFileSize(maxFileSize);
173
+ if (maxFileSizeError) {
174
+ console.error(maxFileSizeError);
175
+ process.exit(1);
176
+ }
177
+ // Validate chunkMinLength range (if provided)
178
+ if (chunkMinLength !== undefined) {
179
+ const chunkMinLengthError = validateChunkMinLength(chunkMinLength);
180
+ if (chunkMinLengthError) {
181
+ console.error(chunkMinLengthError);
182
+ process.exit(1);
183
+ }
184
+ }
185
+ const resolved = {
186
+ dbPath: globalConfig.dbPath,
187
+ cacheDir: globalConfig.cacheDir,
188
+ modelName: globalConfig.modelName,
189
+ baseDirs,
190
+ baseDirsWarnings,
191
+ maxFileSize,
192
+ };
193
+ if (chunkMinLength !== undefined) {
194
+ resolved.chunkMinLength = chunkMinLength;
195
+ }
196
+ return resolved;
197
+ }
198
+ /**
199
+ * Ingest a single file: hash, parse, chunk, embed, delete old chunks, insert new
200
+ * chunks. Returns the number of chunks inserted.
201
+ *
202
+ * When `options.visual === true` AND the file is a `.pdf`, routes through the
203
+ * visual-enrichment path: `parsePdfPages` + VLM captioning (`pdf-visual`
204
+ * orchestrator) + joined-text chunking. `pdf-visual` is loaded via dynamic
205
+ * `await import('../pdf-visual/index.js')` so the default (non-visual) path
206
+ * never pulls the VLM module into the bundle.
207
+ *
208
+ * Non-visual, non-PDF, and `visual: true` + non-PDF paths all use the default
209
+ * text-only branch and never load `pdf-visual`.
210
+ */
211
+ export async function ingestSingleFile(filePath, parser, chunker, embedder, vectorStore, options) {
212
+ const isPdf = filePath.toLowerCase().endsWith('.pdf');
213
+ const prepared = await prepareFileForIngest(filePath, parser, chunker, embedder, {
214
+ images: options?.images === true,
215
+ ...(options?.visual === true
216
+ ? {
217
+ captioner: {
218
+ profile: options.profile,
219
+ cacheDir: options.cacheDir,
220
+ device: options.device,
221
+ },
222
+ }
223
+ : {}),
224
+ });
225
+ if (prepared.omittedImageCount > 0) {
226
+ console.error(` Warning: skipped ${prepared.omittedImageCount} undecodable or oversized ${isPdf ? 'PDF' : 'DOCX'} image(s)`);
227
+ }
228
+ if (prepared.chunks.length === 0) {
229
+ console.error(` Warning: 0 chunks generated (file may be empty or too short)`);
230
+ return 0;
231
+ }
232
+ const vectorChunks = buildPreparedFileVectorChunks(prepared);
233
+ // Delete existing chunks for this file, then insert the new ones
234
+ await vectorStore.deleteChunks(filePath);
235
+ await vectorStore.insertChunks(vectorChunks);
236
+ return vectorChunks.length;
237
+ }
238
+ // ============================================
239
+ // Main Entry Point
240
+ // ============================================
241
+ /**
242
+ * Run the ingest CLI subcommand.
243
+ * @param args - Arguments after "ingest" (e.g., option flags and file/directory path)
244
+ * @param globalOptions - Global options parsed before the subcommand
245
+ */
246
+ export async function runIngest(args, globalOptions = {}) {
247
+ // Parse CLI options
248
+ const { positional, options, help } = parseArgs(args);
249
+ // Handle --help
250
+ if (help) {
251
+ console.error(HELP_TEXT);
252
+ process.exit(0);
253
+ }
254
+ // Validate positional argument
255
+ if (!positional) {
256
+ console.error('Usage: mcp-local-rag ingest [options] <path>');
257
+ console.error(' Ingest a single file or all supported files under a directory.');
258
+ console.error(' Run with --help for all options.');
259
+ process.exit(1);
260
+ }
261
+ const targetPath = positional;
262
+ // Validate path exists
263
+ try {
264
+ await stat(targetPath);
265
+ }
266
+ catch {
267
+ console.error(`Error: path does not exist: ${targetPath}`);
268
+ process.exit(1);
269
+ }
270
+ // Resolve config: CLI flags > env vars > defaults
271
+ const globalConfig = resolveGlobalConfig(globalOptions);
272
+ const config = await resolveConfig(globalConfig, options);
273
+ const excludePaths = [`${resolve(config.dbPath)}${sep}`, `${resolve(config.cacheDir)}${sep}`];
274
+ // Surface resolver warnings (precedence, nested-root pruning) on stderr
275
+ // before scan output starts.
276
+ for (const warning of config.baseDirsWarnings) {
277
+ console.error(warning.message);
278
+ }
279
+ // Directory mode scans only the positional directory; configured roots are
280
+ // the containment boundary used by collectFiles and DocumentParser.
281
+ const files = await collectFiles(targetPath, config.baseDirs.baseDirs, excludePaths);
282
+ if (files.length === 0) {
283
+ console.error('No supported files found.');
284
+ process.exit(1);
285
+ }
286
+ console.error(`Found ${files.length} file(s) to ingest.`);
287
+ // Initialize components (single instances reused across all files).
288
+ // The parser receives the full multi-root config. The directory-scan loop
289
+ // (`collectFiles`) iterates every effective root in `config.baseDirs.baseDirs`
290
+ // and dedupes overlap.
291
+ const parser = new DocumentParser({
292
+ baseDirs: config.baseDirs.baseDirs,
293
+ maxFileSize: config.maxFileSize,
294
+ });
295
+ const chunker = new SemanticChunker(config.chunkMinLength !== undefined ? { minChunkLength: config.chunkMinLength } : {});
296
+ const embedder = createEmbedder(globalConfig);
297
+ const vectorStore = createVectorStore(globalConfig);
298
+ await vectorStore.initialize();
299
+ // Process each file
300
+ const summary = { succeeded: 0, failed: 0, totalChunks: 0 };
301
+ try {
302
+ for (let i = 0; i < files.length; i++) {
303
+ const filePath = files[i];
304
+ const label = `[${i + 1}/${files.length}]`;
305
+ try {
306
+ // Forward visual + VLM env-resolved options into the per-file ingestor.
307
+ // `ingestSingleFile` routes through the visual path when
308
+ // `options.visual === true && filePath.endsWith('.pdf')`. The two
309
+ // variants of `IngestSingleFileOptions` are built explicitly so the
310
+ // VLM fields only travel with the visual-true branch (the cacheDir is
311
+ // pre-validated by `resolveGlobalConfig` so the captioner does not
312
+ // re-read `process.env['CACHE_DIR']` raw).
313
+ const ingestOptions = options.visual
314
+ ? {
315
+ visual: true,
316
+ images: options.images === true,
317
+ // Default the profile to `'fast'` when `--visual-quality` was
318
+ // not provided. The flag is silently ignored when `--visual`
319
+ // itself is absent (mirrors the existing `--visual` precedent
320
+ // of silently coercing for non-PDF files).
321
+ profile: options.visualQuality ?? 'fast',
322
+ cacheDir: globalConfig.cacheDir,
323
+ device: resolveDevice(process.env['RAG_DEVICE']),
324
+ }
325
+ : options.images
326
+ ? { visual: false, images: true }
327
+ : { visual: false, images: false };
328
+ const chunkCount = await ingestSingleFile(filePath, parser, chunker, embedder, vectorStore, ingestOptions);
329
+ if (chunkCount === 0) {
330
+ // 0 chunks is a skip/warning, not a failure
331
+ console.error(`${label} ${filePath} ... SKIPPED (0 chunks)`);
332
+ summary.succeeded++;
333
+ }
334
+ else {
335
+ console.error(`${label} ${filePath} ... OK (${chunkCount} chunks)`);
336
+ summary.succeeded++;
337
+ summary.totalChunks += chunkCount;
338
+ }
339
+ }
340
+ catch (error) {
341
+ const reason = formatCliError(error);
342
+ console.error(`${label} ${filePath} ... FAILED: ${reason}`);
343
+ summary.failed++;
344
+ }
345
+ }
346
+ // Optimize once at end (not per-file)
347
+ await vectorStore.optimize();
348
+ }
349
+ finally {
350
+ await embedder.dispose();
351
+ await vectorStore.close();
352
+ }
353
+ // Print summary
354
+ console.error('');
355
+ console.error('--- Ingest Summary ---');
356
+ console.error(`Succeeded: ${summary.succeeded}`);
357
+ console.error(`Failed: ${summary.failed}`);
358
+ console.error(`Total chunks: ${summary.totalChunks}`);
359
+ if (summary.failed > 0) {
360
+ process.exitCode = 1;
361
+ }
362
+ }
363
+ //# sourceMappingURL=ingest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/cli/ingest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { GlobalOptions } from './options.js';
2
+ interface ListCliOptions {
3
+ /**
4
+ * Collected `--base-dir` values in CLI order. Repeatable: each flag
5
+ * occurrence appends one entry. `undefined` means the flag was not
6
+ * provided.
7
+ */
8
+ baseDirs?: string[] | undefined;
9
+ /**
10
+ * Collected `--scope` path prefixes in CLI order. Repeatable: multiple flags
11
+ * union. Each value is trimmed and validated non-empty at parse time.
12
+ * `undefined` means no scope (list every file); trailing-separator
13
+ * equivalence is applied downstream by `scope-match.ts`.
14
+ */
15
+ scope?: string[] | undefined;
16
+ }
17
+ interface ParsedArgs {
18
+ options: ListCliOptions;
19
+ help: boolean;
20
+ }
21
+ /**
22
+ * Parse list-specific CLI arguments.
23
+ * Flags: --base-dir, -h/--help
24
+ * No positional arguments accepted.
25
+ * Unknown flags cause exit(1).
26
+ */
27
+ export declare function parseArgs(args: string[]): ParsedArgs;
28
+ /**
29
+ * Run the list CLI subcommand.
30
+ * @param args - Arguments after "list"
31
+ * @param globalOptions - Global options parsed before the subcommand
32
+ */
33
+ export declare function runList(args: string[], globalOptions?: GlobalOptions): Promise<void>;
34
+ export {};
35
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/cli/list.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AA4DjD,UAAU,cAAc;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC/B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;CAC7B;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,EAAE,OAAO,CAAA;CACd;AA+DD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAsDpD;AAMD;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,aAAa,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyG9F"}
@@ -0,0 +1,210 @@
1
+ // CLI list subcommand — list files and ingestion status
2
+ import { resolve, sep } from 'node:path';
3
+ import { listDocuments } from '../features/list.js';
4
+ import { displayPath } from '../utils/base-dirs.js';
5
+ import { MAX_SCAN_DEPTH } from '../utils/limits.js';
6
+ import { bfsCollectSupportedFiles } from '../utils/scan.js';
7
+ import { nonAbsolutePrefixes } from '../utils/scope-match.js';
8
+ import { createVectorStore, formatCliError, resolveCliBaseDirsOrExit } from './common.js';
9
+ import { consumeBaseDirArg, requireFlagValue, resolveGlobalConfig, validatePath, } from './options.js';
10
+ /**
11
+ * Bounded BFS scan of a single root, up to `MAX_SCAN_DEPTH` levels deep.
12
+ * Delegates the traversal to {@link bfsCollectSupportedFiles} and renders the
13
+ * `list`-specific warnings: per-directory read failures and the depth-limit
14
+ * warning, both annotated with `displayPath`.
15
+ */
16
+ async function scanRoot(root, excludePaths, scope) {
17
+ // `scope` threads into the walker as the 4th positional arg (after `maxDepth`);
18
+ // pass `undefined` for `maxDepth` to keep the default bound.
19
+ const { files, unreadableDirs, depthLimited } = await bfsCollectSupportedFiles(root, excludePaths, undefined, scope);
20
+ const warnings = [];
21
+ for (const { dirPath, code } of unreadableDirs) {
22
+ warnings.push(`cannot read directory: ${displayPath(dirPath)} (${code})`);
23
+ }
24
+ if (depthLimited) {
25
+ warnings.push(`some directories under ${displayPath(root)} were skipped because they exceed the maximum depth (${MAX_SCAN_DEPTH})`);
26
+ }
27
+ return { files, warnings };
28
+ }
29
+ // ============================================
30
+ // Help
31
+ // ============================================
32
+ const HELP_TEXT = `Usage: mcp-local-rag [global-options] list [options]
33
+
34
+ List files and their ingestion status.
35
+
36
+ Options:
37
+ --base-dir <path> Base directory to scan for files (repeatable: pass once per root; default: BASE_DIRS/BASE_DIR env or cwd)
38
+ --scope <prefix> Restrict results to a path prefix (must be absolute; a relative prefix matches nothing; repeatable for multiple prefixes)
39
+ -h, --help Show this help
40
+
41
+ Global options (must appear before "list"):
42
+ --db-path <path> LanceDB database path
43
+ --cache-dir <path> Model cache directory
44
+ --model-name <name> Embedding model`;
45
+ // ============================================
46
+ // Arg Parsing
47
+ // ============================================
48
+ /**
49
+ * Parse list-specific CLI arguments.
50
+ * Flags: --base-dir, -h/--help
51
+ * No positional arguments accepted.
52
+ * Unknown flags cause exit(1).
53
+ */
54
+ export function parseArgs(args) {
55
+ const options = {};
56
+ let help = false;
57
+ let i = 0;
58
+ while (i < args.length) {
59
+ const arg = args[i];
60
+ switch (arg) {
61
+ case '-h':
62
+ case '--help':
63
+ help = true;
64
+ i++;
65
+ break;
66
+ case '--base-dir': {
67
+ // Repeatable: each `--base-dir <path>` occurrence appends one entry
68
+ // to `options.baseDirs`. The accumulator is lazily initialized so an
69
+ // absent flag leaves `options.baseDirs` as `undefined`, which the
70
+ // resolver treats as "fall through to env / cwd".
71
+ if (options.baseDirs === undefined) {
72
+ options.baseDirs = [];
73
+ }
74
+ const valueIndex = consumeBaseDirArg(args, i, options.baseDirs);
75
+ i = valueIndex + 1;
76
+ break;
77
+ }
78
+ case '--scope': {
79
+ // Repeatable prefix filter (mirrors `query --scope`). Trim and reject
80
+ // empty/whitespace locally — the same non-empty check `normalizeScope`
81
+ // applies at the MCP boundary, kept module-private there. Trailing-
82
+ // separator equivalence is handled downstream in `scope-match.ts`.
83
+ const value = requireFlagValue(args, i, '--scope').trim();
84
+ if (value.length === 0) {
85
+ console.error('--scope value must not be empty');
86
+ process.exit(1);
87
+ }
88
+ const scope = options.scope ?? [];
89
+ scope.push(value);
90
+ options.scope = scope;
91
+ i += 2;
92
+ break;
93
+ }
94
+ default:
95
+ if (arg.startsWith('-')) {
96
+ console.error(`Unknown option: ${arg}`);
97
+ console.error(HELP_TEXT);
98
+ process.exit(1);
99
+ }
100
+ console.error(`Unexpected argument: ${arg}`);
101
+ console.error('The list command does not accept positional arguments.');
102
+ process.exit(1);
103
+ }
104
+ }
105
+ return { options, help };
106
+ }
107
+ // ============================================
108
+ // Main Entry Point
109
+ // ============================================
110
+ /**
111
+ * Run the list CLI subcommand.
112
+ * @param args - Arguments after "list"
113
+ * @param globalOptions - Global options parsed before the subcommand
114
+ */
115
+ export async function runList(args, globalOptions = {}) {
116
+ // Parse CLI options
117
+ const { options, help } = parseArgs(args);
118
+ // Handle --help
119
+ if (help) {
120
+ console.error(HELP_TEXT);
121
+ process.exit(0);
122
+ }
123
+ // Resolve global config
124
+ const globalConfig = resolveGlobalConfig(globalOptions);
125
+ // Validate CLI-supplied paths against the sensitive-path policy BEFORE
126
+ // calling the resolver, so the user sees a `--base-dir`-attributed error
127
+ // without an unnecessary realpath round-trip on a rejected path.
128
+ const cliBaseDirs = options.baseDirs ?? [];
129
+ for (const root of cliBaseDirs) {
130
+ const baseDirError = validatePath(root, '--base-dir');
131
+ if (baseDirError) {
132
+ console.error(baseDirError);
133
+ process.exit(1);
134
+ }
135
+ }
136
+ // Resolve effective base directories via the shared CLI resolver
137
+ // (CLI > BASE_DIRS > BASE_DIR > cwd). Resolver errors (invalid BASE_DIRS,
138
+ // missing directory, ...) exit non-zero with a clear stderr message and
139
+ // do NOT fall back. Resolver warnings (`base-dirs-overrides-base-dir`,
140
+ // `nested-root-pruned`) are routed to stderr so the JSON-only stdout
141
+ // contract is preserved.
142
+ const { config: baseDirsConfig, warnings: baseDirsWarnings } = await resolveCliBaseDirsOrExit(cliBaseDirs);
143
+ for (const warning of baseDirsWarnings) {
144
+ console.error(warning.message);
145
+ }
146
+ // A non-absolute `--scope` prefix matches nothing (scan matching is
147
+ // absolute-path based) but silently yields an empty result for that prefix.
148
+ // Surface it as a non-fatal stderr warning without changing result semantics
149
+ // or the exit code — relative is unhelpful, not an error.
150
+ if (options.scope) {
151
+ for (const prefix of nonAbsolutePrefixes(options.scope)) {
152
+ console.error(`Warning [scope]: "${prefix}" is not an absolute path; it matches nothing.`);
153
+ }
154
+ }
155
+ // Scan/display the normal-path roots (`rawBaseDirs`) so scanned paths match
156
+ // the resolve()-stored DB keys; the realpath'd `baseDirs` are the security
157
+ // boundary, not used here. `rawBaseDirs[0]` is the legacy `baseDir` field.
158
+ const rawBaseDirs = baseDirsConfig.rawBaseDirs;
159
+ const firstRawBaseDir = rawBaseDirs[0];
160
+ if (firstRawBaseDir === undefined) {
161
+ // Cannot happen in non-degraded mode: the resolver always returns at least
162
+ // one effective root. Surface as a programming error rather than emitting
163
+ // an empty `baseDir` field.
164
+ throw new Error('internal: resolver returned no effective base directories');
165
+ }
166
+ const baseDir = firstRawBaseDir;
167
+ const vectorStore = createVectorStore(globalConfig);
168
+ try {
169
+ await vectorStore.initialize();
170
+ // Build exclude paths (resolved to absolute, platform-aware trailing
171
+ // separator). Applied uniformly to every root so dbPath/cacheDir remain
172
+ // excluded under each root even when they happen to live below one of
173
+ // them.
174
+ const excludePaths = [
175
+ `${resolve(globalConfig.dbPath)}${sep}`,
176
+ `${resolve(globalConfig.cacheDir)}${sep}`,
177
+ ];
178
+ const ingested = await vectorStore.listFiles();
179
+ const listed = await listDocuments({
180
+ roots: rawBaseDirs,
181
+ dbPath: globalConfig.dbPath,
182
+ ingested,
183
+ scope: options.scope,
184
+ scan: (root, scope) => scanRoot(root, excludePaths, scope),
185
+ });
186
+ for (const warning of listed.warnings) {
187
+ console.error(`Warning [${warning.baseDir}]: ${warning.message}`);
188
+ }
189
+ const files = listed.files;
190
+ files.sort((a, b) => (a.filePath < b.filePath ? -1 : a.filePath > b.filePath ? 1 : 0));
191
+ const sources = listed.sources;
192
+ const result = {
193
+ baseDirs: [...rawBaseDirs],
194
+ baseDir,
195
+ files,
196
+ sources,
197
+ };
198
+ // Output JSON to stdout
199
+ process.stdout.write(JSON.stringify(result, null, 2));
200
+ }
201
+ catch (error) {
202
+ const message = formatCliError(error);
203
+ console.error(`Failed to list files: ${message}`);
204
+ process.exitCode = 1;
205
+ }
206
+ finally {
207
+ await vectorStore.close();
208
+ }
209
+ }
210
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/cli/list.ts"],"names":[],"mappings":"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"}