codesift-mcp 0.12.0 → 0.13.1
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/README.md +44 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +35 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +25 -2
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/owner-only-file.d.ts +51 -0
- package/dist/cli/owner-only-file.d.ts.map +1 -0
- package/dist/cli/owner-only-file.js +121 -0
- package/dist/cli/owner-only-file.js.map +1 -0
- package/dist/cli/service.d.ts +17 -1
- package/dist/cli/service.d.ts.map +1 -1
- package/dist/cli/service.js +28 -12
- package/dist/cli/service.js.map +1 -1
- package/dist/cli/setup/codex.d.ts.map +1 -1
- package/dist/cli/setup/codex.js +14 -7
- package/dist/cli/setup/codex.js.map +1 -1
- package/dist/cli/setup/fs.d.ts +12 -0
- package/dist/cli/setup/fs.d.ts.map +1 -1
- package/dist/cli/setup/fs.js +17 -2
- package/dist/cli/setup/fs.js.map +1 -1
- package/dist/cli/setup/mcp.d.ts +14 -1
- package/dist/cli/setup/mcp.d.ts.map +1 -1
- package/dist/cli/setup/mcp.js +55 -5
- package/dist/cli/setup/mcp.js.map +1 -1
- package/dist/cli/setup/types.d.ts +19 -0
- package/dist/cli/setup/types.d.ts.map +1 -1
- package/dist/register-tools/runtime.d.ts +15 -6
- package/dist/register-tools/runtime.d.ts.map +1 -1
- package/dist/register-tools/runtime.js +30 -12
- package/dist/register-tools/runtime.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +42 -9
- package/dist/server.js.map +1 -1
- package/dist/storage/embedding-store.d.ts +12 -1
- package/dist/storage/embedding-store.d.ts.map +1 -1
- package/dist/storage/embedding-store.js +42 -2
- package/dist/storage/embedding-store.js.map +1 -1
- package/dist/storage/index-store.d.ts +31 -0
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +293 -10
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/shared-embedding-cache.d.ts +29 -0
- package/dist/storage/shared-embedding-cache.d.ts.map +1 -0
- package/dist/storage/shared-embedding-cache.js +120 -0
- package/dist/storage/shared-embedding-cache.js.map +1 -0
- package/dist/storage/sqlite-index-store.d.ts +89 -0
- package/dist/storage/sqlite-index-store.d.ts.map +1 -0
- package/dist/storage/sqlite-index-store.js +593 -0
- package/dist/storage/sqlite-index-store.js.map +1 -0
- package/dist/tools/index-tools/file-indexer.js +19 -19
- package/dist/tools/index-tools/file-indexer.js.map +1 -1
- package/dist/tools/index-tools/parse.d.ts.map +1 -1
- package/dist/tools/index-tools/parse.js +4 -1
- package/dist/tools/index-tools/parse.js.map +1 -1
- package/dist/tools/index-tools/registry.d.ts.map +1 -1
- package/dist/tools/index-tools/registry.js +16 -0
- package/dist/tools/index-tools/registry.js.map +1 -1
- package/dist/tools/status-tools.d.ts +10 -0
- package/dist/tools/status-tools.d.ts.map +1 -1
- package/dist/tools/status-tools.js +57 -16
- package/dist/tools/status-tools.js.map +1 -1
- package/dist/tools/workspace-scope-helper.d.ts.map +1 -1
- package/dist/tools/workspace-scope-helper.js +8 -1
- package/dist/tools/workspace-scope-helper.js.map +1 -1
- package/dist/tools/workspace-tools.d.ts.map +1 -1
- package/dist/tools/workspace-tools.js +9 -1
- package/dist/tools/workspace-tools.js.map +1 -1
- package/dist/utils/loopback.d.ts +23 -0
- package/dist/utils/loopback.d.ts.map +1 -0
- package/dist/utils/loopback.js +71 -0
- package/dist/utils/loopback.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,14 +1,100 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { statSync } from "node:fs";
|
|
2
3
|
import { join } from "node:path";
|
|
3
4
|
import { createHash } from "node:crypto";
|
|
4
5
|
import { atomicWriteFile } from "./_shared.js";
|
|
6
|
+
import { isSqliteAvailable, loadIndexSqlite, saveIndexSqlite, saveIncrementalSqlite, removeFileFromIndexSqlite, getFileEntrySqlite, getDataVersion, importLegacyIndexIfEmpty, classifyStorageError, IndexStorageError, } from "./sqlite-index-store.js";
|
|
5
7
|
/** Serialize concurrent writes to the same index path. */
|
|
6
8
|
const writeLocks = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Which on-disk format to use.
|
|
11
|
+
*
|
|
12
|
+
* `CODESIFT_INDEX_BACKEND=json` pins the legacy path (the documented rollback);
|
|
13
|
+
* `=sqlite` demands the new one and fails loudly if `node:sqlite` is missing, so a CI run
|
|
14
|
+
* cannot quietly exercise the wrong backend. Unset auto-detects, which is what keeps the
|
|
15
|
+
* `engines: >=20` floor honest: Node 20 has no `node:sqlite` and simply stays on JSON.
|
|
16
|
+
*
|
|
17
|
+
* Read from the environment here rather than `config.ts` because the choice must be
|
|
18
|
+
* resolvable from the short-lived `codesift postindex-file` hook process too, which never
|
|
19
|
+
* builds a full config.
|
|
20
|
+
*/
|
|
21
|
+
let backendPromise;
|
|
22
|
+
export async function resolveIndexBackend() {
|
|
23
|
+
backendPromise ??= computeIndexBackend();
|
|
24
|
+
return backendPromise;
|
|
25
|
+
}
|
|
26
|
+
async function computeIndexBackend() {
|
|
27
|
+
const explicit = process.env["CODESIFT_INDEX_BACKEND"];
|
|
28
|
+
if (explicit === "json")
|
|
29
|
+
return "json";
|
|
30
|
+
if (explicit === "sqlite") {
|
|
31
|
+
if (!(await isSqliteAvailable())) {
|
|
32
|
+
throw new Error("CODESIFT_INDEX_BACKEND=sqlite but node:sqlite is unavailable (requires Node >= 22.5)");
|
|
33
|
+
}
|
|
34
|
+
return "sqlite";
|
|
35
|
+
}
|
|
36
|
+
return (await isSqliteAvailable()) ? "sqlite" : "json";
|
|
37
|
+
}
|
|
38
|
+
export function resetIndexBackendForTesting() {
|
|
39
|
+
backendPromise = undefined;
|
|
40
|
+
}
|
|
41
|
+
/** `<hash>.index.json` -> `<hash>.index.db`, so both formats sit side by side and the JSON
|
|
42
|
+
* stays available as the rollback artifact. */
|
|
43
|
+
export function sqlitePathFor(indexPath) {
|
|
44
|
+
return indexPath.endsWith(".json")
|
|
45
|
+
? `${indexPath.slice(0, -".json".length)}.db`
|
|
46
|
+
: `${indexPath}.db`;
|
|
47
|
+
}
|
|
48
|
+
/** Guards one-time JSON->SQLite migration per index path. */
|
|
49
|
+
const migrations = new Map();
|
|
50
|
+
/**
|
|
51
|
+
* Bring an existing JSON index across on first touch.
|
|
52
|
+
*
|
|
53
|
+
* Deliberately non-destructive: the source `.json` is left in place. Deleting it would make
|
|
54
|
+
* `CODESIFT_INDEX_BACKEND=json` a one-way door, and the whole point of shipping a rollback
|
|
55
|
+
* switch is that it still has something to roll back to.
|
|
56
|
+
*/
|
|
57
|
+
async function ensureSqliteMigrated(indexPath, dbPath) {
|
|
58
|
+
const inFlight = migrations.get(dbPath);
|
|
59
|
+
if (inFlight)
|
|
60
|
+
return inFlight;
|
|
61
|
+
const run = (async () => {
|
|
62
|
+
if ((await loadIndexSqlite(dbPath)) !== null)
|
|
63
|
+
return; // already migrated
|
|
64
|
+
const legacy = await loadJsonIndex(indexPath);
|
|
65
|
+
// importLegacyIndexIfEmpty re-checks emptiness under the write lock, so a second
|
|
66
|
+
// process that raced us here imports nothing instead of overwriting our rows.
|
|
67
|
+
if (legacy)
|
|
68
|
+
await importLegacyIndexIfEmpty(dbPath, legacy);
|
|
69
|
+
})();
|
|
70
|
+
migrations.set(dbPath, run);
|
|
71
|
+
try {
|
|
72
|
+
await run;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
// A failed migration is retried, not remembered as done — and we do NOT re-read the same
|
|
76
|
+
// failing database to decide that. Probing it again inside a `finally` would hit an
|
|
77
|
+
// already-struggling store a second time AND, if that probe throws too, JS try/finally
|
|
78
|
+
// semantics would replace the original error with the second one.
|
|
79
|
+
migrations.delete(dbPath);
|
|
80
|
+
throw err;
|
|
81
|
+
}
|
|
82
|
+
migrations.set(dbPath, Promise.resolve());
|
|
83
|
+
}
|
|
84
|
+
export function resetMigrationCacheForTesting() {
|
|
85
|
+
migrations.clear();
|
|
86
|
+
}
|
|
7
87
|
/**
|
|
8
88
|
* Save a code index atomically.
|
|
9
89
|
* Writes to a temp file first, then renames to prevent partial reads.
|
|
10
90
|
*/
|
|
11
91
|
export async function saveIndex(indexPath, index) {
|
|
92
|
+
if ((await resolveIndexBackend()) === "sqlite") {
|
|
93
|
+
const dbPath = sqlitePathFor(indexPath);
|
|
94
|
+
await saveIndexSqlite(dbPath, index);
|
|
95
|
+
invalidateIndexCache(dbPath);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
12
98
|
const data = JSON.stringify(index);
|
|
13
99
|
await atomicWriteFile(indexPath, data);
|
|
14
100
|
}
|
|
@@ -23,19 +109,187 @@ export async function saveIndex(indexPath, index) {
|
|
|
23
109
|
* where version enforcement would cause spurious reindexes.
|
|
24
110
|
*/
|
|
25
111
|
export async function loadIndex(indexPath, currentVersions) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
112
|
+
const index = await readIndex(indexPath);
|
|
113
|
+
if (!index)
|
|
114
|
+
return null;
|
|
115
|
+
if (currentVersions && !isExtractorVersionCurrent(index, currentVersions))
|
|
116
|
+
return null;
|
|
117
|
+
return index;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* One file's `files[]` entry.
|
|
121
|
+
*
|
|
122
|
+
* This is the accessor ADR-003 exists for. `file-indexer` needs a single file's `mtime_ms`
|
|
123
|
+
* and `symbol_count` to decide whether an edit changed anything, and used to obtain them by
|
|
124
|
+
* loading the entire index — a 262 MB parse on tgm-survey-platform, paid on the first touch
|
|
125
|
+
* of every file, in a hook process that exits immediately afterwards and so can never reuse
|
|
126
|
+
* the result. Under SQLite it is one indexed row.
|
|
127
|
+
*
|
|
128
|
+
* The JSON backend keeps the old cost; there is no way to read one record out of a blob.
|
|
129
|
+
*/
|
|
130
|
+
export async function getFileEntry(indexPath, filePath) {
|
|
131
|
+
if ((await resolveIndexBackend()) === "sqlite") {
|
|
132
|
+
const dbPath = sqlitePathFor(indexPath);
|
|
133
|
+
await ensureSqliteMigrated(indexPath, dbPath);
|
|
134
|
+
return getFileEntrySqlite(dbPath, filePath);
|
|
135
|
+
}
|
|
136
|
+
const index = await loadJsonIndex(indexPath);
|
|
137
|
+
return index?.files.find((f) => f.path === filePath);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Bounded, LRU by insertion order. A materialised index is the largest object this process
|
|
141
|
+
* holds — the JSON equivalent is 262 MB on tgm-survey-platform — and `codesift serve` is a
|
|
142
|
+
* long-lived daemon that touches many repos. An unbounded map here would have been the one
|
|
143
|
+
* cache in this codebase without a ceiling, next to an embedding cache that is explicitly
|
|
144
|
+
* RAM-budgeted (`CODESIFT_MAX_EMBEDDING_MEM_MB`); that asymmetry is how the OOM reports
|
|
145
|
+
* documented in CLAUDE.md started.
|
|
146
|
+
*/
|
|
147
|
+
// `|| 3` would be wrong here: an operator setting 0 to minimise memory would get 3, because
|
|
148
|
+
// 0 is falsy. Only a non-numeric value should fall back.
|
|
149
|
+
const MAX_CACHED_INDEXES = (() => {
|
|
150
|
+
const raw = process.env["CODESIFT_MAX_CACHED_INDEXES"];
|
|
151
|
+
const parsed = raw === undefined ? 3 : Number(raw);
|
|
152
|
+
return Math.max(1, Number.isNaN(parsed) ? 3 : parsed);
|
|
153
|
+
})();
|
|
154
|
+
const indexCache = new Map();
|
|
155
|
+
function cacheIndex(dbPath, entry) {
|
|
156
|
+
// Re-insert to move to the most-recent end of Map iteration order.
|
|
157
|
+
indexCache.delete(dbPath);
|
|
158
|
+
indexCache.set(dbPath, entry);
|
|
159
|
+
while (indexCache.size > MAX_CACHED_INDEXES) {
|
|
160
|
+
const oldest = indexCache.keys().next();
|
|
161
|
+
if (oldest.done)
|
|
162
|
+
break;
|
|
163
|
+
indexCache.delete(oldest.value);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Detach the two arrays callers actually touch.
|
|
168
|
+
*
|
|
169
|
+
* A bare `{...index}` only stops a caller REASSIGNING `files`/`symbols`; an in-place
|
|
170
|
+
* `push`/`sort`/`splice` would still hit the array the cache holds — and `data_version`
|
|
171
|
+
* cannot see an in-memory mutation, so the corruption would survive every later hit. The
|
|
172
|
+
* elements stay shared (symbols are treated as immutable records); this copies the two
|
|
173
|
+
* array containers, which is the boundary that was actually being crossed.
|
|
174
|
+
*/
|
|
175
|
+
function copyIndex(index) {
|
|
176
|
+
return { ...index, files: [...index.files], symbols: [...index.symbols] };
|
|
177
|
+
}
|
|
178
|
+
function invalidateIndexCache(dbPath) {
|
|
179
|
+
indexCache.delete(dbPath);
|
|
180
|
+
}
|
|
181
|
+
export function resetIndexCacheForTesting() {
|
|
182
|
+
indexCache.clear();
|
|
183
|
+
}
|
|
184
|
+
export function getIndexCacheSizeForTesting() {
|
|
185
|
+
return indexCache.size;
|
|
186
|
+
}
|
|
187
|
+
/** Backend-agnostic read, without version enforcement. */
|
|
188
|
+
async function readIndex(indexPath) {
|
|
189
|
+
if ((await resolveIndexBackend()) === "sqlite") {
|
|
190
|
+
const dbPath = sqlitePathFor(indexPath);
|
|
191
|
+
await ensureSqliteMigrated(indexPath, dbPath);
|
|
192
|
+
const dataVersion = await getDataVersion(dbPath);
|
|
193
|
+
const cached = indexCache.get(dbPath);
|
|
194
|
+
if (cached && cached.dataVersion === dataVersion) {
|
|
195
|
+
// Re-insert on HIT too, or the eviction order is FIFO-by-first-load rather than LRU:
|
|
196
|
+
// the hottest repo would be evicted the moment an (N+1)th repo is touched, while a
|
|
197
|
+
// repo read once and never again outlives it. That thrashes exactly the working set
|
|
198
|
+
// the cache exists to keep warm.
|
|
199
|
+
cacheIndex(dbPath, cached);
|
|
200
|
+
return copyIndex(cached.index);
|
|
31
201
|
}
|
|
32
|
-
|
|
202
|
+
const index = await loadIndexSqlite(dbPath);
|
|
203
|
+
if (!index)
|
|
33
204
|
return null;
|
|
205
|
+
cacheIndex(dbPath, { index, dataVersion });
|
|
206
|
+
// Copy on the miss path too: returning the freshly-cached object itself would let the
|
|
207
|
+
// very first caller mutate the entry every later reader is about to be handed.
|
|
208
|
+
return copyIndex(index);
|
|
209
|
+
}
|
|
210
|
+
warnIfRollbackIsStale(indexPath);
|
|
211
|
+
return loadJsonIndex(indexPath);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Warn when the JSON backend is serving a snapshot that SQLite has since moved past.
|
|
215
|
+
*
|
|
216
|
+
* The rollback switch keeps the `.json` untouched, which is what makes rolling back possible
|
|
217
|
+
* — and also means that after a repo has run on SQLite for a while, the JSON is a frozen
|
|
218
|
+
* snapshot from migration day. Falling back to it then answers every query from a stale index
|
|
219
|
+
* with no error and no empty result: the shape is valid, the extractor versions still match,
|
|
220
|
+
* it is simply old. That is the worst failure mode we have (confidently wrong), so it gets a
|
|
221
|
+
* loud one-time line rather than silence.
|
|
222
|
+
*/
|
|
223
|
+
const staleRollbackWarned = new Set();
|
|
224
|
+
function warnIfRollbackIsStale(indexPath) {
|
|
225
|
+
if (staleRollbackWarned.has(indexPath))
|
|
226
|
+
return;
|
|
227
|
+
try {
|
|
228
|
+
// Mark only once a real comparison happened. Marking up front would permanently silence
|
|
229
|
+
// the warning for a long-lived JSON-pinned process that read this repo before any `.db`
|
|
230
|
+
// existed — precisely the process that most needs telling when one appears later.
|
|
231
|
+
const dbStat = statSync(sqlitePathFor(indexPath));
|
|
232
|
+
const jsonStat = statSync(indexPath);
|
|
233
|
+
staleRollbackWarned.add(indexPath);
|
|
234
|
+
if (dbStat.mtimeMs <= jsonStat.mtimeMs)
|
|
235
|
+
return;
|
|
236
|
+
const ageHours = Math.round((dbStat.mtimeMs - jsonStat.mtimeMs) / 3_600_000);
|
|
237
|
+
console.error(`[codesift] WARNING: reading the legacy JSON index at ${indexPath}, but a SQLite index ` +
|
|
238
|
+
`updated ~${ageHours}h more recently exists alongside it. Every answer from this repo ` +
|
|
239
|
+
`is from the pre-rollback snapshot. Run index_folder to rebuild the JSON index, or ` +
|
|
240
|
+
`unset CODESIFT_INDEX_BACKEND to go back to SQLite.`);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
/* no .db, or unreadable — nothing to compare against, so nothing to warn about */
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
export function resetStaleRollbackWarningForTesting() {
|
|
247
|
+
staleRollbackWarned.clear();
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Codes that genuinely mean "there is no index file here". Everything else that `readFile` can
|
|
251
|
+
* fail with — EISDIR, ENOTDIR, ENAMETOOLONG, ELOOP, platform-specific I/O errors — describes a
|
|
252
|
+
* path that is wrong or unreadable, not a repo that was never indexed. Reporting those as
|
|
253
|
+
* absence is the same misdiagnosis this change exists to remove, one layer down.
|
|
254
|
+
*/
|
|
255
|
+
const ABSENCE_CODES = new Set(["ENOENT", "ENOTDIR_PARENT"]);
|
|
256
|
+
function nonAbsenceReadCode(err) {
|
|
257
|
+
const code = typeof err === "object" && err !== null ? err.code : undefined;
|
|
258
|
+
// No recognisable code at all: this is NOT evidence of absence. Only an explicit ENOENT is.
|
|
259
|
+
// Defaulting the unknown case to "nothing indexed here" is how a real fault becomes a
|
|
260
|
+
// confident empty answer — the whole failure mode being removed.
|
|
261
|
+
if (typeof code !== "string")
|
|
262
|
+
return "UNKNOWN_READ_ERROR";
|
|
263
|
+
return ABSENCE_CODES.has(code) ? null : code;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* The legacy path, kept intact: it is both the Node 20 backend and the rollback target.
|
|
267
|
+
*
|
|
268
|
+
* ENOENT is absence and stays `null`; a malformed document is also `null` (an invalid index is
|
|
269
|
+
* rebuildable, which is the historical contract). But EACCES/EIO/EBUSY mean the file exists and
|
|
270
|
+
* we simply could not read it — reporting that as "no index" is how a permissions problem gets
|
|
271
|
+
* misdiagnosed as an unindexed repo.
|
|
272
|
+
*/
|
|
273
|
+
async function loadJsonIndex(indexPath) {
|
|
274
|
+
let raw;
|
|
275
|
+
try {
|
|
276
|
+
raw = await readFile(indexPath, "utf-8");
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
const code = classifyStorageError(err) ?? nonAbsenceReadCode(err);
|
|
280
|
+
if (code !== null) {
|
|
281
|
+
throw new IndexStorageError(`index storage at ${indexPath} is unreadable (${code}): ${err instanceof Error ? err.message : String(err)}`, code, indexPath, { cause: err });
|
|
34
282
|
}
|
|
283
|
+
return null; // ENOENT and friends: nothing indexed here
|
|
284
|
+
}
|
|
285
|
+
try {
|
|
286
|
+
const parsed = JSON.parse(raw);
|
|
287
|
+
if (!isValidIndex(parsed))
|
|
288
|
+
return null;
|
|
35
289
|
return parsed;
|
|
36
290
|
}
|
|
37
291
|
catch {
|
|
38
|
-
return null;
|
|
292
|
+
return null; // malformed JSON is a rebuildable index, not a storage fault
|
|
39
293
|
}
|
|
40
294
|
}
|
|
41
295
|
/** All languages whose stored `extractor_version` entry does not match
|
|
@@ -96,10 +350,23 @@ export function collectExtractorVersionMismatches(index, currentVersions) {
|
|
|
96
350
|
* to `loadIndex(...)` returning null. Callers must still handle null (no
|
|
97
351
|
* structured error) for those cases. */
|
|
98
352
|
export async function loadIndexOrStale(indexPath, currentVersions) {
|
|
353
|
+
let parsed;
|
|
99
354
|
try {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
355
|
+
parsed = await readIndex(indexPath);
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
const code = classifyStorageError(err);
|
|
359
|
+
if (code === null)
|
|
360
|
+
throw err;
|
|
361
|
+
return {
|
|
362
|
+
status: "unreadable",
|
|
363
|
+
reason: "storage_error",
|
|
364
|
+
code,
|
|
365
|
+
message: err instanceof Error ? err.message : String(err),
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
try {
|
|
369
|
+
if (!parsed)
|
|
103
370
|
return null;
|
|
104
371
|
const mismatches = collectExtractorVersionMismatches(parsed, currentVersions);
|
|
105
372
|
if (mismatches.length > 0) {
|
|
@@ -241,6 +508,15 @@ function enqueueIndexMutation(indexPath, missing, apply) {
|
|
|
241
508
|
* Serialized per indexPath to prevent read-modify-write races.
|
|
242
509
|
*/
|
|
243
510
|
export async function saveIncremental(indexPath, updatedFile, newSymbols, fileEntry) {
|
|
511
|
+
if ((await resolveIndexBackend()) === "sqlite") {
|
|
512
|
+
const dbPath = sqlitePathFor(indexPath);
|
|
513
|
+
await ensureSqliteMigrated(indexPath, dbPath);
|
|
514
|
+
// No mutation batching here on purpose: batching exists to amortise a whole-blob
|
|
515
|
+
// rewrite, and this backend writes one file's rows inside a transaction instead.
|
|
516
|
+
await saveIncrementalSqlite(dbPath, updatedFile, newSymbols, fileEntry);
|
|
517
|
+
invalidateIndexCache(dbPath);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
244
520
|
return enqueueIndexMutation(indexPath, "throw", (existing) => {
|
|
245
521
|
const filtered = existing.symbols.filter((symbol) => symbol.file !== updatedFile);
|
|
246
522
|
const merged = [...filtered, ...newSymbols];
|
|
@@ -261,6 +537,13 @@ export async function saveIncremental(indexPath, updatedFile, newSymbols, fileEn
|
|
|
261
537
|
* Serialized per indexPath to prevent read-modify-write races.
|
|
262
538
|
*/
|
|
263
539
|
export async function removeFileFromIndex(indexPath, deletedFile) {
|
|
540
|
+
if ((await resolveIndexBackend()) === "sqlite") {
|
|
541
|
+
const dbPath = sqlitePathFor(indexPath);
|
|
542
|
+
await ensureSqliteMigrated(indexPath, dbPath);
|
|
543
|
+
await removeFileFromIndexSqlite(dbPath, deletedFile);
|
|
544
|
+
invalidateIndexCache(dbPath);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
264
547
|
return enqueueIndexMutation(indexPath, "skip", (existing) => {
|
|
265
548
|
const hadSymbols = existing.symbols.some((s) => s.file === deletedFile);
|
|
266
549
|
const hadFile = existing.files.some((f) => f.path === deletedFile);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-store.js","sourceRoot":"","sources":["../../src/storage/index-store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-store.js","sourceRoot":"","sources":["../../src/storage/index-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key for a piece of text under a specific model.
|
|
3
|
+
*
|
|
4
|
+
* The model and dimensions are IN the key: vectors from different models are
|
|
5
|
+
* not interchangeable, and serving one for the other would silently corrupt
|
|
6
|
+
* every similarity score rather than fail. sha256 truncated to 128 bits —
|
|
7
|
+
* collisions at that width are not a practical concern, and the shorter key
|
|
8
|
+
* halves the file size.
|
|
9
|
+
*/
|
|
10
|
+
export declare function contentKey(model: string, dimensions: number, text: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Read the cache into memory once per process.
|
|
13
|
+
*
|
|
14
|
+
* Missing file, unreadable line, malformed JSON: all skipped. A cache that
|
|
15
|
+
* cannot be read must degrade into "compute it again", never into an error —
|
|
16
|
+
* it is an optimization, and a broken one has to stay invisible.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadSharedCache(): Promise<Map<string, Float32Array>>;
|
|
19
|
+
/**
|
|
20
|
+
* Append new vectors. Both the file and the in-memory map are updated, so a
|
|
21
|
+
* second repo indexed in the same process hits memory rather than disk.
|
|
22
|
+
*/
|
|
23
|
+
export declare function appendSharedCache(entries: Array<{
|
|
24
|
+
key: string;
|
|
25
|
+
vec: Float32Array;
|
|
26
|
+
}>): void;
|
|
27
|
+
/** Test-only: forget the in-memory copy so a fresh path is picked up. */
|
|
28
|
+
export declare function _resetSharedCacheForTests(): void;
|
|
29
|
+
//# sourceMappingURL=shared-embedding-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-embedding-cache.d.ts","sourceRoot":"","sources":["../../src/storage/shared-embedding-cache.ts"],"names":[],"mappings":"AAwCA;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKlF;AAKD;;;;;;GAMG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAyB1E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,YAAY,CAAA;CAAE,CAAC,GAAG,IAAI,CAgB1F;AAED,yEAAyE;AACzE,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, appendFileSync, createReadStream } from "node:fs";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
/**
|
|
7
|
+
* Embeddings keyed by CONTENT, shared across every repository.
|
|
8
|
+
*
|
|
9
|
+
* A vector is a pure function of (model, dimensions, text). Nothing about it
|
|
10
|
+
* belongs to a repository — yet embeddings were stored per repo, so the same
|
|
11
|
+
* symbol text was sent to the model once per repo that contained it.
|
|
12
|
+
*
|
|
13
|
+
* That is not a marginal cost here. A linked worktree is a separate repo to
|
|
14
|
+
* CodeSift, and its files are usually IDENTICAL to the checkout it came from:
|
|
15
|
+
* `backlog-wave-1-integration` had 1,799 files and differed from main by zero.
|
|
16
|
+
* With 40 worktrees registered, the same text was embedded up to 40 times. Half
|
|
17
|
+
* of the 2M symbols still queued for embedding are worktrees or temp dirs.
|
|
18
|
+
*
|
|
19
|
+
* Auto-indexing no longer creates those entries, but an EXPLICIT
|
|
20
|
+
* `index_folder(path=<worktree>)` still should work — the H19 hint tells agents
|
|
21
|
+
* to do exactly that when they are working in one. This makes that cheap
|
|
22
|
+
* instead of forbidden: the second repo containing a given symbol pays a hash
|
|
23
|
+
* lookup, not a model call.
|
|
24
|
+
*
|
|
25
|
+
* Format: ndjson, append-only, one `{k, v}` per line. Append-only because
|
|
26
|
+
* concurrent writers are the norm (one process per agent window) and appending
|
|
27
|
+
* a line is the only operation that is safe without a lock. Duplicate keys are
|
|
28
|
+
* harmless — the last one read wins, and they carry the same value by
|
|
29
|
+
* construction.
|
|
30
|
+
*/
|
|
31
|
+
/** Bump when the vector layout changes in a way that invalidates old entries. */
|
|
32
|
+
const CACHE_VERSION = 1;
|
|
33
|
+
function cachePath() {
|
|
34
|
+
const dataDir = process.env["CODESIFT_DATA_DIR"] ?? join(homedir(), ".codesift");
|
|
35
|
+
return join(dataDir, `shared-embeddings.v${CACHE_VERSION}.ndjson`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Key for a piece of text under a specific model.
|
|
39
|
+
*
|
|
40
|
+
* The model and dimensions are IN the key: vectors from different models are
|
|
41
|
+
* not interchangeable, and serving one for the other would silently corrupt
|
|
42
|
+
* every similarity score rather than fail. sha256 truncated to 128 bits —
|
|
43
|
+
* collisions at that width are not a practical concern, and the shorter key
|
|
44
|
+
* halves the file size.
|
|
45
|
+
*/
|
|
46
|
+
export function contentKey(model, dimensions, text) {
|
|
47
|
+
return createHash("sha256")
|
|
48
|
+
.update(`${model}\0${dimensions}\0${text}`)
|
|
49
|
+
.digest("hex")
|
|
50
|
+
.slice(0, 32);
|
|
51
|
+
}
|
|
52
|
+
let memory = null;
|
|
53
|
+
let loadedFrom = null;
|
|
54
|
+
/**
|
|
55
|
+
* Read the cache into memory once per process.
|
|
56
|
+
*
|
|
57
|
+
* Missing file, unreadable line, malformed JSON: all skipped. A cache that
|
|
58
|
+
* cannot be read must degrade into "compute it again", never into an error —
|
|
59
|
+
* it is an optimization, and a broken one has to stay invisible.
|
|
60
|
+
*/
|
|
61
|
+
export async function loadSharedCache() {
|
|
62
|
+
const path = cachePath();
|
|
63
|
+
if (memory && loadedFrom === path)
|
|
64
|
+
return memory;
|
|
65
|
+
const map = new Map();
|
|
66
|
+
if (existsSync(path)) {
|
|
67
|
+
try {
|
|
68
|
+
const rl = createInterface({ input: createReadStream(path, { encoding: "utf-8" }), crlfDelay: Infinity });
|
|
69
|
+
for await (const line of rl) {
|
|
70
|
+
if (!line)
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
const entry = JSON.parse(line);
|
|
74
|
+
if (typeof entry.k === "string" && Array.isArray(entry.v)) {
|
|
75
|
+
map.set(entry.k, new Float32Array(entry.v));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Skip a malformed line rather than abandoning the whole cache.
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Unreadable file — behave as if empty.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
memory = map;
|
|
88
|
+
loadedFrom = path;
|
|
89
|
+
return map;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Append new vectors. Both the file and the in-memory map are updated, so a
|
|
93
|
+
* second repo indexed in the same process hits memory rather than disk.
|
|
94
|
+
*/
|
|
95
|
+
export function appendSharedCache(entries) {
|
|
96
|
+
if (entries.length === 0)
|
|
97
|
+
return;
|
|
98
|
+
const path = cachePath();
|
|
99
|
+
try {
|
|
100
|
+
mkdirSync(join(path, ".."), { recursive: true });
|
|
101
|
+
let payload = "";
|
|
102
|
+
for (const { key, vec } of entries) {
|
|
103
|
+
if (memory && !memory.has(key))
|
|
104
|
+
memory.set(key, vec);
|
|
105
|
+
payload += JSON.stringify({ k: key, v: Array.from(vec) }) + "\n";
|
|
106
|
+
}
|
|
107
|
+
// One append for the batch: fewer syscalls, and a single write is far less
|
|
108
|
+
// likely to interleave with another process mid-line than many small ones.
|
|
109
|
+
appendFileSync(path, payload, "utf-8");
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// A cache that cannot be written must not fail the indexing run.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Test-only: forget the in-memory copy so a fresh path is picked up. */
|
|
116
|
+
export function _resetSharedCacheForTests() {
|
|
117
|
+
memory = null;
|
|
118
|
+
loadedFrom = null;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=shared-embedding-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-embedding-cache.js","sourceRoot":"","sources":["../../src/storage/shared-embedding-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { DatabaseSync as DatabaseSyncType } from "node:sqlite";
|
|
2
|
+
import type { CodeIndex, CodeSymbol, FileEntry } from "../types.js";
|
|
3
|
+
export declare function loadSqliteCtor(): Promise<typeof DatabaseSyncType | null>;
|
|
4
|
+
export declare function isSqliteAvailable(): Promise<boolean>;
|
|
5
|
+
/** Tests need to prove the JSON fallback still works on a runtime that has sqlite. */
|
|
6
|
+
export declare function setSqliteCtorForTesting(ctor: typeof DatabaseSyncType | null | undefined): void;
|
|
7
|
+
/**
|
|
8
|
+
* A storage fault, as distinct from "this repo has no index".
|
|
9
|
+
*
|
|
10
|
+
* Both used to arrive at callers as `null`, so a locked or corrupt database was indistinguishable
|
|
11
|
+
* from an unindexed repo: tools reported "not indexed" (prompting a pointless full reindex over a
|
|
12
|
+
* database that was merely busy) or returned empty results that read as an authoritative "no
|
|
13
|
+
* matches". Empty-because-broken is the worst answer an index can give, because nothing about it
|
|
14
|
+
* looks wrong.
|
|
15
|
+
*/
|
|
16
|
+
export declare class IndexStorageError extends Error {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
constructor(message: string, code: string, path: string, options?: {
|
|
20
|
+
cause?: unknown;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Structural check, not `instanceof`.
|
|
25
|
+
*
|
|
26
|
+
* A duplicated module instance (bundler, worker/thread boundary, a test importing through a
|
|
27
|
+
* different specifier) makes `instanceof` false for an object that is in every observable way
|
|
28
|
+
* the right error — and the failure mode is silent: the fault falls into the "unexpected error"
|
|
29
|
+
* branch and gets reported as an unindexed repo, which is the exact bug this file exists to
|
|
30
|
+
* prevent.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isIndexStorageError(err: unknown): err is IndexStorageError;
|
|
33
|
+
/** The operational code for `err`, or null when it is not an operational failure. */
|
|
34
|
+
export declare function classifyStorageError(err: unknown): string | null;
|
|
35
|
+
export declare const SCHEMA_VERSION = 1;
|
|
36
|
+
/**
|
|
37
|
+
* Open (and cache) a connection, creating the schema on first use.
|
|
38
|
+
*
|
|
39
|
+
* WAL is the reason this migration solves a problem a sharded JSON layout would not: the MCP
|
|
40
|
+
* server and the `codesift postindex-file` hook are separate processes writing the same
|
|
41
|
+
* index, and WAL gives them concurrent readers with a single writer instead of a corruption
|
|
42
|
+
* window. `busy_timeout` makes a writer wait its turn rather than throwing SQLITE_BUSY when
|
|
43
|
+
* an agent edits files faster than the previous write settles.
|
|
44
|
+
*/
|
|
45
|
+
export declare function openIndexDb(dbPath: string): Promise<DatabaseSyncType>;
|
|
46
|
+
/** Close one cached connection (tests, and the shutdown path). */
|
|
47
|
+
export declare function closeIndexDb(dbPath: string): void;
|
|
48
|
+
export declare function closeAllIndexDbs(): void;
|
|
49
|
+
/** Replace the entire index. Used by full (re)indexing and by JSON->SQLite migration. */
|
|
50
|
+
export declare function saveIndexSqlite(dbPath: string, index: CodeIndex): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Import a legacy JSON index, but only if this db is still empty — decided and written
|
|
53
|
+
* inside ONE `BEGIN IMMEDIATE` transaction.
|
|
54
|
+
*
|
|
55
|
+
* The check-then-act cannot be done in JS: `codesift postindex-file` is a fresh process per
|
|
56
|
+
* edit, so two of them (or one plus the server) can both observe an empty db, both read the
|
|
57
|
+
* same legacy JSON, and the slower writer then overwrites an incremental update the faster
|
|
58
|
+
* one already committed. An in-process guard cannot see the other process at all.
|
|
59
|
+
*
|
|
60
|
+
* `BEGIN IMMEDIATE` takes the write lock before the emptiness check, so the second writer
|
|
61
|
+
* either waits and then sees the committed import (returns false), or fails on busy_timeout —
|
|
62
|
+
* never silently clobbers. Returns true when this call performed the import.
|
|
63
|
+
*/
|
|
64
|
+
export declare function importLegacyIndexIfEmpty(dbPath: string, index: CodeIndex): Promise<boolean>;
|
|
65
|
+
/** Materialise the whole index. Returns null when the db has never been written to. */
|
|
66
|
+
export declare function loadIndexSqlite(dbPath: string): Promise<CodeIndex | null>;
|
|
67
|
+
/**
|
|
68
|
+
* One file's `mtime_ms`, without materialising the index.
|
|
69
|
+
*
|
|
70
|
+
* `file-indexer.ts` used to parse the whole blob for exactly this value and then
|
|
71
|
+
* `saveIncremental` parsed it a second time — two full parses of 262 MB to decide whether a
|
|
72
|
+
* 40-line file had changed.
|
|
73
|
+
*/
|
|
74
|
+
export declare function getFileMtimeSqlite(dbPath: string, filePath: string): Promise<number | undefined>;
|
|
75
|
+
/** One file's `files[]` entry, without materialising the index. */
|
|
76
|
+
export declare function getFileEntrySqlite(dbPath: string, filePath: string): Promise<FileEntry | undefined>;
|
|
77
|
+
/** Replace one file's symbols (and optionally its files[] entry) in a single transaction. */
|
|
78
|
+
export declare function saveIncrementalSqlite(dbPath: string, updatedFile: string, newSymbols: CodeSymbol[], fileEntry?: FileEntry): Promise<void>;
|
|
79
|
+
/** Drop a deleted file's symbols and its files[] entry. */
|
|
80
|
+
export declare function removeFileFromIndexSqlite(dbPath: string, deletedFile: string): Promise<void>;
|
|
81
|
+
/** All symbols for one file — lets per-file tools skip the whole-index load. */
|
|
82
|
+
export declare function getSymbolsForFileSqlite(dbPath: string, filePath: string): Promise<CodeSymbol[]>;
|
|
83
|
+
/**
|
|
84
|
+
* Cross-process change counter. SQLite bumps `data_version` when *another* connection
|
|
85
|
+
* commits, which is the invalidation signal a plain JSON file never had — and the reason an
|
|
86
|
+
* in-memory index cache becomes safe here despite the hook writing from its own process.
|
|
87
|
+
*/
|
|
88
|
+
export declare function getDataVersion(dbPath: string): Promise<number>;
|
|
89
|
+
//# sourceMappingURL=sqlite-index-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-index-store.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite-index-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AA0B/E,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,gBAAgB,GAAG,IAAI,CAAC,CAS9E;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE1D;AAED,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAE9F;AAMD;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAHvB,YACE,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAI9B;CACF;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,iBAAiB,CAO1E;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAwBhE;AAoBD,eAAO,MAAM,cAAc,IAAI,CAAC;AA+ChC;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2C3E;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CASjD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAsLD,yFAAyF;AACzF,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrF;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED,uFAAuF;AACvF,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA6C/E;AAMD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAM7B;AAED,mEAAmE;AACnE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAMhC;AAED,6FAA6F;AAC7F,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,EAAE,EACxB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,2DAA2D;AAC3D,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CAQvB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpE"}
|