@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,145 @@
1
+ import { AppError } from './errors.js';
2
+ /**
3
+ * Effective document roots, in two index-aligned forms. This is the canonical
4
+ * statement of the path policy; other sites reference it.
5
+ *
6
+ * - `baseDirs`: realpath-resolved — the containment boundary for
7
+ * `DocumentParser`, and the ONLY place realpath is used.
8
+ * - `rawBaseDirs`: the same roots, resolve()-only. Everything user-facing
9
+ * scans and displays in this space so paths match the resolve()-stored DB
10
+ * keys; otherwise a symlinked prefix (macOS /tmp → /private/tmp) would make
11
+ * ingested files look un-ingested.
12
+ */
13
+ export interface BaseDirsConfig {
14
+ baseDirs: string[];
15
+ rawBaseDirs: string[];
16
+ }
17
+ /**
18
+ * Discriminated union of configuration warnings surfaced by helpers in this
19
+ * module. Both CLI (stderr) and MCP (tool response content block) paths
20
+ * consume these — the consumer decides how to render them.
21
+ */
22
+ export type BaseDirsConfigWarning = {
23
+ kind: 'nested-root-pruned';
24
+ message: string;
25
+ parent: string;
26
+ pruned: string;
27
+ } | {
28
+ kind: 'base-dirs-overrides-base-dir';
29
+ message: string;
30
+ };
31
+ /**
32
+ * Configuration error raised by parsers and the realpath helper. Modeled as
33
+ * a dedicated subclass so consumers can distinguish configuration problems
34
+ * from other I/O errors (e.g. `ValidationError` from `DocumentParser`).
35
+ */
36
+ export declare class BaseDirsConfigError extends AppError {
37
+ constructor(message: string, options?: {
38
+ cause?: Error;
39
+ });
40
+ }
41
+ /**
42
+ * Result of {@link parseBaseDirsEnv}. A discriminated union avoids forcing
43
+ * callers to use `try/catch` for what is a routine configuration-validation
44
+ * branch (invalid input → structured error → user-facing message).
45
+ */
46
+ export type ParseBaseDirsResult = {
47
+ ok: true;
48
+ value: string[];
49
+ } | {
50
+ ok: false;
51
+ error: BaseDirsConfigError;
52
+ };
53
+ /**
54
+ * Substitute `$HOME` with `~` for a user-visible path, so a warning flowing
55
+ * out through MCP does not leak the OS username. `$HOME` is read at call time,
56
+ * never cached.
57
+ */
58
+ export declare function displayPath(path: string): string;
59
+ /**
60
+ * Parse `BASE_DIRS`: only a JSON array of non-empty strings is accepted, so
61
+ * delimiter syntax like `'/a:/b'` is an error rather than a silent misread.
62
+ * Syntax only — existence is {@link normalizeRealpath}'s job.
63
+ */
64
+ export declare function parseBaseDirsEnv(raw: string): ParseBaseDirsResult;
65
+ /**
66
+ * Append a trailing path separator if the input does not already end with
67
+ * one. This is the prefix-safety pattern used throughout the parser
68
+ * (`/foo/bar` must not match `/foo/barista`).
69
+ */
70
+ export declare function withTrailingSeparator(path: string): string;
71
+ /**
72
+ * Resolve a directory to its realpath and append a trailing separator, so the
73
+ * result works directly as a prefix in a containment check.
74
+ *
75
+ * Throws when the path is not an existing directory: a root must point at one.
76
+ */
77
+ export declare function normalizeRealpath(path: string): Promise<string>;
78
+ /**
79
+ * Output of {@link dedupAndPruneRoots}.
80
+ */
81
+ export interface DedupAndPruneResult {
82
+ /** Effective roots in input order, after exact dedup and nested pruning. */
83
+ roots: string[];
84
+ /** Warnings describing pruned nested roots, in pruning order. */
85
+ warnings: BaseDirsConfigWarning[];
86
+ }
87
+ /**
88
+ * Reduce realpath-normalized roots to the effective set.
89
+ *
90
+ * Exact duplicates are dropped silently — that is convenience, not a mistake.
91
+ * A nested root is pruned in favour of its parent with a warning, which keeps
92
+ * scan output free of duplicates without widening the boundary past the parent
93
+ * the user already configured. Surviving order is preserved so the first
94
+ * element stays a meaningful legacy `baseDir`.
95
+ *
96
+ * Every input MUST already end with a separator — that is what makes the
97
+ * `startsWith` check safe against a sibling like `/foo/barista`.
98
+ */
99
+ export declare function dedupAndPruneRoots(inputs: string[]): DedupAndPruneResult;
100
+ /**
101
+ * Input to {@link resolveBaseDirs}, in precedence order: `cliRoots` (highest),
102
+ * `envBaseDirs`, `envBaseDir`, `cwd`.
103
+ *
104
+ * The resolver reads no process state, so both entry points can share it and
105
+ * tests can drive it deterministically.
106
+ */
107
+ export interface ResolveBaseDirsInput {
108
+ cliRoots?: string[] | undefined;
109
+ envBaseDirs?: string | undefined;
110
+ envBaseDir?: string | undefined;
111
+ cwd: string;
112
+ }
113
+ /**
114
+ * Result of {@link resolveBaseDirs}, discriminated by `ok` — invalid
115
+ * `BASE_DIRS` is a routine user-facing path, not an exception.
116
+ *
117
+ * `warnings` is in display order: the precedence note first, then one entry
118
+ * per pruned root.
119
+ */
120
+ export type ResolveBaseDirsResult = {
121
+ ok: true;
122
+ config: BaseDirsConfig;
123
+ warnings: BaseDirsConfigWarning[];
124
+ } | {
125
+ ok: false;
126
+ error: BaseDirsConfigError;
127
+ };
128
+ /**
129
+ * Resolve effective base directories from CLI / env / cwd.
130
+ *
131
+ * `cliRoots` REPLACES the env roots rather than merging with them; otherwise
132
+ * precedence falls through `BASE_DIRS`, `BASE_DIR`, `cwd`. The
133
+ * `BASE_DIRS > BASE_DIR` warning therefore fires only on an env-driven run.
134
+ *
135
+ * An invalid `BASE_DIRS`, or a root that is not a readable directory, returns
136
+ * `{ ok: false }`. The resolver never falls back to `BASE_DIR` or `cwd` — each
137
+ * caller surfaces the error per its own UI contract.
138
+ */
139
+ export declare function resolveBaseDirs(input: ResolveBaseDirsInput): Promise<ResolveBaseDirsResult>;
140
+ /**
141
+ * The legacy single-root `baseDir`: the first effective root after pruning.
142
+ * Holds only for a config built via {@link dedupAndPruneRoots}.
143
+ */
144
+ export declare function legacyBaseDir(config: BaseDirsConfig): string;
145
+ //# sourceMappingURL=base-dirs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-dirs.d.ts","sourceRoot":"","sources":["../../src/utils/base-dirs.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAW,MAAM,aAAa,CAAA;AAM/C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,oBAAoB,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf,GACD;IACE,IAAI,EAAE,8BAA8B,CAAA;IACpC,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAEL;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;IAC/C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,EAGvD;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAM7C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBhD;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CA+DjE;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BrE;AAMD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,iEAAiE;IACjE,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,mBAAmB,CA6CxE;AAwBD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAAE,GACvE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAiDjG;AAkED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAM5D"}
@@ -0,0 +1,344 @@
1
+ // Shared base-dirs module: one internal representation of the effective
2
+ // document roots, used by both the CLI and the MCP server entry point, plus
3
+ // the pure helpers that derive it from env vars and CLI flags.
4
+ import { realpath, stat } from 'node:fs/promises';
5
+ import { homedir } from 'node:os';
6
+ import { resolve, sep } from 'node:path';
7
+ import { AppError, toError } from './errors.js';
8
+ /**
9
+ * Configuration error raised by parsers and the realpath helper. Modeled as
10
+ * a dedicated subclass so consumers can distinguish configuration problems
11
+ * from other I/O errors (e.g. `ValidationError` from `DocumentParser`).
12
+ */
13
+ export class BaseDirsConfigError extends AppError {
14
+ constructor(message, options) {
15
+ super(message, 'config', 'config', options);
16
+ this.name = 'BaseDirsConfigError';
17
+ }
18
+ }
19
+ // ============================================
20
+ // Path display helpers
21
+ // ============================================
22
+ /**
23
+ * Substitute `$HOME` with `~` for a user-visible path, so a warning flowing
24
+ * out through MCP does not leak the OS username. `$HOME` is read at call time,
25
+ * never cached.
26
+ */
27
+ export function displayPath(path) {
28
+ const home = process.env['HOME'] || homedir();
29
+ if (home.length === 0) {
30
+ return path;
31
+ }
32
+ const isWin = process.platform === 'win32';
33
+ const cmp = (s) => (isWin ? s.toLowerCase() : s);
34
+ const homeCmp = cmp(home);
35
+ const pathCmp = cmp(path);
36
+ if (pathCmp === homeCmp) {
37
+ return '~';
38
+ }
39
+ if (pathCmp.startsWith(homeCmp + sep) || pathCmp.startsWith(`${homeCmp}/`)) {
40
+ return `~${path.slice(home.length)}`;
41
+ }
42
+ return path;
43
+ }
44
+ // ============================================
45
+ // JSON-array parser for BASE_DIRS
46
+ // ============================================
47
+ /**
48
+ * Parse `BASE_DIRS`: only a JSON array of non-empty strings is accepted, so
49
+ * delimiter syntax like `'/a:/b'` is an error rather than a silent misread.
50
+ * Syntax only — existence is {@link normalizeRealpath}'s job.
51
+ */
52
+ export function parseBaseDirsEnv(raw) {
53
+ const trimmed = raw.trim();
54
+ if (trimmed.length === 0) {
55
+ return {
56
+ ok: false,
57
+ error: new BaseDirsConfigError('BASE_DIRS must be a JSON array of non-empty path strings (received empty value).'),
58
+ };
59
+ }
60
+ let parsed;
61
+ try {
62
+ parsed = JSON.parse(trimmed);
63
+ }
64
+ catch (error) {
65
+ return {
66
+ ok: false,
67
+ error: new BaseDirsConfigError(`BASE_DIRS must be a JSON array of non-empty path strings. Failed to parse as JSON: ${truncate(raw)}`, { cause: toError(error) }),
68
+ };
69
+ }
70
+ if (!Array.isArray(parsed)) {
71
+ return {
72
+ ok: false,
73
+ error: new BaseDirsConfigError(`BASE_DIRS must be a JSON array (received ${describeJsonShape(parsed)}).`),
74
+ };
75
+ }
76
+ if (parsed.length === 0) {
77
+ return {
78
+ ok: false,
79
+ error: new BaseDirsConfigError('BASE_DIRS must not be an empty array.'),
80
+ };
81
+ }
82
+ const value = [];
83
+ for (let i = 0; i < parsed.length; i++) {
84
+ const item = parsed[i];
85
+ if (typeof item !== 'string') {
86
+ return {
87
+ ok: false,
88
+ error: new BaseDirsConfigError(`BASE_DIRS[${i}] must be a string (received ${describeJsonShape(item)}).`),
89
+ };
90
+ }
91
+ if (item.trim().length === 0) {
92
+ return {
93
+ ok: false,
94
+ error: new BaseDirsConfigError(`BASE_DIRS[${i}] must be a non-empty, non-whitespace path string.`),
95
+ };
96
+ }
97
+ value.push(item);
98
+ }
99
+ return { ok: true, value };
100
+ }
101
+ // ============================================
102
+ // Realpath normalization
103
+ // ============================================
104
+ /**
105
+ * Append a trailing path separator if the input does not already end with
106
+ * one. This is the prefix-safety pattern used throughout the parser
107
+ * (`/foo/bar` must not match `/foo/barista`).
108
+ */
109
+ export function withTrailingSeparator(path) {
110
+ return path.endsWith(sep) ? path : path + sep;
111
+ }
112
+ /**
113
+ * Resolve a directory to its realpath and append a trailing separator, so the
114
+ * result works directly as a prefix in a containment check.
115
+ *
116
+ * Throws when the path is not an existing directory: a root must point at one.
117
+ */
118
+ export async function normalizeRealpath(path) {
119
+ let resolved;
120
+ try {
121
+ resolved = await realpath(resolve(path));
122
+ }
123
+ catch (error) {
124
+ throw new BaseDirsConfigError(`Failed to resolve base directory: ${displayPath(path)}. The directory may not exist or is inaccessible.`, { cause: toError(error) });
125
+ }
126
+ let stats;
127
+ try {
128
+ stats = await stat(resolved);
129
+ }
130
+ catch (error) {
131
+ throw new BaseDirsConfigError(`Failed to stat resolved base directory: ${displayPath(resolved)}.`, { cause: toError(error) });
132
+ }
133
+ if (!stats.isDirectory()) {
134
+ throw new BaseDirsConfigError(`Base directory is not a directory: ${displayPath(path)} (resolved: ${displayPath(resolved)}).`);
135
+ }
136
+ return withTrailingSeparator(resolved);
137
+ }
138
+ /**
139
+ * Reduce realpath-normalized roots to the effective set.
140
+ *
141
+ * Exact duplicates are dropped silently — that is convenience, not a mistake.
142
+ * A nested root is pruned in favour of its parent with a warning, which keeps
143
+ * scan output free of duplicates without widening the boundary past the parent
144
+ * the user already configured. Surviving order is preserved so the first
145
+ * element stays a meaningful legacy `baseDir`.
146
+ *
147
+ * Every input MUST already end with a separator — that is what makes the
148
+ * `startsWith` check safe against a sibling like `/foo/barista`.
149
+ */
150
+ export function dedupAndPruneRoots(inputs) {
151
+ // Pass 1: exact dedup, preserving order.
152
+ const deduped = [];
153
+ const seen = new Set();
154
+ for (const root of inputs) {
155
+ if (!seen.has(root)) {
156
+ seen.add(root);
157
+ deduped.push(root);
158
+ }
159
+ }
160
+ // Pass 2: nested-root pruning.
161
+ //
162
+ // In a chain like `[grandparent, parent, child]` both descendants are pruned
163
+ // and each warning names the closest SURVIVING ancestor, so a warning never
164
+ // points at a path that was itself pruned. Hence two passes: the pre-pass
165
+ // computes the survivors, the main pass resolves ancestors against them.
166
+ // O(n^2) in root count, which is harmless at realistic sizes.
167
+ const roots = [];
168
+ const warnings = [];
169
+ // Pre-pass: identify every candidate that has any ancestor in `deduped`
170
+ // (these are the pruned candidates). The candidates that do NOT have any
171
+ // ancestor in `deduped` are the surviving roots.
172
+ const survivors = [];
173
+ for (const candidate of deduped) {
174
+ if (findParent(candidate, deduped) === undefined) {
175
+ survivors.push(candidate);
176
+ }
177
+ }
178
+ for (const candidate of deduped) {
179
+ const survivingAncestor = findParent(candidate, survivors);
180
+ if (survivingAncestor === undefined) {
181
+ // This candidate is itself a surviving root.
182
+ roots.push(candidate);
183
+ continue;
184
+ }
185
+ warnings.push({
186
+ kind: 'nested-root-pruned',
187
+ message: `Nested base directory pruned: ${displayPath(candidate)} is inside ${displayPath(survivingAncestor)}. Keeping ${displayPath(survivingAncestor)} only.`,
188
+ parent: survivingAncestor,
189
+ pruned: candidate,
190
+ });
191
+ }
192
+ return { roots, warnings };
193
+ }
194
+ /** Closest ancestor of `candidate` in `all`, measured by prefix length. */
195
+ function findParent(candidate, all) {
196
+ let best;
197
+ for (const other of all) {
198
+ if (other === candidate) {
199
+ continue;
200
+ }
201
+ // `other` ends with `sep` (precondition), so this prefix check is
202
+ // sibling-prefix safe.
203
+ if (candidate.startsWith(other)) {
204
+ if (best === undefined || other.length > best.length) {
205
+ best = other;
206
+ }
207
+ }
208
+ }
209
+ return best;
210
+ }
211
+ /**
212
+ * Resolve effective base directories from CLI / env / cwd.
213
+ *
214
+ * `cliRoots` REPLACES the env roots rather than merging with them; otherwise
215
+ * precedence falls through `BASE_DIRS`, `BASE_DIR`, `cwd`. The
216
+ * `BASE_DIRS > BASE_DIR` warning therefore fires only on an env-driven run.
217
+ *
218
+ * An invalid `BASE_DIRS`, or a root that is not a readable directory, returns
219
+ * `{ ok: false }`. The resolver never falls back to `BASE_DIR` or `cwd` — each
220
+ * caller surfaces the error per its own UI contract.
221
+ */
222
+ export async function resolveBaseDirs(input) {
223
+ const selection = selectRoots(input);
224
+ if (!selection.ok) {
225
+ return selection;
226
+ }
227
+ const warnings = [];
228
+ if (selection.precedenceWarning) {
229
+ warnings.push(selection.precedenceWarning);
230
+ }
231
+ // Realpath-normalize each selected root. Failures (missing directory,
232
+ // permission denied, ...) are surfaced as a structured config error.
233
+ //
234
+ // Pair each realpath'd root (security form) with its resolve()-only form so
235
+ // `rawBaseDirs` mirrors the dedup/prune decisions index-for-index. See
236
+ // {@link BaseDirsConfig} for the path policy.
237
+ const normalized = [];
238
+ const realToRaw = new Map();
239
+ for (const root of selection.roots) {
240
+ let real;
241
+ try {
242
+ real = await normalizeRealpath(root);
243
+ }
244
+ catch (error) {
245
+ if (error instanceof BaseDirsConfigError) {
246
+ return { ok: false, error };
247
+ }
248
+ throw error;
249
+ }
250
+ normalized.push(real);
251
+ // First-occurrence-wins so the surviving raw root matches the first
252
+ // configured spelling of a root that realpaths to the same directory.
253
+ if (!realToRaw.has(real)) {
254
+ realToRaw.set(real, withTrailingSeparator(resolve(root)));
255
+ }
256
+ }
257
+ const { roots, warnings: pruningWarnings } = dedupAndPruneRoots(normalized);
258
+ warnings.push(...pruningWarnings);
259
+ // Project the surviving realpath'd roots back to their resolve()-only forms,
260
+ // preserving order so `rawBaseDirs[i]` and `baseDirs[i]` are the same root.
261
+ const rawRoots = roots.map((real) => realToRaw.get(real) ?? real);
262
+ return {
263
+ ok: true,
264
+ config: { baseDirs: roots, rawBaseDirs: rawRoots },
265
+ warnings,
266
+ };
267
+ }
268
+ /**
269
+ * Pick which input set of roots wins. String-level only, so the realpath I/O
270
+ * in {@link resolveBaseDirs} stays separate from the precedence rules.
271
+ */
272
+ function selectRoots(input) {
273
+ // 1. CLI roots — when non-empty, replace env entirely (no precedence
274
+ // warning even if env vars are also set, because the user explicitly
275
+ // overrode them via CLI).
276
+ if (input.cliRoots !== undefined && input.cliRoots.length > 0) {
277
+ return { ok: true, roots: input.cliRoots };
278
+ }
279
+ // 2. BASE_DIRS — when CLI absent. Whitespace-only is treated as an
280
+ // invalid value (consistent with parseBaseDirsEnv), not as "unset",
281
+ // so the user notices a malformed env var instead of silently falling
282
+ // through to BASE_DIR.
283
+ if (input.envBaseDirs !== undefined && input.envBaseDirs.length > 0) {
284
+ const parsed = parseBaseDirsEnv(input.envBaseDirs);
285
+ if (!parsed.ok) {
286
+ return { ok: false, error: parsed.error };
287
+ }
288
+ const precedenceWarning = input.envBaseDir !== undefined && input.envBaseDir.trim().length > 0
289
+ ? {
290
+ kind: 'base-dirs-overrides-base-dir',
291
+ message: 'BASE_DIRS is set; BASE_DIR is ignored. Unset BASE_DIR or remove BASE_DIRS to silence this warning.',
292
+ }
293
+ : undefined;
294
+ return precedenceWarning
295
+ ? { ok: true, roots: parsed.value, precedenceWarning }
296
+ : { ok: true, roots: parsed.value };
297
+ }
298
+ // 3. BASE_DIR — when CLI and BASE_DIRS are absent. Whitespace-only is
299
+ // treated as "unset" (a user clearing the value with spaces gets the
300
+ // same behavior as not setting it at all).
301
+ if (input.envBaseDir !== undefined && input.envBaseDir.trim().length > 0) {
302
+ return { ok: true, roots: [input.envBaseDir] };
303
+ }
304
+ // 4. cwd — final fallback.
305
+ return { ok: true, roots: [input.cwd] };
306
+ }
307
+ // ============================================
308
+ // Legacy single-root accessor
309
+ // ============================================
310
+ /**
311
+ * The legacy single-root `baseDir`: the first effective root after pruning.
312
+ * Holds only for a config built via {@link dedupAndPruneRoots}.
313
+ */
314
+ export function legacyBaseDir(config) {
315
+ const first = config.baseDirs[0];
316
+ if (first === undefined) {
317
+ throw new BaseDirsConfigError('BaseDirsConfig must contain at least one base directory.');
318
+ }
319
+ return first;
320
+ }
321
+ /**
322
+ * Describe a JSON value's shape for error messages without dumping its full
323
+ * (possibly large) content.
324
+ */
325
+ function describeJsonShape(value) {
326
+ if (value === null) {
327
+ return 'null';
328
+ }
329
+ if (Array.isArray(value)) {
330
+ return 'array';
331
+ }
332
+ return typeof value;
333
+ }
334
+ /**
335
+ * Truncate user-supplied input so configuration error messages stay readable
336
+ * even when the offending value is large.
337
+ */
338
+ function truncate(input, max = 100) {
339
+ if (input.length <= max) {
340
+ return input;
341
+ }
342
+ return `${input.slice(0, max)}...`;
343
+ }
344
+ //# sourceMappingURL=base-dirs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-dirs.js","sourceRoot":"","sources":["../../src/utils/base-dirs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /** Architectural layer that raised the error. */
2
+ export type AppErrorLayer = 'embedder' | 'parser' | 'vectordb' | 'config' | 'pdf-visual';
3
+ /** Nature of the failure, independent of layer. */
4
+ export type AppErrorKind = 'validation' | 'io' | 'config' | 'internal';
5
+ /**
6
+ * Abstract base for every domain error. Stores the `layer`/`kind`
7
+ * discriminants and the originating `cause`, leaving the concrete subclass to
8
+ * own its public constructor signature and its `name`.
9
+ */
10
+ export declare abstract class AppError extends Error {
11
+ readonly layer: AppErrorLayer;
12
+ readonly kind: AppErrorKind;
13
+ readonly cause?: Error;
14
+ protected constructor(message: string, layer: AppErrorLayer, kind: AppErrorKind, options?: {
15
+ cause?: Error;
16
+ });
17
+ }
18
+ /**
19
+ * Narrow a caught value to an `Error` so it can be stored as a `cause`. A
20
+ * non-`Error` is wrapped as `String(value)`, so its text survives in the chain
21
+ * but its structure does not.
22
+ */
23
+ export declare function toError(value: unknown): Error;
24
+ /** Type guard: narrows an unknown value to the shared error taxonomy. */
25
+ export declare function isAppError(value: unknown): value is AppError;
26
+ /**
27
+ * Walks the `.cause` chain starting from `error`, returning errors in order
28
+ * `[outer, cause, cause.cause, ...]`. The walk stops at the first link whose
29
+ * `.cause` is not an `Error`. Self-referential chains are guarded against.
30
+ */
31
+ export declare function getCauseChain(error: Error): Error[];
32
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAWA,iDAAiD;AACjD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAA;AAExF,mDAAmD;AACnD,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,CAAA;AAEtE;;;;GAIG;AACH,8BAAsB,QAAS,SAAQ,KAAK;IAC1C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAI3B,SAAkB,KAAK,CAAC,EAAE,KAAK,CAAA;IAE/B,SAAS,aACP,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,YAAY,EAClB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,EAQ5B;CACF;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAE7C;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,CAWnD"}
@@ -0,0 +1,61 @@
1
+ // Shared error taxonomy foundation.
2
+ //
3
+ // `AppError` is the abstract base every domain error class extends. It carries
4
+ // two discriminants — `layer` (which architectural layer raised it) and `kind`
5
+ // (the nature of the failure) — so a single boundary mapper can convert errors
6
+ // to client codes and to logs without each handler re-deriving identity.
7
+ //
8
+ // This module is behavior-preserving on its own: it adds the `layer`/`kind`
9
+ // metadata and centralizes `cause` storage, while the concrete classes keep
10
+ // their existing names, messages, and `cause` semantics.
11
+ /**
12
+ * Abstract base for every domain error. Stores the `layer`/`kind`
13
+ * discriminants and the originating `cause`, leaving the concrete subclass to
14
+ * own its public constructor signature and its `name`.
15
+ */
16
+ export class AppError extends Error {
17
+ layer;
18
+ kind;
19
+ // Declared explicitly so the type is `Error | undefined` (not `unknown`,
20
+ // as on the native `Error.cause`) and assignment honors
21
+ // `exactOptionalPropertyTypes`.
22
+ cause;
23
+ constructor(message, layer, kind, options) {
24
+ super(message);
25
+ this.layer = layer;
26
+ this.kind = kind;
27
+ if (options?.cause !== undefined) {
28
+ this.cause = options.cause;
29
+ }
30
+ }
31
+ }
32
+ /**
33
+ * Narrow a caught value to an `Error` so it can be stored as a `cause`. A
34
+ * non-`Error` is wrapped as `String(value)`, so its text survives in the chain
35
+ * but its structure does not.
36
+ */
37
+ export function toError(value) {
38
+ return value instanceof Error ? value : new Error(String(value));
39
+ }
40
+ /** Type guard: narrows an unknown value to the shared error taxonomy. */
41
+ export function isAppError(value) {
42
+ return value instanceof AppError;
43
+ }
44
+ /**
45
+ * Walks the `.cause` chain starting from `error`, returning errors in order
46
+ * `[outer, cause, cause.cause, ...]`. The walk stops at the first link whose
47
+ * `.cause` is not an `Error`. Self-referential chains are guarded against.
48
+ */
49
+ export function getCauseChain(error) {
50
+ const chain = [];
51
+ const seen = new Set();
52
+ let current = error;
53
+ while (current !== undefined && !seen.has(current)) {
54
+ chain.push(current);
55
+ seen.add(current);
56
+ const next = current.cause;
57
+ current = next instanceof Error ? next : undefined;
58
+ }
59
+ return chain;
60
+ }
61
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,yEAAyE;AACzE,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,yDAAyD;AAQzD;;;;GAIG;AACH,MAAM,OAAgB,QAAS,SAAQ,KAAK;IACjC,KAAK,CAAe;IACpB,IAAI,CAAc;IAC3B,yEAAyE;IACzE,wDAAwD;IACxD,gCAAgC;IACd,KAAK,CAAQ;IAE/B,YACE,OAAe,EACf,KAAoB,EACpB,IAAkB,EAClB,OAA2B;QAE3B,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;QAC5B,CAAC;IACH,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAClE,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,QAAQ,CAAA;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAY;IACxC,MAAM,KAAK,GAAY,EAAE,CAAA;IACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAS,CAAA;IAC7B,IAAI,OAAO,GAAsB,KAAK,CAAA;IACtC,OAAO,OAAO,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,IAAI,GAAY,OAAO,CAAC,KAAK,CAAA;QACnC,OAAO,GAAG,IAAI,YAAY,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IACpD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Maximum directory recursion depth when scanning a base directory or ingest
3
+ * target. Applied identically by the CLI `ingest`/`list` walkers and the MCP
4
+ * server's `list_files` scan so the boundary is consistent everywhere.
5
+ */
6
+ export declare const MAX_SCAN_DEPTH = 10;
7
+ /**
8
+ * Default maximum file size for ingestion, in bytes (100 MB). Used when neither
9
+ * the CLI `--max-file-size` flag nor the `MAX_FILE_SIZE` env var is provided.
10
+ */
11
+ export declare const DEFAULT_MAX_FILE_SIZE = 104857600;
12
+ /**
13
+ * Hard upper bound (inclusive) for the configurable max file size, in bytes
14
+ * (500 MB). Values above this are rejected by `validateMaxFileSize`.
15
+ */
16
+ export declare const MAX_FILE_SIZE_LIMIT = 524288000;
17
+ /** Inclusive result-count range shared by CLI, MCP validation, and VectorStore. */
18
+ export declare const MIN_QUERY_LIMIT = 1;
19
+ export declare const MAX_QUERY_LIMIT = 20;
20
+ /** Maximum number of adjacent chunks accepted on either side of a target. */
21
+ export declare const MAX_NEIGHBOR_COUNT = 50;
22
+ /** Inclusive upper bound for the configurable minimum chunk length. */
23
+ export declare const MAX_CHUNK_MIN_LENGTH = 10000;
24
+ /** Maximum encoded bytes for one visual attachment returned with a chunk. */
25
+ export declare const MAX_VISUAL_RENDITION_BYTES: number;
26
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/utils/limits.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,cAAc,KAAK,CAAA;AAEhC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,YAAc,CAAA;AAEhD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAc,CAAA;AAE9C,mFAAmF;AACnF,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,KAAK,CAAA;AAEpC,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,QAAS,CAAA;AAE1C,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,QAAa,CAAA"}