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.
- package/LICENSE +21 -0
- package/README.de.md +416 -0
- package/README.es.md +416 -0
- package/README.fr.md +416 -0
- package/README.md +491 -0
- package/README.pt-BR.md +416 -0
- package/README.zh-CN.md +416 -0
- package/dist/bin/install-skills.d.ts +20 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +195 -0
- package/dist/bin/install-skills.js.map +1 -0
- package/dist/chunker/index.d.ts +24 -0
- package/dist/chunker/index.d.ts.map +1 -0
- package/dist/chunker/index.js +2 -0
- package/dist/chunker/index.js.map +1 -0
- package/dist/chunker/semantic-chunker.d.ts +97 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +294 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +28 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +219 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/cli/common.d.ts +65 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +138 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/delete.d.ts +8 -0
- package/dist/cli/delete.d.ts.map +1 -0
- package/dist/cli/delete.js +173 -0
- package/dist/cli/delete.js.map +1 -0
- package/dist/cli/file-collection.d.ts +2 -0
- package/dist/cli/file-collection.d.ts.map +1 -0
- package/dist/cli/file-collection.js +53 -0
- package/dist/cli/file-collection.js.map +1 -0
- package/dist/cli/ingest.d.ts +100 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +363 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/list.d.ts +35 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +210 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/options.d.ts +100 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +241 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/query.d.ts +24 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +191 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/read-neighbors.d.ts +11 -0
- package/dist/cli/read-neighbors.d.ts.map +1 -0
- package/dist/cli/read-neighbors.js +224 -0
- package/dist/cli/read-neighbors.js.map +1 -0
- package/dist/cli/status.d.ts +8 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +80 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync.d.ts +8 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +244 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli-main.d.ts +12 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +63 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/embedder/index.d.ts +85 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +284 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/features/list.d.ts +37 -0
- package/dist/features/list.d.ts.map +1 -0
- package/dist/features/list.js +40 -0
- package/dist/features/list.js.map +1 -0
- package/dist/features/sync.d.ts +207 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +380 -0
- package/dist/features/sync.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/compute.d.ts +86 -0
- package/dist/ingest/compute.d.ts.map +1 -0
- package/dist/ingest/compute.js +177 -0
- package/dist/ingest/compute.js.map +1 -0
- package/dist/ingest/file.d.ts +27 -0
- package/dist/ingest/file.d.ts.map +1 -0
- package/dist/ingest/file.js +67 -0
- package/dist/ingest/file.js.map +1 -0
- package/dist/ingest/visual.d.ts +45 -0
- package/dist/ingest/visual.d.ts.map +1 -0
- package/dist/ingest/visual.js +234 -0
- package/dist/ingest/visual.js.map +1 -0
- package/dist/parser/docx-parser.d.ts +12 -0
- package/dist/parser/docx-parser.d.ts.map +1 -0
- package/dist/parser/docx-parser.js +328 -0
- package/dist/parser/docx-parser.js.map +1 -0
- package/dist/parser/html-parser.d.ts +18 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +102 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +214 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +454 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-extract.d.ts +81 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -0
- package/dist/parser/pdf-extract.js +112 -0
- package/dist/parser/pdf-extract.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +117 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +528 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/parser/title-extractor.d.ts +69 -0
- package/dist/parser/title-extractor.d.ts.map +1 -0
- package/dist/parser/title-extractor.js +145 -0
- package/dist/parser/title-extractor.js.map +1 -0
- package/dist/pdf-visual/captioner.d.ts +16 -0
- package/dist/pdf-visual/captioner.d.ts.map +1 -0
- package/dist/pdf-visual/captioner.js +63 -0
- package/dist/pdf-visual/captioner.js.map +1 -0
- package/dist/pdf-visual/captioners/fast.d.ts +7 -0
- package/dist/pdf-visual/captioners/fast.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/fast.js +103 -0
- package/dist/pdf-visual/captioners/fast.js.map +1 -0
- package/dist/pdf-visual/captioners/quality.d.ts +7 -0
- package/dist/pdf-visual/captioners/quality.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/quality.js +127 -0
- package/dist/pdf-visual/captioners/quality.js.map +1 -0
- package/dist/pdf-visual/captioners/shared.d.ts +44 -0
- package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/shared.js +104 -0
- package/dist/pdf-visual/captioners/shared.js.map +1 -0
- package/dist/pdf-visual/detector.d.ts +9 -0
- package/dist/pdf-visual/detector.d.ts.map +1 -0
- package/dist/pdf-visual/detector.js +234 -0
- package/dist/pdf-visual/detector.js.map +1 -0
- package/dist/pdf-visual/index.d.ts +13 -0
- package/dist/pdf-visual/index.d.ts.map +1 -0
- package/dist/pdf-visual/index.js +45 -0
- package/dist/pdf-visual/index.js.map +1 -0
- package/dist/pdf-visual/renderer.d.ts +9 -0
- package/dist/pdf-visual/renderer.d.ts.map +1 -0
- package/dist/pdf-visual/renderer.js +177 -0
- package/dist/pdf-visual/renderer.js.map +1 -0
- package/dist/pdf-visual/types.d.ts +62 -0
- package/dist/pdf-visual/types.d.ts.map +1 -0
- package/dist/pdf-visual/types.js +32 -0
- package/dist/pdf-visual/types.js.map +1 -0
- package/dist/server/error-utils.d.ts +79 -0
- package/dist/server/error-utils.d.ts.map +1 -0
- package/dist/server/error-utils.js +148 -0
- package/dist/server/error-utils.js.map +1 -0
- package/dist/server/index.d.ts +258 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1104 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/list-scanner.d.ts +52 -0
- package/dist/server/list-scanner.d.ts.map +1 -0
- package/dist/server/list-scanner.js +72 -0
- package/dist/server/list-scanner.js.map +1 -0
- package/dist/server/tool-definitions.d.ts +8 -0
- package/dist/server/tool-definitions.d.ts.map +1 -0
- package/dist/server/tool-definitions.js +181 -0
- package/dist/server/tool-definitions.js.map +1 -0
- package/dist/server/tool-input.d.ts +37 -0
- package/dist/server/tool-input.d.ts.map +1 -0
- package/dist/server/tool-input.js +216 -0
- package/dist/server/tool-input.js.map +1 -0
- package/dist/server/types.d.ts +331 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +3 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server-main.d.ts +46 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +242 -0
- package/dist/server-main.js.map +1 -0
- package/dist/utils/base-dirs.d.ts +212 -0
- package/dist/utils/base-dirs.d.ts.map +1 -0
- package/dist/utils/base-dirs.js +422 -0
- package/dist/utils/base-dirs.js.map +1 -0
- package/dist/utils/errors.d.ts +24 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +53 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/limits.d.ts +26 -0
- package/dist/utils/limits.d.ts.map +1 -0
- package/dist/utils/limits.js +28 -0
- package/dist/utils/limits.js.map +1 -0
- package/dist/utils/list-sources.d.ts +47 -0
- package/dist/utils/list-sources.d.ts.map +1 -0
- package/dist/utils/list-sources.js +50 -0
- package/dist/utils/list-sources.js.map +1 -0
- package/dist/utils/raw-data-utils.d.ts +131 -0
- package/dist/utils/raw-data-utils.d.ts.map +1 -0
- package/dist/utils/raw-data-utils.js +255 -0
- package/dist/utils/raw-data-utils.js.map +1 -0
- package/dist/utils/scan.d.ts +126 -0
- package/dist/utils/scan.d.ts.map +1 -0
- package/dist/utils/scan.js +221 -0
- package/dist/utils/scan.js.map +1 -0
- package/dist/utils/scope-match.d.ts +43 -0
- package/dist/utils/scope-match.d.ts.map +1 -0
- package/dist/utils/scope-match.js +87 -0
- package/dist/utils/scope-match.js.map +1 -0
- package/dist/utils/sensitive-path.d.ts +23 -0
- package/dist/utils/sensitive-path.d.ts.map +1 -0
- package/dist/utils/sensitive-path.js +91 -0
- package/dist/utils/sensitive-path.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +20 -0
- package/dist/utils/sync-path-key.d.ts.map +1 -0
- package/dist/utils/sync-path-key.js +33 -0
- package/dist/utils/sync-path-key.js.map +1 -0
- package/dist/vectordb/index.d.ts +168 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +619 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/search-filters.d.ts +39 -0
- package/dist/vectordb/search-filters.d.ts.map +1 -0
- package/dist/vectordb/search-filters.js +136 -0
- package/dist/vectordb/search-filters.js.map +1 -0
- package/dist/vectordb/types.d.ts +196 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +224 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +105 -0
- package/skills/mcp-local-rag/SKILL.md +308 -0
- package/skills/mcp-local-rag/references/cli-reference.md +175 -0
- package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
- package/skills/mcp-local-rag/references/query-optimization.md +57 -0
- package/skills/mcp-local-rag/references/result-refinement.md +56 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// Shared base-dirs module.
|
|
2
|
+
//
|
|
3
|
+
// Provides one internal representation of the effective document roots used
|
|
4
|
+
// by both the CLI (`ingest`, `list`, ...) and the MCP server entry point
|
|
5
|
+
// (`server-main.ts`), plus the pure helpers needed to derive it from raw
|
|
6
|
+
// configuration inputs (env vars, CLI flags).
|
|
7
|
+
//
|
|
8
|
+
// Scope: this file ships only pure helpers and the types so every consumer
|
|
9
|
+
// can adopt the same realpath/prefix-safety semantics without duplicating
|
|
10
|
+
// the trailing-separator pattern.
|
|
11
|
+
import { realpath, stat } from 'node:fs/promises';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { resolve, sep } from 'node:path';
|
|
14
|
+
import { AppError } from './errors.js';
|
|
15
|
+
/**
|
|
16
|
+
* Configuration error raised by parsers and the realpath helper. Modeled as
|
|
17
|
+
* a dedicated subclass so consumers can distinguish configuration problems
|
|
18
|
+
* from other I/O errors (e.g. `ValidationError` from `DocumentParser`).
|
|
19
|
+
*/
|
|
20
|
+
export class BaseDirsConfigError extends AppError {
|
|
21
|
+
constructor(message, cause) {
|
|
22
|
+
super(message, 'config', 'config', cause);
|
|
23
|
+
this.name = 'BaseDirsConfigError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ============================================
|
|
27
|
+
// Path display helpers
|
|
28
|
+
// ============================================
|
|
29
|
+
/**
|
|
30
|
+
* Render an absolute path for inclusion in user-visible error/warning
|
|
31
|
+
* messages, substituting the current `$HOME` prefix with `~`. The substitution
|
|
32
|
+
* keeps the message useful for debugging while avoiding leaking the operating
|
|
33
|
+
* username when warnings/errors flow out through MCP responses to clients.
|
|
34
|
+
*
|
|
35
|
+
* `$HOME` resolution is read once at call time, so processes that mutate
|
|
36
|
+
* `HOME` between invocations still see the current value (no caching).
|
|
37
|
+
*
|
|
38
|
+
* Exact-match on the home directory itself (`/Users/me` → `~`) and prefix
|
|
39
|
+
* match with a trailing separator (`/Users/me/work` → `~/work`) are both
|
|
40
|
+
* supported; other paths pass through unchanged.
|
|
41
|
+
*/
|
|
42
|
+
export function displayPath(path) {
|
|
43
|
+
const home = process.env['HOME'] || homedir();
|
|
44
|
+
if (home.length === 0)
|
|
45
|
+
return path;
|
|
46
|
+
const isWin = process.platform === 'win32';
|
|
47
|
+
const cmp = (s) => (isWin ? s.toLowerCase() : s);
|
|
48
|
+
const homeCmp = cmp(home);
|
|
49
|
+
const pathCmp = cmp(path);
|
|
50
|
+
if (pathCmp === homeCmp)
|
|
51
|
+
return '~';
|
|
52
|
+
if (pathCmp.startsWith(homeCmp + sep) || pathCmp.startsWith(`${homeCmp}/`)) {
|
|
53
|
+
return `~${path.slice(home.length)}`;
|
|
54
|
+
}
|
|
55
|
+
return path;
|
|
56
|
+
}
|
|
57
|
+
// ============================================
|
|
58
|
+
// JSON-array parser for BASE_DIRS
|
|
59
|
+
// ============================================
|
|
60
|
+
/**
|
|
61
|
+
* Parse the `BASE_DIRS` environment variable.
|
|
62
|
+
*
|
|
63
|
+
* Accepts only a JSON array of one or more non-empty, non-whitespace-only
|
|
64
|
+
* strings — e.g. `'["/Users/me/work","/Users/me/specs"]'`. Anything else
|
|
65
|
+
* (delimiter syntax such as `'/a:/b'`, an empty array, an array containing
|
|
66
|
+
* empty strings, non-string elements, JSON scalars, JSON objects, ...)
|
|
67
|
+
* produces a {@link BaseDirsConfigError}.
|
|
68
|
+
*
|
|
69
|
+
* This helper performs only syntactic validation. It does not resolve
|
|
70
|
+
* realpaths or check that the directories exist — that is the job of
|
|
71
|
+
* {@link normalizeRealpath} after the resolver picks a source.
|
|
72
|
+
*/
|
|
73
|
+
export function parseBaseDirsEnv(raw) {
|
|
74
|
+
const trimmed = raw.trim();
|
|
75
|
+
if (trimmed.length === 0) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
error: new BaseDirsConfigError('BASE_DIRS must be a JSON array of non-empty path strings (received empty value).'),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let parsed;
|
|
82
|
+
try {
|
|
83
|
+
parsed = JSON.parse(trimmed);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
error: new BaseDirsConfigError(`BASE_DIRS must be a JSON array of non-empty path strings. Failed to parse as JSON: ${truncate(raw)}`, error),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (!Array.isArray(parsed)) {
|
|
92
|
+
return {
|
|
93
|
+
ok: false,
|
|
94
|
+
error: new BaseDirsConfigError(`BASE_DIRS must be a JSON array (received ${describeJsonShape(parsed)}).`),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (parsed.length === 0) {
|
|
98
|
+
return {
|
|
99
|
+
ok: false,
|
|
100
|
+
error: new BaseDirsConfigError('BASE_DIRS must not be an empty array.'),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const value = [];
|
|
104
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
105
|
+
const item = parsed[i];
|
|
106
|
+
if (typeof item !== 'string') {
|
|
107
|
+
return {
|
|
108
|
+
ok: false,
|
|
109
|
+
error: new BaseDirsConfigError(`BASE_DIRS[${i}] must be a string (received ${describeJsonShape(item)}).`),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (item.trim().length === 0) {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
error: new BaseDirsConfigError(`BASE_DIRS[${i}] must be a non-empty, non-whitespace path string.`),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
value.push(item);
|
|
119
|
+
}
|
|
120
|
+
return { ok: true, value };
|
|
121
|
+
}
|
|
122
|
+
// ============================================
|
|
123
|
+
// Realpath normalization
|
|
124
|
+
// ============================================
|
|
125
|
+
/**
|
|
126
|
+
* Append a trailing path separator if the input does not already end with
|
|
127
|
+
* one. This is the prefix-safety pattern used throughout the parser
|
|
128
|
+
* (`/foo/bar` must not match `/foo/barista`).
|
|
129
|
+
*/
|
|
130
|
+
export function withTrailingSeparator(path) {
|
|
131
|
+
return path.endsWith(sep) ? path : path + sep;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolve a directory to its realpath form and append a trailing separator
|
|
135
|
+
* so the result can be used directly as a prefix in security checks.
|
|
136
|
+
*
|
|
137
|
+
* realpath here is the security boundary (see {@link BaseDirsConfig} for the
|
|
138
|
+
* path policy); user-facing surfaces use the resolve()-only `rawBaseDirs`.
|
|
139
|
+
*
|
|
140
|
+
* Throws {@link BaseDirsConfigError} when the directory does not exist or
|
|
141
|
+
* is not a directory — root configuration must point at real directories
|
|
142
|
+
* the process is allowed to read.
|
|
143
|
+
*/
|
|
144
|
+
export async function normalizeRealpath(path) {
|
|
145
|
+
let resolved;
|
|
146
|
+
try {
|
|
147
|
+
resolved = await realpath(resolve(path));
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
throw new BaseDirsConfigError(`Failed to resolve base directory: ${displayPath(path)}. The directory may not exist or is inaccessible.`, error);
|
|
151
|
+
}
|
|
152
|
+
let stats;
|
|
153
|
+
try {
|
|
154
|
+
stats = await stat(resolved);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new BaseDirsConfigError(`Failed to stat resolved base directory: ${displayPath(resolved)}.`, error);
|
|
158
|
+
}
|
|
159
|
+
if (!stats.isDirectory()) {
|
|
160
|
+
throw new BaseDirsConfigError(`Base directory is not a directory: ${displayPath(path)} (resolved: ${displayPath(resolved)}).`);
|
|
161
|
+
}
|
|
162
|
+
return withTrailingSeparator(resolved);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Reduce a list of realpath-normalized roots to the effective set.
|
|
166
|
+
*
|
|
167
|
+
* Behavior:
|
|
168
|
+
* - Exact duplicates (`A === B` after realpath normalization) are silently
|
|
169
|
+
* deduplicated. This is treated as user convenience rather than a
|
|
170
|
+
* configuration mistake, so no warning is emitted.
|
|
171
|
+
* - Nested roots (`B` lives under `A` after realpath normalization) are
|
|
172
|
+
* pruned: the parent `A` is kept, the child `B` is dropped, and a
|
|
173
|
+
* `nested-root-pruned` warning describes both paths. This avoids
|
|
174
|
+
* duplicate `list_files` / CLI scan output without widening the security
|
|
175
|
+
* boundary beyond the parent root the user already configured.
|
|
176
|
+
*
|
|
177
|
+
* Input order is preserved for the surviving roots so the first element
|
|
178
|
+
* remains a meaningful legacy `baseDir` (see {@link legacyBaseDir}).
|
|
179
|
+
*
|
|
180
|
+
* All inputs MUST already have a trailing separator (see
|
|
181
|
+
* {@link normalizeRealpath}) — that is what makes the `startsWith`-based
|
|
182
|
+
* nested check safe against sibling-prefix paths like `/foo/barista`.
|
|
183
|
+
*/
|
|
184
|
+
export function dedupAndPruneRoots(inputs) {
|
|
185
|
+
// Pass 1: exact dedup, preserving order.
|
|
186
|
+
const deduped = [];
|
|
187
|
+
const seen = new Set();
|
|
188
|
+
for (const root of inputs) {
|
|
189
|
+
if (!seen.has(root)) {
|
|
190
|
+
seen.add(root);
|
|
191
|
+
deduped.push(root);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Pass 2: nested-root pruning.
|
|
195
|
+
//
|
|
196
|
+
// A root `child` is pruned when some other root `parent` (parent !== child)
|
|
197
|
+
// is a strict prefix of `child`. Because every input ends with `sep`, the
|
|
198
|
+
// prefix check correctly distinguishes `/foo/bar/` (parent of `/foo/bar/baz/`)
|
|
199
|
+
// from `/foo/barista/` (sibling, not a parent).
|
|
200
|
+
//
|
|
201
|
+
// When a chain like `[grandparent, parent, child]` is provided, both
|
|
202
|
+
// `parent` and `child` are pruned and each emits a warning referencing the
|
|
203
|
+
// closest SURVIVING ancestor (the grandparent). This is the same result the
|
|
204
|
+
// user would have gotten by passing only the grandparent, and avoids the
|
|
205
|
+
// confusing case where a warning points at another path that was itself
|
|
206
|
+
// pruned. Implementation note: this runs in two passes over `deduped`. The
|
|
207
|
+
// pre-pass computes the `survivors` set (candidates with no ancestor in
|
|
208
|
+
// `deduped`); the main pass then resolves each candidate's closest ancestor
|
|
209
|
+
// against `survivors` so the reported parent is always a surviving root.
|
|
210
|
+
// The two `findParent` scans make this O(n^2) in the number of roots, which
|
|
211
|
+
// is harmless at realistic root counts.
|
|
212
|
+
const roots = [];
|
|
213
|
+
const warnings = [];
|
|
214
|
+
// Pre-pass: identify every candidate that has any ancestor in `deduped`
|
|
215
|
+
// (these are the pruned candidates). The candidates that do NOT have any
|
|
216
|
+
// ancestor in `deduped` are the surviving roots.
|
|
217
|
+
const survivors = [];
|
|
218
|
+
for (const candidate of deduped) {
|
|
219
|
+
if (findParent(candidate, deduped) === undefined) {
|
|
220
|
+
survivors.push(candidate);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
for (const candidate of deduped) {
|
|
224
|
+
const survivingAncestor = findParent(candidate, survivors);
|
|
225
|
+
if (survivingAncestor === undefined) {
|
|
226
|
+
// This candidate is itself a surviving root.
|
|
227
|
+
roots.push(candidate);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
warnings.push({
|
|
231
|
+
kind: 'nested-root-pruned',
|
|
232
|
+
message: `Nested base directory pruned: ${displayPath(candidate)} is inside ${displayPath(survivingAncestor)}. Keeping ${displayPath(survivingAncestor)} only.`,
|
|
233
|
+
parent: survivingAncestor,
|
|
234
|
+
pruned: candidate,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return { roots, warnings };
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Return the closest ancestor of `candidate` in `all` (excluding `candidate`
|
|
241
|
+
* itself), or `undefined` if no ancestor exists. Closest is measured by
|
|
242
|
+
* prefix length — longer prefix wins so we report the most specific
|
|
243
|
+
* surviving parent.
|
|
244
|
+
*/
|
|
245
|
+
function findParent(candidate, all) {
|
|
246
|
+
let best;
|
|
247
|
+
for (const other of all) {
|
|
248
|
+
if (other === candidate)
|
|
249
|
+
continue;
|
|
250
|
+
// `other` ends with `sep` (precondition), so this prefix check is
|
|
251
|
+
// sibling-prefix safe.
|
|
252
|
+
if (candidate.startsWith(other)) {
|
|
253
|
+
if (best === undefined || other.length > best.length) {
|
|
254
|
+
best = other;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return best;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Resolve effective base directories from CLI / env / cwd inputs.
|
|
262
|
+
*
|
|
263
|
+
* Resolution order (per the multi-base-dirs plan):
|
|
264
|
+
* 1. `cliRoots` (one or more `--base-dir` flags) — when non-empty, replaces
|
|
265
|
+
* env roots. CLI and env are never merged.
|
|
266
|
+
* 2. `envBaseDirs` (JSON array) — when CLI roots are absent.
|
|
267
|
+
* 3. `envBaseDir` (single path) — when CLI and `BASE_DIRS` are absent.
|
|
268
|
+
* 4. `cwd` — when none of the above are set.
|
|
269
|
+
*
|
|
270
|
+
* Warning rules:
|
|
271
|
+
* - `BASE_DIRS > BASE_DIR` precedence warning fires only when CLI roots are
|
|
272
|
+
* absent AND both `BASE_DIRS` and `BASE_DIR` are set. CLI-driven runs do
|
|
273
|
+
* not produce this warning even if both env vars are also set.
|
|
274
|
+
* - Nested-root pruning warnings always fire when applicable, regardless
|
|
275
|
+
* of which source provided the roots.
|
|
276
|
+
*
|
|
277
|
+
* Error rules:
|
|
278
|
+
* - Invalid `BASE_DIRS` (malformed JSON, non-array, empty array, empty
|
|
279
|
+
* string element, ...) returns `{ ok: false, error }`. The resolver does
|
|
280
|
+
* NOT fall back to `BASE_DIR` or `cwd` — callers surface the error per
|
|
281
|
+
* their UI contract (CLI exit code, MCP tool error, `status` diagnostic).
|
|
282
|
+
* - A path that fails realpath resolution (does not exist, not a directory,
|
|
283
|
+
* permission denied) also returns `{ ok: false, error }`. Roots must
|
|
284
|
+
* point at real directories the process is allowed to read.
|
|
285
|
+
*
|
|
286
|
+
* Post-resolution normalization:
|
|
287
|
+
* - Every selected path is realpath-normalized and gets a trailing path
|
|
288
|
+
* separator (see {@link normalizeRealpath}) so it can be used as a prefix
|
|
289
|
+
* in security checks.
|
|
290
|
+
* - Exact duplicates are silently deduplicated.
|
|
291
|
+
* - Nested roots are pruned with a warning (see {@link dedupAndPruneRoots}).
|
|
292
|
+
*/
|
|
293
|
+
export async function resolveBaseDirs(input) {
|
|
294
|
+
const selection = selectRoots(input);
|
|
295
|
+
if (!selection.ok) {
|
|
296
|
+
return selection;
|
|
297
|
+
}
|
|
298
|
+
const warnings = [];
|
|
299
|
+
if (selection.precedenceWarning) {
|
|
300
|
+
warnings.push(selection.precedenceWarning);
|
|
301
|
+
}
|
|
302
|
+
// Realpath-normalize each selected root. Failures (missing directory,
|
|
303
|
+
// permission denied, ...) are surfaced as a structured config error.
|
|
304
|
+
//
|
|
305
|
+
// Pair each realpath'd root (security form) with its resolve()-only form so
|
|
306
|
+
// `rawBaseDirs` mirrors the dedup/prune decisions index-for-index. See
|
|
307
|
+
// {@link BaseDirsConfig} for the path policy.
|
|
308
|
+
const normalized = [];
|
|
309
|
+
const realToRaw = new Map();
|
|
310
|
+
for (const root of selection.roots) {
|
|
311
|
+
let real;
|
|
312
|
+
try {
|
|
313
|
+
real = await normalizeRealpath(root);
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
if (error instanceof BaseDirsConfigError) {
|
|
317
|
+
return { ok: false, error };
|
|
318
|
+
}
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
normalized.push(real);
|
|
322
|
+
// First-occurrence-wins so the surviving raw root matches the first
|
|
323
|
+
// configured spelling of a root that realpaths to the same directory.
|
|
324
|
+
if (!realToRaw.has(real)) {
|
|
325
|
+
realToRaw.set(real, withTrailingSeparator(resolve(root)));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const { roots, warnings: pruningWarnings } = dedupAndPruneRoots(normalized);
|
|
329
|
+
warnings.push(...pruningWarnings);
|
|
330
|
+
// Project the surviving realpath'd roots back to their resolve()-only forms,
|
|
331
|
+
// preserving order so `rawBaseDirs[i]` and `baseDirs[i]` are the same root.
|
|
332
|
+
const rawRoots = roots.map((real) => realToRaw.get(real) ?? real);
|
|
333
|
+
return {
|
|
334
|
+
ok: true,
|
|
335
|
+
config: { baseDirs: roots, rawBaseDirs: rawRoots },
|
|
336
|
+
warnings,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Apply the source-precedence rules to pick which input set of roots to use.
|
|
341
|
+
*
|
|
342
|
+
* Kept as a small helper so the realpath normalization in
|
|
343
|
+
* {@link resolveBaseDirs} stays focused on I/O, not precedence logic. This
|
|
344
|
+
* function performs only string-level parsing and selection — no fs access.
|
|
345
|
+
*/
|
|
346
|
+
function selectRoots(input) {
|
|
347
|
+
// 1. CLI roots — when non-empty, replace env entirely (no precedence
|
|
348
|
+
// warning even if env vars are also set, because the user explicitly
|
|
349
|
+
// overrode them via CLI).
|
|
350
|
+
if (input.cliRoots !== undefined && input.cliRoots.length > 0) {
|
|
351
|
+
return { ok: true, roots: input.cliRoots };
|
|
352
|
+
}
|
|
353
|
+
// 2. BASE_DIRS — when CLI absent. Whitespace-only is treated as an
|
|
354
|
+
// invalid value (consistent with parseBaseDirsEnv), not as "unset",
|
|
355
|
+
// so the user notices a malformed env var instead of silently falling
|
|
356
|
+
// through to BASE_DIR.
|
|
357
|
+
if (input.envBaseDirs !== undefined && input.envBaseDirs.length > 0) {
|
|
358
|
+
const parsed = parseBaseDirsEnv(input.envBaseDirs);
|
|
359
|
+
if (!parsed.ok) {
|
|
360
|
+
return { ok: false, error: parsed.error };
|
|
361
|
+
}
|
|
362
|
+
const precedenceWarning = input.envBaseDir !== undefined && input.envBaseDir.trim().length > 0
|
|
363
|
+
? {
|
|
364
|
+
kind: 'base-dirs-overrides-base-dir',
|
|
365
|
+
message: 'BASE_DIRS is set; BASE_DIR is ignored. Unset BASE_DIR or remove BASE_DIRS to silence this warning.',
|
|
366
|
+
}
|
|
367
|
+
: undefined;
|
|
368
|
+
return precedenceWarning
|
|
369
|
+
? { ok: true, roots: parsed.value, precedenceWarning }
|
|
370
|
+
: { ok: true, roots: parsed.value };
|
|
371
|
+
}
|
|
372
|
+
// 3. BASE_DIR — when CLI and BASE_DIRS are absent. Whitespace-only is
|
|
373
|
+
// treated as "unset" (a user clearing the value with spaces gets the
|
|
374
|
+
// same behavior as not setting it at all).
|
|
375
|
+
if (input.envBaseDir !== undefined && input.envBaseDir.trim().length > 0) {
|
|
376
|
+
return { ok: true, roots: [input.envBaseDir] };
|
|
377
|
+
}
|
|
378
|
+
// 4. cwd — final fallback.
|
|
379
|
+
return { ok: true, roots: [input.cwd] };
|
|
380
|
+
}
|
|
381
|
+
// ============================================
|
|
382
|
+
// Legacy single-root accessor
|
|
383
|
+
// ============================================
|
|
384
|
+
/**
|
|
385
|
+
* Return the legacy single-root `baseDir` value for a {@link BaseDirsConfig}.
|
|
386
|
+
*
|
|
387
|
+
* Used for backward compatibility with consumers (and response fields) that
|
|
388
|
+
* pre-date the multi-root model. The contract is "first effective root after
|
|
389
|
+
* normalization and nested-root pruning"; callers must build the config via
|
|
390
|
+
* {@link dedupAndPruneRoots} for this to hold.
|
|
391
|
+
*/
|
|
392
|
+
export function legacyBaseDir(config) {
|
|
393
|
+
const first = config.baseDirs[0];
|
|
394
|
+
if (first === undefined) {
|
|
395
|
+
throw new BaseDirsConfigError('BaseDirsConfig must contain at least one base directory.');
|
|
396
|
+
}
|
|
397
|
+
return first;
|
|
398
|
+
}
|
|
399
|
+
// ============================================
|
|
400
|
+
// Private helpers
|
|
401
|
+
// ============================================
|
|
402
|
+
/**
|
|
403
|
+
* Describe a JSON value's shape for error messages without dumping its full
|
|
404
|
+
* (possibly large) content.
|
|
405
|
+
*/
|
|
406
|
+
function describeJsonShape(value) {
|
|
407
|
+
if (value === null)
|
|
408
|
+
return 'null';
|
|
409
|
+
if (Array.isArray(value))
|
|
410
|
+
return 'array';
|
|
411
|
+
return typeof value;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Truncate user-supplied input so configuration error messages stay readable
|
|
415
|
+
* even when the offending value is large.
|
|
416
|
+
*/
|
|
417
|
+
function truncate(input, max = 100) {
|
|
418
|
+
if (input.length <= max)
|
|
419
|
+
return input;
|
|
420
|
+
return `${input.slice(0, max)}...`;
|
|
421
|
+
}
|
|
422
|
+
//# 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,24 @@
|
|
|
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, cause?: Error);
|
|
15
|
+
}
|
|
16
|
+
/** Type guard: narrows an unknown value to the shared error taxonomy. */
|
|
17
|
+
export declare function isAppError(value: unknown): value is AppError;
|
|
18
|
+
/**
|
|
19
|
+
* Walks the `.cause` chain starting from `error`, returning errors in order
|
|
20
|
+
* `[outer, cause, cause.cause, ...]`. The walk stops at the first link whose
|
|
21
|
+
* `.cause` is not an `Error`. Self-referential chains are guarded against.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCauseChain(error: Error): Error[];
|
|
24
|
+
//# 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,aAAa,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,KAAK,EAO7F;CACF;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,53 @@
|
|
|
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, cause) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.layer = layer;
|
|
26
|
+
this.kind = kind;
|
|
27
|
+
if (cause !== undefined) {
|
|
28
|
+
this.cause = cause;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Type guard: narrows an unknown value to the shared error taxonomy. */
|
|
33
|
+
export function isAppError(value) {
|
|
34
|
+
return value instanceof AppError;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Walks the `.cause` chain starting from `error`, returning errors in order
|
|
38
|
+
* `[outer, cause, cause.cause, ...]`. The walk stops at the first link whose
|
|
39
|
+
* `.cause` is not an `Error`. Self-referential chains are guarded against.
|
|
40
|
+
*/
|
|
41
|
+
export function getCauseChain(error) {
|
|
42
|
+
const chain = [];
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
let current = error;
|
|
45
|
+
while (current !== undefined && !seen.has(current)) {
|
|
46
|
+
chain.push(current);
|
|
47
|
+
seen.add(current);
|
|
48
|
+
const next = current.cause;
|
|
49
|
+
current = next instanceof Error ? next : undefined;
|
|
50
|
+
}
|
|
51
|
+
return chain;
|
|
52
|
+
}
|
|
53
|
+
//# 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,YAAsB,OAAe,EAAE,KAAoB,EAAE,IAAkB,EAAE,KAAa;QAC5F,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QACpB,CAAC;IACH,CAAC;CACF;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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Cross-cutting numeric limits shared across CLI and MCP server entry points.
|
|
2
|
+
// Dependency-free leaf module so any layer can import it without coupling.
|
|
3
|
+
/**
|
|
4
|
+
* Maximum directory recursion depth when scanning a base directory or ingest
|
|
5
|
+
* target. Applied identically by the CLI `ingest`/`list` walkers and the MCP
|
|
6
|
+
* server's `list_files` scan so the boundary is consistent everywhere.
|
|
7
|
+
*/
|
|
8
|
+
export const MAX_SCAN_DEPTH = 10;
|
|
9
|
+
/**
|
|
10
|
+
* Default maximum file size for ingestion, in bytes (100 MB). Used when neither
|
|
11
|
+
* the CLI `--max-file-size` flag nor the `MAX_FILE_SIZE` env var is provided.
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_MAX_FILE_SIZE = 104_857_600;
|
|
14
|
+
/**
|
|
15
|
+
* Hard upper bound (inclusive) for the configurable max file size, in bytes
|
|
16
|
+
* (500 MB). Values above this are rejected by `validateMaxFileSize`.
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_FILE_SIZE_LIMIT = 524_288_000;
|
|
19
|
+
/** Inclusive result-count range shared by CLI, MCP validation, and VectorStore. */
|
|
20
|
+
export const MIN_QUERY_LIMIT = 1;
|
|
21
|
+
export const MAX_QUERY_LIMIT = 20;
|
|
22
|
+
/** Maximum number of adjacent chunks accepted on either side of a target. */
|
|
23
|
+
export const MAX_NEIGHBOR_COUNT = 50;
|
|
24
|
+
/** Inclusive upper bound for the configurable minimum chunk length. */
|
|
25
|
+
export const MAX_CHUNK_MIN_LENGTH = 10_000;
|
|
26
|
+
/** Maximum encoded bytes for one visual attachment returned with a chunk. */
|
|
27
|
+
export const MAX_VISUAL_RENDITION_BYTES = 512 * 1024;
|
|
28
|
+
//# sourceMappingURL=limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/utils/limits.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAE3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAA;AAEhC;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAA;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAA;AAE9C,mFAAmF;AACnF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAA;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAA;AAEjC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAA;AAEpC,uEAAuE;AACvE,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAE1C,6EAA6E;AAC7E,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,GAAG,IAAI,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ingested entry paired with its identity key (`realpathForMatch` of the
|
|
3
|
+
* stored `filePath`). Only the fields the classifier reads are required, so the
|
|
4
|
+
* caller's richer row type is consumed structurally.
|
|
5
|
+
*/
|
|
6
|
+
export interface KeyedIngestedEntry {
|
|
7
|
+
entry: {
|
|
8
|
+
filePath: string;
|
|
9
|
+
chunkCount: number;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
};
|
|
12
|
+
key: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A classified source: a raw-data entry restored to its original `source`, or a
|
|
16
|
+
* real-file / orphaned entry keyed by `filePath`. Structurally compatible with
|
|
17
|
+
* the `SourceEntry` union both surfaces already return (no type-move refactor).
|
|
18
|
+
*/
|
|
19
|
+
export type ClassifiedSource = {
|
|
20
|
+
source: string;
|
|
21
|
+
chunkCount: number;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
} | {
|
|
24
|
+
filePath: string;
|
|
25
|
+
chunkCount: number;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Classify the ingested entries that matched no scanned file into `sources`.
|
|
30
|
+
*
|
|
31
|
+
* Base filter (always): keep only entries whose `key` is absent from
|
|
32
|
+
* `matchedKeys`.
|
|
33
|
+
*
|
|
34
|
+
* When `scope` is present (non-empty): raw-data entries
|
|
35
|
+
* Managed raw-data entries have no filesystem path under a base directory, so
|
|
36
|
+
* they are always emitted regardless of scope; real-file entries are kept only
|
|
37
|
+
* when their stored `filePath` is under scope (`matchesAnyScope`) — a real-file
|
|
38
|
+
* entry outside scope is dropped so it appears in neither `files[]` (already
|
|
39
|
+
* pruned from the scan) nor `sources[]` (no orphan misclassification), while an
|
|
40
|
+
* unmatched real-file entry under scope remains an orphan source.
|
|
41
|
+
*
|
|
42
|
+
* When `scope` is absent (or empty): behavior is unchanged from the pre-extraction
|
|
43
|
+
* inline block — every unmatched entry is emitted, raw-data as `{ source }` when
|
|
44
|
+
* `extractSourceFromPath` yields one, else as `{ filePath }`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function classifyIngestedSources(ingestedKeyed: readonly KeyedIngestedEntry[], matchedKeys: ReadonlySet<string>, dbPath: string, scope?: string[]): ClassifiedSource[];
|
|
47
|
+
//# sourceMappingURL=list-sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-sources.d.ts","sourceRoot":"","sources":["../../src/utils/list-sources.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,SAAS,kBAAkB,EAAE,EAC5C,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,EAChC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EAAE,GACf,gBAAgB,EAAE,CAoBpB"}
|