@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.
- package/LICENSE +21 -0
- package/README.de.md +441 -0
- package/README.es.md +441 -0
- package/README.fr.md +441 -0
- package/README.md +530 -0
- package/README.pt-BR.md +441 -0
- package/README.zh-CN.md +441 -0
- package/dist/bin/install-skills.d.ts +19 -0
- package/dist/bin/install-skills.d.ts.map +1 -0
- package/dist/bin/install-skills.js +218 -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 +96 -0
- package/dist/chunker/semantic-chunker.d.ts.map +1 -0
- package/dist/chunker/semantic-chunker.js +362 -0
- package/dist/chunker/semantic-chunker.js.map +1 -0
- package/dist/chunker/sentence-splitter.d.ts +32 -0
- package/dist/chunker/sentence-splitter.d.ts.map +1 -0
- package/dist/chunker/sentence-splitter.js +231 -0
- package/dist/chunker/sentence-splitter.js.map +1 -0
- package/dist/chunker/token-containment.d.ts +39 -0
- package/dist/chunker/token-containment.d.ts.map +1 -0
- package/dist/chunker/token-containment.js +83 -0
- package/dist/chunker/token-containment.js.map +1 -0
- package/dist/cli/common.d.ts +34 -0
- package/dist/cli/common.d.ts.map +1 -0
- package/dist/cli/common.js +121 -0
- package/dist/cli/common.js.map +1 -0
- package/dist/cli/delete.d.ts +3 -0
- package/dist/cli/delete.d.ts.map +1 -0
- package/dist/cli/delete.js +169 -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 +69 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +323 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/list.d.ts +27 -0
- package/dist/cli/list.d.ts.map +1 -0
- package/dist/cli/list.js +207 -0
- package/dist/cli/list.js.map +1 -0
- package/dist/cli/options.d.ts +89 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +244 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/query.d.ts +17 -0
- package/dist/cli/query.d.ts.map +1 -0
- package/dist/cli/query.js +194 -0
- package/dist/cli/query.js.map +1 -0
- package/dist/cli/read-neighbors.d.ts +3 -0
- package/dist/cli/read-neighbors.d.ts.map +1 -0
- package/dist/cli/read-neighbors.js +192 -0
- package/dist/cli/read-neighbors.js.map +1 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +78 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync.d.ts +6 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +271 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli-main.d.ts +9 -0
- package/dist/cli-main.d.ts.map +1 -0
- package/dist/cli-main.js +60 -0
- package/dist/cli-main.js.map +1 -0
- package/dist/embedder/index.d.ts +143 -0
- package/dist/embedder/index.d.ts.map +1 -0
- package/dist/embedder/index.js +429 -0
- package/dist/embedder/index.js.map +1 -0
- package/dist/embedder/remote.d.ts +51 -0
- package/dist/embedder/remote.d.ts.map +1 -0
- package/dist/embedder/remote.js +182 -0
- package/dist/embedder/remote.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 +41 -0
- package/dist/features/list.js.map +1 -0
- package/dist/features/sync.d.ts +219 -0
- package/dist/features/sync.d.ts.map +1 -0
- package/dist/features/sync.js +461 -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 +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/compute.d.ts +63 -0
- package/dist/ingest/compute.d.ts.map +1 -0
- package/dist/ingest/compute.js +161 -0
- package/dist/ingest/compute.js.map +1 -0
- package/dist/ingest/file.d.ts +40 -0
- package/dist/ingest/file.d.ts.map +1 -0
- package/dist/ingest/file.js +74 -0
- package/dist/ingest/file.js.map +1 -0
- package/dist/ingest/visual.d.ts +52 -0
- package/dist/ingest/visual.d.ts.map +1 -0
- package/dist/ingest/visual.js +294 -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 +375 -0
- package/dist/parser/docx-parser.js.map +1 -0
- package/dist/parser/html-parser.d.ts +16 -0
- package/dist/parser/html-parser.d.ts.map +1 -0
- package/dist/parser/html-parser.js +119 -0
- package/dist/parser/html-parser.js.map +1 -0
- package/dist/parser/index.d.ts +125 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +364 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/pdf-extract.d.ts +49 -0
- package/dist/parser/pdf-extract.d.ts.map +1 -0
- package/dist/parser/pdf-extract.js +114 -0
- package/dist/parser/pdf-extract.js.map +1 -0
- package/dist/parser/pdf-filter.d.ts +91 -0
- package/dist/parser/pdf-filter.d.ts.map +1 -0
- package/dist/parser/pdf-filter.js +522 -0
- package/dist/parser/pdf-filter.js.map +1 -0
- package/dist/parser/title-extractor.d.ts +28 -0
- package/dist/parser/title-extractor.d.ts.map +1 -0
- package/dist/parser/title-extractor.js +105 -0
- package/dist/parser/title-extractor.js.map +1 -0
- package/dist/pdf-visual/captioner.d.ts +11 -0
- package/dist/pdf-visual/captioner.d.ts.map +1 -0
- package/dist/pdf-visual/captioner.js +48 -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 +108 -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 +101 -0
- package/dist/pdf-visual/captioners/quality.js.map +1 -0
- package/dist/pdf-visual/captioners/shared.d.ts +81 -0
- package/dist/pdf-visual/captioners/shared.d.ts.map +1 -0
- package/dist/pdf-visual/captioners/shared.js +156 -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 +269 -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 +53 -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 +186 -0
- package/dist/pdf-visual/renderer.js.map +1 -0
- package/dist/pdf-visual/types.d.ts +53 -0
- package/dist/pdf-visual/types.d.ts.map +1 -0
- package/dist/pdf-visual/types.js +17 -0
- package/dist/pdf-visual/types.js.map +1 -0
- package/dist/server/error-utils.d.ts +63 -0
- package/dist/server/error-utils.d.ts.map +1 -0
- package/dist/server/error-utils.js +124 -0
- package/dist/server/error-utils.js.map +1 -0
- package/dist/server/index.d.ts +216 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1068 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/list-scanner.d.ts +30 -0
- package/dist/server/list-scanner.d.ts.map +1 -0
- package/dist/server/list-scanner.js +50 -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 +211 -0
- package/dist/server/tool-input.js.map +1 -0
- package/dist/server/types.d.ts +307 -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 +40 -0
- package/dist/server-main.d.ts.map +1 -0
- package/dist/server-main.js +254 -0
- package/dist/server-main.js.map +1 -0
- package/dist/utils/base-dirs.d.ts +145 -0
- package/dist/utils/base-dirs.d.ts.map +1 -0
- package/dist/utils/base-dirs.js +344 -0
- package/dist/utils/base-dirs.js.map +1 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -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 +38 -0
- package/dist/utils/list-sources.d.ts.map +1 -0
- package/dist/utils/list-sources.js +40 -0
- package/dist/utils/list-sources.js.map +1 -0
- package/dist/utils/raw-data-utils.d.ts +76 -0
- package/dist/utils/raw-data-utils.d.ts.map +1 -0
- package/dist/utils/raw-data-utils.js +202 -0
- package/dist/utils/raw-data-utils.js.map +1 -0
- package/dist/utils/scan.d.ts +114 -0
- package/dist/utils/scan.d.ts.map +1 -0
- package/dist/utils/scan.js +209 -0
- package/dist/utils/scan.js.map +1 -0
- package/dist/utils/scope-match.d.ts +38 -0
- package/dist/utils/scope-match.d.ts.map +1 -0
- package/dist/utils/scope-match.js +86 -0
- package/dist/utils/scope-match.js.map +1 -0
- package/dist/utils/sensitive-path.d.ts +9 -0
- package/dist/utils/sensitive-path.d.ts.map +1 -0
- package/dist/utils/sensitive-path.js +78 -0
- package/dist/utils/sensitive-path.js.map +1 -0
- package/dist/utils/sync-path-key.d.ts +14 -0
- package/dist/utils/sync-path-key.d.ts.map +1 -0
- package/dist/utils/sync-path-key.js +27 -0
- package/dist/utils/sync-path-key.js.map +1 -0
- package/dist/utils/type-guards.d.ts +18 -0
- package/dist/utils/type-guards.d.ts.map +1 -0
- package/dist/utils/type-guards.js +34 -0
- package/dist/utils/type-guards.js.map +1 -0
- package/dist/utils/visual-profile.d.ts +10 -0
- package/dist/utils/visual-profile.d.ts.map +1 -0
- package/dist/utils/visual-profile.js +15 -0
- package/dist/utils/visual-profile.js.map +1 -0
- package/dist/vectordb/index.d.ts +132 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +617 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/search-filters.d.ts +15 -0
- package/dist/vectordb/search-filters.d.ts.map +1 -0
- package/dist/vectordb/search-filters.js +129 -0
- package/dist/vectordb/search-filters.js.map +1 -0
- package/dist/vectordb/types.d.ts +194 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +237 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +108 -0
- package/skills/mcp-local-rag/SKILL.md +234 -0
- package/skills/mcp-local-rag/references/cli-reference.md +190 -0
- package/skills/mcp-local-rag/references/html-ingestion.md +78 -0
package/dist/cli/sync.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
// CLI sync subcommand — foreground incremental reconciliation.
|
|
2
|
+
//
|
|
3
|
+
// Composition root for `src/features/sync.ts`: supplies the real collaborators
|
|
4
|
+
// and renders the result. Planning, prune eligibility, execution order and the
|
|
5
|
+
// stop-on-first-error policy all live in the core, including the
|
|
6
|
+
// "inside a configured root" check.
|
|
7
|
+
//
|
|
8
|
+
// The run stays attached to the process: backgrounding and polling belong to
|
|
9
|
+
// the caller, so there is no daemon or watchdog here.
|
|
10
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
11
|
+
import { resolve, sep } from 'node:path';
|
|
12
|
+
import { SemanticChunker } from '../chunker/index.js';
|
|
13
|
+
import { formatSyncError, runSync as runSyncCore, } from '../features/sync.js';
|
|
14
|
+
import { computeContentHash } from '../ingest/compute.js';
|
|
15
|
+
import { DocumentParser } from '../parser/index.js';
|
|
16
|
+
import { MAX_SCAN_DEPTH } from '../utils/limits.js';
|
|
17
|
+
import { bfsCollectSupportedFiles, canonicalizeRequestedPath, classifyRequestedPath, } from '../utils/scan.js';
|
|
18
|
+
import { createEmbedder, createVectorStore, formatCliError } from './common.js';
|
|
19
|
+
import { buildFileIngestOptions, ingestSingleFile, resolveConfig } from './ingest.js';
|
|
20
|
+
import { consumeBaseDirArg, requireVisualQuality, resolveGlobalConfig } from './options.js';
|
|
21
|
+
// ============================================
|
|
22
|
+
// Help
|
|
23
|
+
// ============================================
|
|
24
|
+
const HELP_TEXT = `Usage: mcp-local-rag [global-options] sync [options] [path]
|
|
25
|
+
|
|
26
|
+
Reconcile the index with the files on disk: ingest new and changed files, leave
|
|
27
|
+
unchanged files alone, and remove index entries for files that are gone.
|
|
28
|
+
|
|
29
|
+
Each changed PDF keeps the visual profile it was last indexed with; a new PDF,
|
|
30
|
+
or one indexed before profiles were recorded, stays text-only. Use --visual to
|
|
31
|
+
request VLM captioning for every PDF in scope instead, which also establishes a
|
|
32
|
+
profile for those PDFs. A PDF is re-ingested when its bytes or its profile
|
|
33
|
+
differ from what is indexed, and skipped otherwise. To turn visual mode off
|
|
34
|
+
for a path, run "ingest <path>": a successful normal ingest clears the recorded
|
|
35
|
+
profile. To retry a failed caption, run "ingest <path> --visual
|
|
36
|
+
--visual-quality <profile>" with the profile you want, because a plain ingest
|
|
37
|
+
clears it. Image storage is separate: --images is never recorded and never
|
|
38
|
+
makes a file changed.
|
|
39
|
+
|
|
40
|
+
Runs in the foreground until it finishes. Use your shell to run it in the
|
|
41
|
+
background.
|
|
42
|
+
|
|
43
|
+
Arguments:
|
|
44
|
+
<path> File or directory inside a configured base directory
|
|
45
|
+
(default: every configured base directory)
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--base-dir <path> Document root (repeatable; overrides environment roots)
|
|
49
|
+
--images Store images for new/changed PDF and DOCX files
|
|
50
|
+
--visual Request VLM captioning for every PDF in scope, overriding
|
|
51
|
+
each PDF's recorded profile (PDFs only)
|
|
52
|
+
--visual-quality <profile>
|
|
53
|
+
VLM profile when --visual is set: fast (default,
|
|
54
|
+
lightweight) or quality (Qwen2.5-VL-3B, ~10x cache,
|
|
55
|
+
~2x inference)
|
|
56
|
+
-h, --help Show this help
|
|
57
|
+
|
|
58
|
+
Without --base-dir, roots come from BASE_DIRS / BASE_DIR (default: current directory).
|
|
59
|
+
|
|
60
|
+
Global options (must appear before "sync"):
|
|
61
|
+
--db-path <path> LanceDB database path
|
|
62
|
+
--cache-dir <path> Model cache directory
|
|
63
|
+
--model-name <name> Embedding model`;
|
|
64
|
+
/**
|
|
65
|
+
* Parse sync-specific CLI arguments: repeatable roots, at most one positional
|
|
66
|
+
* path, and -h/--help. Unknown flags still print the usage and exit 1.
|
|
67
|
+
*/
|
|
68
|
+
function parseArgs(args) {
|
|
69
|
+
let help = false;
|
|
70
|
+
const baseDirs = [];
|
|
71
|
+
let path;
|
|
72
|
+
let images = false;
|
|
73
|
+
let visual = false;
|
|
74
|
+
let visualQuality;
|
|
75
|
+
let index = 0;
|
|
76
|
+
while (index < args.length) {
|
|
77
|
+
const arg = args[index] ?? '';
|
|
78
|
+
switch (arg) {
|
|
79
|
+
case '-h':
|
|
80
|
+
case '--help':
|
|
81
|
+
help = true;
|
|
82
|
+
index++;
|
|
83
|
+
break;
|
|
84
|
+
case '--base-dir': {
|
|
85
|
+
const valueIndex = consumeBaseDirArg(args, index, baseDirs);
|
|
86
|
+
index = valueIndex + 1;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case '--images':
|
|
90
|
+
images = true;
|
|
91
|
+
index++;
|
|
92
|
+
break;
|
|
93
|
+
case '--visual':
|
|
94
|
+
visual = true;
|
|
95
|
+
index++;
|
|
96
|
+
break;
|
|
97
|
+
case '--visual-quality':
|
|
98
|
+
visualQuality = requireVisualQuality(args, index);
|
|
99
|
+
index += 2;
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
if (arg.startsWith('-')) {
|
|
103
|
+
console.error(`Unknown option: ${arg}`);
|
|
104
|
+
console.error(HELP_TEXT);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
if (path !== undefined) {
|
|
108
|
+
console.error(`Unexpected argument: ${arg}`);
|
|
109
|
+
console.error('Only one path is accepted. Omit it to sync every configured base directory.');
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
path = arg;
|
|
113
|
+
index++;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const parsed = { help, baseDirs, images, visual };
|
|
118
|
+
if (path !== undefined) {
|
|
119
|
+
parsed.path = path;
|
|
120
|
+
}
|
|
121
|
+
if (visualQuality !== undefined) {
|
|
122
|
+
parsed.visualQuality = visualQuality;
|
|
123
|
+
}
|
|
124
|
+
return parsed;
|
|
125
|
+
}
|
|
126
|
+
// ============================================
|
|
127
|
+
// Reporting
|
|
128
|
+
// ============================================
|
|
129
|
+
/**
|
|
130
|
+
* Render the scanner's coverage facts as operator warnings. Each unobserved
|
|
131
|
+
* region is why prune was withheld there, so the path is named; the wording
|
|
132
|
+
* itself is not a contract.
|
|
133
|
+
*/
|
|
134
|
+
function coverageWarnings(coverage, maxFileSize) {
|
|
135
|
+
return [
|
|
136
|
+
...coverage.unreadableDirs.map(({ dirPath, code }) => `Warning: cannot read directory (${code}), so its indexed files were kept: ${dirPath}`),
|
|
137
|
+
...coverage.depthLimitedDirs.map((dirPath) => `Warning: not scanned because it exceeds the maximum depth (${MAX_SCAN_DEPTH}), so its indexed files were kept: ${dirPath}`),
|
|
138
|
+
...coverage.skippedSymlinks.map((linkPath) => `Warning: symbolic link not followed, so its indexed files were kept: ${linkPath}`),
|
|
139
|
+
...coverage.oversizedFiles.map((filePath) => `Warning: not read because it exceeds the maximum file size (${maxFileSize} bytes), so its indexed chunks were kept: ${filePath}`),
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
// ============================================
|
|
143
|
+
// Main Entry Point
|
|
144
|
+
// ============================================
|
|
145
|
+
/**
|
|
146
|
+
* Run the sync CLI subcommand.
|
|
147
|
+
*/
|
|
148
|
+
export async function runSync(args, globalOptions = {}) {
|
|
149
|
+
const parsed = parseArgs(args);
|
|
150
|
+
if (parsed.help) {
|
|
151
|
+
console.error(HELP_TEXT);
|
|
152
|
+
process.exit(0);
|
|
153
|
+
}
|
|
154
|
+
const globalConfig = resolveGlobalConfig(globalOptions);
|
|
155
|
+
// Shared with `ingest`: CLI roots replace BASE_DIRS / BASE_DIR / cwd; an empty
|
|
156
|
+
// array preserves that environment fallback. Size/chunk settings share the
|
|
157
|
+
// same resolution and validation path.
|
|
158
|
+
const config = await resolveConfig(globalConfig, { baseDirs: parsed.baseDirs });
|
|
159
|
+
for (const warning of config.baseDirsWarnings) {
|
|
160
|
+
console.error(warning.message);
|
|
161
|
+
}
|
|
162
|
+
const excludePaths = [`${resolve(config.dbPath)}${sep}`, `${resolve(config.cacheDir)}${sep}`];
|
|
163
|
+
const vectorStore = createVectorStore(globalConfig);
|
|
164
|
+
// The parser's realpath check is the security boundary, so it takes the
|
|
165
|
+
// realpath'd roots; scanning uses the resolve()-only `rawBaseDirs` so scanned
|
|
166
|
+
// paths match the resolve()-stored DB keys (same split as `list`).
|
|
167
|
+
const parser = new DocumentParser({
|
|
168
|
+
baseDirs: config.baseDirs.baseDirs,
|
|
169
|
+
maxFileSize: config.maxFileSize,
|
|
170
|
+
});
|
|
171
|
+
const chunker = new SemanticChunker(config.chunkMinLength !== undefined ? { minChunkLength: config.chunkMinLength } : {});
|
|
172
|
+
// Built on the first upsert only: a run with nothing to ingest must not pay
|
|
173
|
+
// for the embedding model.
|
|
174
|
+
let embedder;
|
|
175
|
+
const ensureEmbedder = () => {
|
|
176
|
+
embedder ??= createEmbedder(globalConfig);
|
|
177
|
+
return embedder;
|
|
178
|
+
};
|
|
179
|
+
const collaborators = {
|
|
180
|
+
// The containment boundary for a requested path: the core compares this
|
|
181
|
+
// canonical form against the realpath'd roots, which is the only way to see
|
|
182
|
+
// that an intermediate component is a symbolic link out of the root.
|
|
183
|
+
canonicalizeRequestedPath,
|
|
184
|
+
// The walker's own predicates, so an explicitly requested path is subject to
|
|
185
|
+
// the same rules as a discovered one and is refused before it is read.
|
|
186
|
+
classifyPath: async (path) => await classifyRequestedPath(path, excludePaths),
|
|
187
|
+
// No `scope` argument, on purpose: a scope-pruned directory appears in none
|
|
188
|
+
// of the coverage arrays, which would hide an unobserved region and make
|
|
189
|
+
// prune unsafe.
|
|
190
|
+
scanDir: async (rootPath) => await bfsCollectSupportedFiles(rootPath, excludePaths, { maxDepth: MAX_SCAN_DEPTH }),
|
|
191
|
+
// Size first, bytes second: `MAX_FILE_SIZE` is otherwise enforced inside
|
|
192
|
+
// the parser, long after the whole file is already in memory here.
|
|
193
|
+
// Declining (`null`) keeps the rest of the run usable rather than aborting
|
|
194
|
+
// every future sync of the root over one oversized file.
|
|
195
|
+
//
|
|
196
|
+
// The bound holds only against a non-racing filesystem: a writer that grows
|
|
197
|
+
// the file between the `stat` and the `readFile` restores the unbounded
|
|
198
|
+
// read. That actor already has local write access as this user and can
|
|
199
|
+
// reach the database directly, so this is a recorded limitation.
|
|
200
|
+
hashFile: async (filePath) => {
|
|
201
|
+
if ((await stat(filePath)).size > config.maxFileSize) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return computeContentHash(await readFile(filePath));
|
|
205
|
+
},
|
|
206
|
+
loadDbManifest: async () => await vectorStore.listSyncManifest(),
|
|
207
|
+
// Named as it happens, so a long run shows which file it is on and the
|
|
208
|
+
// counters alone are not the only record of what changed. A zero-chunk file
|
|
209
|
+
// already reports itself from inside `ingestSingleFile`.
|
|
210
|
+
ingestFile: async (filePath, options) => {
|
|
211
|
+
const chunkCount = await ingestSingleFile(filePath, { parser, chunker, embedder: ensureEmbedder(), vectorStore }, buildFileIngestOptions(options, globalConfig));
|
|
212
|
+
if (chunkCount > 0) {
|
|
213
|
+
console.error(`upserted ${filePath} (${chunkCount} chunks)`);
|
|
214
|
+
}
|
|
215
|
+
return chunkCount;
|
|
216
|
+
},
|
|
217
|
+
deleteExactPath: async (filePath) => await vectorStore.deleteChunks(filePath),
|
|
218
|
+
optimize: async () => {
|
|
219
|
+
await vectorStore.optimize();
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
try {
|
|
223
|
+
await vectorStore.initialize();
|
|
224
|
+
const result = await runSyncCore({
|
|
225
|
+
roots: config.baseDirs.rawBaseDirs,
|
|
226
|
+
// The realpath'd counterpart of the same roots, which is what the core
|
|
227
|
+
// decides requested-path containment in (the parser's boundary domain).
|
|
228
|
+
canonicalRoots: config.baseDirs.baseDirs,
|
|
229
|
+
dbPath: config.dbPath,
|
|
230
|
+
excludePaths,
|
|
231
|
+
platform: process.platform,
|
|
232
|
+
// resolve() (never realpath) so the requested path is spelled like the
|
|
233
|
+
// stored DB keys; the core validates it against the configured roots.
|
|
234
|
+
...(parsed.path === undefined ? {} : { requestedPath: resolve(parsed.path) }),
|
|
235
|
+
...(parsed.images ? { images: true } : {}),
|
|
236
|
+
// Only `--visual` makes the request explicit. Without it the core lets
|
|
237
|
+
// each PDF inherit its recorded profile, so a bare `--visual-quality` is
|
|
238
|
+
// parsed (and validated) but has no effect.
|
|
239
|
+
...(parsed.visual ? { visualProfile: parsed.visualQuality ?? 'fast' } : {}),
|
|
240
|
+
collaborators,
|
|
241
|
+
});
|
|
242
|
+
for (const prunedPath of result.prunedPaths) {
|
|
243
|
+
console.error(`pruned ${prunedPath}`);
|
|
244
|
+
}
|
|
245
|
+
for (const warning of coverageWarnings(result.coverage, config.maxFileSize)) {
|
|
246
|
+
console.error(warning);
|
|
247
|
+
}
|
|
248
|
+
if (result.error !== null) {
|
|
249
|
+
console.error(`Error: ${formatSyncError(result.error)}`);
|
|
250
|
+
process.exitCode = 1;
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
process.stdout.write(JSON.stringify({
|
|
254
|
+
upserted: result.upserted,
|
|
255
|
+
skipped: result.skipped,
|
|
256
|
+
empty: result.empty,
|
|
257
|
+
pruned: result.pruned,
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
console.error(`Error: ${formatCliError(error)}`);
|
|
262
|
+
process.exitCode = 1;
|
|
263
|
+
}
|
|
264
|
+
finally {
|
|
265
|
+
if (embedder !== undefined) {
|
|
266
|
+
await embedder.dispose();
|
|
267
|
+
}
|
|
268
|
+
await vectorStore.close();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GlobalOptions } from './cli/options.js';
|
|
2
|
+
export declare const SUBCOMMANDS: readonly ['skills', 'ingest', 'list', 'query', 'status', 'delete', 'read-neighbors', 'sync'];
|
|
3
|
+
export type Subcommand = (typeof SUBCOMMANDS)[number];
|
|
4
|
+
/**
|
|
5
|
+
* Handle CLI subcommands. The caller is expected to have already validated
|
|
6
|
+
* `subcommand` against `SUBCOMMANDS`; the union type makes the switch exhaustive.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleCli(subcommand: Subcommand, args: string[], globalOptions?: GlobalOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=cli-main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAMrD,eAAO,MAAM,WAAW,YACtB,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,MAAM,CACE,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAErD;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EAAE,EACd,aAAa,GAAE,aAAkB,GAChC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|
package/dist/cli-main.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// CLI entry point for subcommands (skills install, etc.)
|
|
2
|
+
import { run as runSkillsInstall } from './bin/install-skills.js';
|
|
3
|
+
import { runDelete } from './cli/delete.js';
|
|
4
|
+
import { runIngest } from './cli/ingest.js';
|
|
5
|
+
import { runList } from './cli/list.js';
|
|
6
|
+
import { runQuery } from './cli/query.js';
|
|
7
|
+
import { runReadNeighbors } from './cli/read-neighbors.js';
|
|
8
|
+
import { runStatus } from './cli/status.js';
|
|
9
|
+
import { runSync } from './cli/sync.js';
|
|
10
|
+
export const SUBCOMMANDS = [
|
|
11
|
+
'skills',
|
|
12
|
+
'ingest',
|
|
13
|
+
'list',
|
|
14
|
+
'query',
|
|
15
|
+
'status',
|
|
16
|
+
'delete',
|
|
17
|
+
'read-neighbors',
|
|
18
|
+
'sync',
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Handle CLI subcommands. The caller is expected to have already validated
|
|
22
|
+
* `subcommand` against `SUBCOMMANDS`; the union type makes the switch exhaustive.
|
|
23
|
+
*/
|
|
24
|
+
export async function handleCli(subcommand, args, globalOptions = {}) {
|
|
25
|
+
switch (subcommand) {
|
|
26
|
+
case 'skills':
|
|
27
|
+
if (args[0] === 'install') {
|
|
28
|
+
runSkillsInstall(args.slice(1));
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.error('Unknown skills subcommand. Usage: npx mcp-local-rag skills install [options]');
|
|
33
|
+
console.error('Run "npx mcp-local-rag skills install --help" for more information.');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
case 'ingest':
|
|
38
|
+
await runIngest(args, globalOptions);
|
|
39
|
+
break;
|
|
40
|
+
case 'list':
|
|
41
|
+
await runList(args, globalOptions);
|
|
42
|
+
break;
|
|
43
|
+
case 'query':
|
|
44
|
+
await runQuery(args, globalOptions);
|
|
45
|
+
break;
|
|
46
|
+
case 'status':
|
|
47
|
+
await runStatus(args, globalOptions);
|
|
48
|
+
break;
|
|
49
|
+
case 'delete':
|
|
50
|
+
await runDelete(args, globalOptions);
|
|
51
|
+
break;
|
|
52
|
+
case 'read-neighbors':
|
|
53
|
+
await runReadNeighbors(args, globalOptions);
|
|
54
|
+
break;
|
|
55
|
+
case 'sync':
|
|
56
|
+
await runSync(args, globalOptions);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=cli-main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-main.js","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,gBAAgB;IAChB,MAAM;CACE,CAAA;AAIV;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,UAAsB,EACtB,IAAc,EACd,aAAa,GAAkB,EAAE;IAEjC,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1B,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;gBAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CACX,8EAA8E,CAC/E,CAAA;gBACD,OAAO,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAA;gBACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,MAAK;QAEP,KAAK,QAAQ;YACX,MAAM,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACpC,MAAK;QAEP,KAAK,MAAM;YACT,MAAM,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAClC,MAAK;QAEP,KAAK,OAAO;YACV,MAAM,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACnC,MAAK;QAEP,KAAK,QAAQ;YACX,MAAM,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACpC,MAAK;QAEP,KAAK,QAAQ;YACX,MAAM,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACpC,MAAK;QAEP,KAAK,gBAAgB;YACnB,MAAM,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAC3C,MAAK;QAEP,KAAK,MAAM;YACT,MAAM,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YAClC,MAAK;IACT,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { AppError } from '../utils/errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Embedder configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface EmbedderConfig {
|
|
6
|
+
/** HuggingFace model path */
|
|
7
|
+
modelPath: string;
|
|
8
|
+
/** Batch size */
|
|
9
|
+
batchSize: number;
|
|
10
|
+
/** Model cache directory */
|
|
11
|
+
cacheDir: string;
|
|
12
|
+
/** Device type */
|
|
13
|
+
device?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Quantization dtype, passed through to transformers.js with no allowlist.
|
|
16
|
+
* `undefined` means unset, which `initialize()` resolves to fp32 — the
|
|
17
|
+
* distinction gates failure-path error enrichment, so keep it.
|
|
18
|
+
*/
|
|
19
|
+
dtype?: string;
|
|
20
|
+
}
|
|
21
|
+
interface TokenizerOptions {
|
|
22
|
+
padding?: boolean;
|
|
23
|
+
truncation?: boolean;
|
|
24
|
+
return_tensor?: boolean;
|
|
25
|
+
max_length?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface PipelineTokenizer {
|
|
28
|
+
(input: string[], options: TokenizerOptions): {
|
|
29
|
+
input_ids?: unknown;
|
|
30
|
+
} | null | undefined;
|
|
31
|
+
/** `unknown` because a model may omit it or report a sentinel; see {@link usableTokenLimit}. */
|
|
32
|
+
model_max_length?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface TokenLimitClamp {
|
|
35
|
+
/** The effective token cap, or `null` for degraded mode (no cap, no clamp). */
|
|
36
|
+
tokenLimit: number | null;
|
|
37
|
+
/** The pre-clamp tokenizer, for measuring true lengths. */
|
|
38
|
+
measurementTokenizer: PipelineTokenizer | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Bound the pipeline's tokenization length to the model's position window, by
|
|
42
|
+
* installing a proxy on `candidate`'s tokenizer.
|
|
43
|
+
*
|
|
44
|
+
* The pipeline tokenizes with no `max_length`, which resolves to
|
|
45
|
+
* `model_max_length ?? Infinity` and then to the batch's longest sequence, so a
|
|
46
|
+
* model whose `tokenizer_config.json` omits a real limit sends more positions
|
|
47
|
+
* than it has position embeddings and onnxruntime fails in the
|
|
48
|
+
* position-embedding `Add` node (#202).
|
|
49
|
+
*
|
|
50
|
+
* The measurement tokenizer is captured before the proxy, so measurement
|
|
51
|
+
* reports true lengths. A `Proxy` is used because `model_max_length` is a getter
|
|
52
|
+
* with no setter. An unrecognized shape, or no usable limit, leaves `candidate`
|
|
53
|
+
* untouched.
|
|
54
|
+
*/
|
|
55
|
+
export declare function installTokenLimitClamp(candidate: unknown): TokenLimitClamp;
|
|
56
|
+
/**
|
|
57
|
+
* Embedding generation error
|
|
58
|
+
*/
|
|
59
|
+
export declare class EmbeddingError extends AppError {
|
|
60
|
+
constructor(message: string, options?: {
|
|
61
|
+
cause?: Error;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Transformers.js wrapper: lazily loaded model, batched embedding. */
|
|
65
|
+
export declare class Embedder {
|
|
66
|
+
private model;
|
|
67
|
+
private initPromise;
|
|
68
|
+
/** The resolved cap, or `null` before initialization and in degraded mode. */
|
|
69
|
+
private tokenLimit;
|
|
70
|
+
/** The pre-clamp tokenizer, so measurement never reports clamped lengths. */
|
|
71
|
+
private measurementTokenizer;
|
|
72
|
+
/**
|
|
73
|
+
* One-shot flags, per instance: each state belongs to this embedder's model.
|
|
74
|
+
* They survive `dispose()`; re-initialization is not new information.
|
|
75
|
+
*/
|
|
76
|
+
private truncationWarned;
|
|
77
|
+
private degradedModeWarned;
|
|
78
|
+
private readonly config;
|
|
79
|
+
constructor(config: EmbedderConfig);
|
|
80
|
+
/**
|
|
81
|
+
* Release resources held by the Embedder pipeline
|
|
82
|
+
*/
|
|
83
|
+
dispose(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Initialize Transformers.js model
|
|
86
|
+
*/
|
|
87
|
+
initialize(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Best-effort failure-path enrichment for an explicit `RAG_DTYPE`: name the
|
|
90
|
+
* dtypes the model does provide when the requested one is absent.
|
|
91
|
+
*
|
|
92
|
+
* The enumeration is a Hub network call in its own try/catch, so an
|
|
93
|
+
* air-gapped run degrades to a generic dtype-aware message instead of
|
|
94
|
+
* surfacing a confusing secondary error. Never throws, and never converts
|
|
95
|
+
* the load failure into a fallback — the caller always re-throws.
|
|
96
|
+
*/
|
|
97
|
+
private enrichDtypeFailureMessage;
|
|
98
|
+
/**
|
|
99
|
+
* Ensure model is initialized (lazy initialization)
|
|
100
|
+
* This method is called automatically by embed() and embedBatch()
|
|
101
|
+
*/
|
|
102
|
+
private ensureInitialized;
|
|
103
|
+
/**
|
|
104
|
+
* The effective token cap, or `null` when none could be resolved.
|
|
105
|
+
*
|
|
106
|
+
* Self-initializing: the value exists only after the model loads, and a
|
|
107
|
+
* caller may need it before the first embedding.
|
|
108
|
+
*/
|
|
109
|
+
getTokenLimit(): Promise<number | null>;
|
|
110
|
+
/**
|
|
111
|
+
* Report once that no cap was resolved. Warning here rather than in
|
|
112
|
+
* `initialize()` covers every consumer, which all read the cap through
|
|
113
|
+
* {@link getTokenLimit}.
|
|
114
|
+
*/
|
|
115
|
+
private warnDegradedMode;
|
|
116
|
+
/**
|
|
117
|
+
* The lengths batch planning runs on: `min(trueLength, cap)`, the length the
|
|
118
|
+
* clamped pipeline actually feeds the model. Warns once when a true length
|
|
119
|
+
* exceeds the cap.
|
|
120
|
+
*/
|
|
121
|
+
private planTokenLengths;
|
|
122
|
+
/**
|
|
123
|
+
* The true token length of each text, in input order. Tokenization only, no
|
|
124
|
+
* inference.
|
|
125
|
+
*
|
|
126
|
+
* Measured with `truncation: false` through the pre-clamp tokenizer, so a
|
|
127
|
+
* length above {@link getTokenLimit} means inference will truncate. Throws
|
|
128
|
+
* when no such tokenizer was captured, rather than returning a length
|
|
129
|
+
* measured through an unknown surface.
|
|
130
|
+
*/
|
|
131
|
+
countTokens(texts: string[]): Promise<number[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Single-text embedding; the vector dimension depends on the model.
|
|
134
|
+
*
|
|
135
|
+
* Delegates to {@link embedBatch} so this path shares its clamp, measurement
|
|
136
|
+
* and warning rather than reaching the pipeline unguarded.
|
|
137
|
+
*/
|
|
138
|
+
embed(text: string): Promise<number[]>;
|
|
139
|
+
/** Batched embedding; the vector dimension depends on the model. */
|
|
140
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
141
|
+
}
|
|
142
|
+
export {};
|
|
143
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/embedder/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,QAAQ,EAAW,MAAM,oBAAoB,CAAA;AAOtD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAQD,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAA;IACxF,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AA6CD,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,2DAA2D;IAC3D,oBAAoB,EAAE,iBAAiB,GAAG,IAAI,CAAA;CAC/C;AA4BD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,eAAe,CAyB1E;AAkED;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,EAGvD;CACF;AAMD,uEAAuE;AACvE,qBAAa,QAAQ;IAEnB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,WAAW,CAA6B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,UAAU,CAAsB;IACxC,6EAA6E;IAC7E,OAAO,CAAC,oBAAoB,CAAiC;IAC7D;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAiB;IACzC,OAAO,CAAC,kBAAkB,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC,YAAY,MAAM,EAAE,cAAc,EAEjC;IAED;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAc7B;IAED;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAyChC;IAED;;;;;;;;OAQG;YACW,yBAAyB;IAqBvC;;;OAGG;YACW,iBAAiB;IAyB/B;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM5C;IAED;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;;;OAIG;YACW,gBAAgB;IAoB9B;;;;;;;;OAQG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBpD;IAED;;;;;OAKG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO3C;IAED,oEAAoE;IAC9D,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAyFrD;CACF"}
|