lmgrep 0.1.0 → 0.1.2
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/dist/cli.js +559 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +32 -0
- package/dist/index.js +180 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/build.d.ts +7 -0
- package/dist/lib/build.js +222 -0
- package/dist/lib/build.js.map +1 -0
- package/dist/{chunker → lib/chunker}/context.d.ts +0 -4
- package/dist/{chunker → lib/chunker}/context.js +3 -76
- package/dist/lib/chunker/context.js.map +1 -0
- package/dist/lib/chunker/index.d.ts +7 -0
- package/dist/{chunker → lib/chunker}/index.js +10 -5
- package/dist/lib/chunker/index.js.map +1 -0
- package/dist/lib/chunker/languages.js.map +1 -0
- package/dist/lib/config.d.ts +12 -0
- package/dist/lib/config.js +82 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/embedder.d.ts +55 -0
- package/dist/lib/embedder.js +221 -0
- package/dist/lib/embedder.js.map +1 -0
- package/dist/{providers.js → lib/providers.js} +0 -2
- package/dist/lib/providers.js.map +1 -0
- package/dist/lib/repair.d.ts +3 -0
- package/dist/lib/repair.js +104 -0
- package/dist/lib/repair.js.map +1 -0
- package/dist/lib/scanner.d.ts +34 -0
- package/dist/lib/scanner.js +219 -0
- package/dist/lib/scanner.js.map +1 -0
- package/dist/lib/serve.d.ts +11 -0
- package/dist/lib/serve.js +124 -0
- package/dist/lib/serve.js.map +1 -0
- package/dist/lib/store.d.ts +147 -0
- package/dist/lib/store.js +673 -0
- package/dist/lib/store.js.map +1 -0
- package/dist/lib/types.d.ts +118 -0
- package/dist/lib/types.js +13 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/mcp.js +160 -45
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunker/context.js.map +0 -1
- package/dist/chunker/index.d.ts +0 -3
- package/dist/chunker/index.js.map +0 -1
- package/dist/chunker/languages.js.map +0 -1
- package/dist/config.d.ts +0 -2
- package/dist/config.js +0 -31
- package/dist/config.js.map +0 -1
- package/dist/embedder.d.ts +0 -3
- package/dist/embedder.js +0 -55
- package/dist/embedder.js.map +0 -1
- package/dist/index-cmd.d.ts +0 -9
- package/dist/index-cmd.js +0 -250
- package/dist/index-cmd.js.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/repair-cmd.d.ts +0 -5
- package/dist/repair-cmd.js +0 -112
- package/dist/repair-cmd.js.map +0 -1
- package/dist/search-cmd.d.ts +0 -10
- package/dist/search-cmd.js +0 -60
- package/dist/search-cmd.js.map +0 -1
- package/dist/serve-cmd.d.ts +0 -1
- package/dist/serve-cmd.js +0 -139
- package/dist/serve-cmd.js.map +0 -1
- package/dist/status-cmd.d.ts +0 -5
- package/dist/status-cmd.js +0 -119
- package/dist/status-cmd.js.map +0 -1
- package/dist/store.d.ts +0 -25
- package/dist/store.js +0 -207
- package/dist/store.js.map +0 -1
- package/dist/types.d.ts +0 -40
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/walker.d.ts +0 -3
- package/dist/walker.js +0 -90
- package/dist/walker.js.map +0 -1
- /package/dist/{chunker → lib/chunker}/languages.d.ts +0 -0
- /package/dist/{chunker → lib/chunker}/languages.js +0 -0
- /package/dist/{providers.d.ts → lib/providers.d.ts} +0 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Embedder } from "./lib/embedder.js";
|
|
2
|
+
import type { BuildOptions, Chunker, Logger, LmgrepConfig, RepairResult, SearchOptions, SearchResult, StatusInfo } from "./lib/types.js";
|
|
3
|
+
export type { BuildOptions, Chunk, Chunker, FileChange, FileEntry, IndexedChunk, Logger, LmgrepConfig, ProgressEvent, RepairResult, SearchOptions, SearchResult, StatusInfo, } from "./lib/types.js";
|
|
4
|
+
export { consoleLogger, silentLogger } from "./lib/types.js";
|
|
5
|
+
export type { Embedder } from "./lib/embedder.js";
|
|
6
|
+
export { AISDKEmbedder, EmbeddingAbortError } from "./lib/embedder.js";
|
|
7
|
+
export { TreeSitterChunker } from "./lib/chunker/index.js";
|
|
8
|
+
export { Store, findIndexedAncestor, getDbPath, getLegacyDbPath, resolveProject, discoverIndexedProjects, writeProjectMetadata, readProjectMetadata, extractModelFamily, acquireDbLock, releaseDbLock, isDbLocked, discoverRunningProcesses, } from "./lib/store.js";
|
|
9
|
+
export type { ProjectMetadata, RunningProcess } from "./lib/store.js";
|
|
10
|
+
export { startWatcher } from "./lib/serve.js";
|
|
11
|
+
export { loadConfig, getConfigDir, getGlobalConfigPath } from "./lib/config.js";
|
|
12
|
+
export interface CreateIndexOptions {
|
|
13
|
+
cwd: string;
|
|
14
|
+
config?: Partial<LmgrepConfig>;
|
|
15
|
+
embedder?: Embedder;
|
|
16
|
+
chunker?: Chunker;
|
|
17
|
+
logger?: Logger;
|
|
18
|
+
}
|
|
19
|
+
export interface LmgrepIndex {
|
|
20
|
+
readonly cwd: string;
|
|
21
|
+
readonly config: LmgrepConfig;
|
|
22
|
+
build(opts?: BuildOptions): Promise<{
|
|
23
|
+
succeeded: number;
|
|
24
|
+
failed: number;
|
|
25
|
+
}>;
|
|
26
|
+
search(query: string, opts?: SearchOptions): Promise<SearchResult[]>;
|
|
27
|
+
repair(dry?: boolean): Promise<RepairResult>;
|
|
28
|
+
watch(): Promise<void>;
|
|
29
|
+
status(): Promise<StatusInfo>;
|
|
30
|
+
close(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare function createIndex(options: CreateIndexOptions): Promise<LmgrepIndex>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { loadConfig } from "./lib/config.js";
|
|
2
|
+
import { TreeSitterChunker } from "./lib/chunker/index.js";
|
|
3
|
+
import { AISDKEmbedder } from "./lib/embedder.js";
|
|
4
|
+
import { build } from "./lib/build.js";
|
|
5
|
+
import { repair } from "./lib/repair.js";
|
|
6
|
+
import { serve } from "./lib/serve.js";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { Store, findIndexedAncestor, resolveProject, readProjectMetadata, getDbPath, extractModelFamily, } from "./lib/store.js";
|
|
9
|
+
import { consoleLogger } from "./lib/types.js";
|
|
10
|
+
export { consoleLogger, silentLogger } from "./lib/types.js";
|
|
11
|
+
export { AISDKEmbedder, EmbeddingAbortError } from "./lib/embedder.js";
|
|
12
|
+
export { TreeSitterChunker } from "./lib/chunker/index.js";
|
|
13
|
+
export { Store, findIndexedAncestor, getDbPath, getLegacyDbPath, resolveProject, discoverIndexedProjects, writeProjectMetadata, readProjectMetadata, extractModelFamily, acquireDbLock, releaseDbLock, isDbLocked, discoverRunningProcesses, } from "./lib/store.js";
|
|
14
|
+
export { startWatcher } from "./lib/serve.js";
|
|
15
|
+
export { loadConfig, getConfigDir, getGlobalConfigPath } from "./lib/config.js";
|
|
16
|
+
export async function createIndex(options) {
|
|
17
|
+
const { cwd } = options;
|
|
18
|
+
// Resolve config: user overrides > file config > defaults
|
|
19
|
+
const fileConfig = loadConfig(cwd);
|
|
20
|
+
const config = { ...fileConfig, ...options.config };
|
|
21
|
+
const store = Store.forProject(cwd);
|
|
22
|
+
const embedder = options.embedder ?? new AISDKEmbedder(config);
|
|
23
|
+
const chunker = options.chunker ?? new TreeSitterChunker();
|
|
24
|
+
const logger = options.logger ?? consoleLogger;
|
|
25
|
+
return {
|
|
26
|
+
cwd,
|
|
27
|
+
config,
|
|
28
|
+
async build(opts) {
|
|
29
|
+
return build(cwd, store, config, embedder, chunker, opts, logger);
|
|
30
|
+
},
|
|
31
|
+
async search(query, opts = {}) {
|
|
32
|
+
let queryVector = await embedder.embedQuery(query);
|
|
33
|
+
// Check model compatibility with the index
|
|
34
|
+
const dbPath = getDbPath(cwd);
|
|
35
|
+
const meta = readProjectMetadata(dbPath);
|
|
36
|
+
if (meta) {
|
|
37
|
+
// Hard error: dimension mismatch
|
|
38
|
+
if (meta.dimensions != null && queryVector.length !== meta.dimensions) {
|
|
39
|
+
throw new Error(`Dimension mismatch: index has ${meta.dimensions}-dim vectors but your model produces ${queryVector.length}-dim. ` +
|
|
40
|
+
`These embeddings are incompatible.`);
|
|
41
|
+
}
|
|
42
|
+
// Advisory: model family mismatch
|
|
43
|
+
if (meta.model) {
|
|
44
|
+
const indexFamily = extractModelFamily(meta.model);
|
|
45
|
+
const queryFamily = extractModelFamily(config.model);
|
|
46
|
+
if (indexFamily !== queryFamily) {
|
|
47
|
+
logger.info(`Warning: index was built with "${meta.model}" (${indexFamily}) ` +
|
|
48
|
+
`but searching with "${config.model}" (${queryFamily}). ` +
|
|
49
|
+
`Results may be degraded if these are different model families.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Subtract the --not vector to push away unwanted results
|
|
54
|
+
if (opts.not) {
|
|
55
|
+
const notVector = await embedder.embedQuery(opts.not);
|
|
56
|
+
queryVector = queryVector.map((v, i) => v - notVector[i] * 0.5);
|
|
57
|
+
}
|
|
58
|
+
// Determine which stores to search
|
|
59
|
+
const targets = resolveSearchTargets(cwd, store, opts);
|
|
60
|
+
const limit = opts.limit ?? 25;
|
|
61
|
+
// Search all targets
|
|
62
|
+
let results = [];
|
|
63
|
+
for (const target of targets) {
|
|
64
|
+
const targetResults = await target.store.search(queryVector, limit, target.filePrefix, opts.type);
|
|
65
|
+
// Tag results from foreign projects with their root
|
|
66
|
+
if (target.projectRoot) {
|
|
67
|
+
for (const r of targetResults) {
|
|
68
|
+
r.filePath = `${target.projectRoot}/${r.filePath}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
results.push(...targetResults);
|
|
72
|
+
}
|
|
73
|
+
// When searching multiple targets, sort by score and trim
|
|
74
|
+
if (targets.length > 1) {
|
|
75
|
+
results.sort((a, b) => b.score - a.score);
|
|
76
|
+
results = results.slice(0, limit);
|
|
77
|
+
}
|
|
78
|
+
// Post-filter by language (file extension)
|
|
79
|
+
if (opts.language && opts.language.length > 0) {
|
|
80
|
+
const exts = new Set(opts.language.map((l) => (l.startsWith(".") ? l : `.${l}`)));
|
|
81
|
+
results = results.filter((r) => exts.has(r.filePath.slice(r.filePath.lastIndexOf("."))));
|
|
82
|
+
}
|
|
83
|
+
if (opts.minScore != null) {
|
|
84
|
+
results = results.filter((r) => r.score >= opts.minScore);
|
|
85
|
+
}
|
|
86
|
+
// Close any foreign stores we opened
|
|
87
|
+
for (const target of targets) {
|
|
88
|
+
if (target.store !== store) {
|
|
89
|
+
await target.store.close();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
},
|
|
94
|
+
async repair(dry = false) {
|
|
95
|
+
return repair(cwd, store, chunker, dry, logger);
|
|
96
|
+
},
|
|
97
|
+
async watch() {
|
|
98
|
+
return serve(cwd, store, config, embedder, chunker, logger);
|
|
99
|
+
},
|
|
100
|
+
async status() {
|
|
101
|
+
const ancestor = findIndexedAncestor(cwd);
|
|
102
|
+
const projectRoot = ancestor ? ancestor.root : cwd;
|
|
103
|
+
const prefix = ancestor?.prefix ?? "";
|
|
104
|
+
const statusStore = projectRoot === cwd ? store : Store.forProject(projectRoot);
|
|
105
|
+
const files = await statusStore.getIndexedFiles();
|
|
106
|
+
const hashes = await statusStore.getIndexedHashes();
|
|
107
|
+
let totalChunks = 0;
|
|
108
|
+
for (const [, h] of files)
|
|
109
|
+
totalChunks += h.length;
|
|
110
|
+
let embeddingOk = false;
|
|
111
|
+
let embeddingLatencyMs;
|
|
112
|
+
try {
|
|
113
|
+
const start = Date.now();
|
|
114
|
+
await embedder.embedQuery("test");
|
|
115
|
+
embeddingLatencyMs = Date.now() - start;
|
|
116
|
+
embeddingOk = true;
|
|
117
|
+
}
|
|
118
|
+
catch { }
|
|
119
|
+
// Read index metadata for model/dimensions info
|
|
120
|
+
const meta = readProjectMetadata(getDbPath(projectRoot));
|
|
121
|
+
return {
|
|
122
|
+
projectRoot,
|
|
123
|
+
prefix,
|
|
124
|
+
config,
|
|
125
|
+
fileCount: files.size,
|
|
126
|
+
chunkCount: totalChunks,
|
|
127
|
+
uniqueHashes: hashes.size,
|
|
128
|
+
embeddingOk,
|
|
129
|
+
embeddingLatencyMs,
|
|
130
|
+
indexModel: meta?.model,
|
|
131
|
+
indexDimensions: meta?.dimensions,
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
async close() {
|
|
135
|
+
await store.close();
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function resolveSearchTargets(cwd, localStore, opts) {
|
|
140
|
+
// --across: search multiple projects
|
|
141
|
+
if (opts.across && opts.across.length > 0) {
|
|
142
|
+
const targets = [
|
|
143
|
+
{ store: localStore, filePrefix: opts.filePrefix },
|
|
144
|
+
];
|
|
145
|
+
for (const p of opts.across) {
|
|
146
|
+
const abs = resolve(cwd, p);
|
|
147
|
+
const { root } = resolveProject(abs);
|
|
148
|
+
targets.push({
|
|
149
|
+
store: Store.forProject(abs),
|
|
150
|
+
filePrefix: opts.filePrefix,
|
|
151
|
+
projectRoot: root,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return targets;
|
|
155
|
+
}
|
|
156
|
+
// --project: search a single foreign project
|
|
157
|
+
if (opts.project) {
|
|
158
|
+
const abs = resolve(cwd, opts.project);
|
|
159
|
+
const { root } = resolveProject(abs);
|
|
160
|
+
return [
|
|
161
|
+
{
|
|
162
|
+
store: Store.forProject(abs),
|
|
163
|
+
filePrefix: opts.filePrefix,
|
|
164
|
+
projectRoot: root,
|
|
165
|
+
},
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
// Default: search local project, resolving ancestor prefix
|
|
169
|
+
let filePrefix = opts.filePrefix;
|
|
170
|
+
let searchStore = localStore;
|
|
171
|
+
const ancestor = findIndexedAncestor(cwd);
|
|
172
|
+
if (ancestor?.prefix) {
|
|
173
|
+
searchStore = Store.forProject(ancestor.root);
|
|
174
|
+
filePrefix = filePrefix
|
|
175
|
+
? `${ancestor.prefix}/${filePrefix}`
|
|
176
|
+
: ancestor.prefix;
|
|
177
|
+
}
|
|
178
|
+
return [{ store: searchStore, filePrefix }];
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Embedder } from "./embedder.js";
|
|
2
|
+
import { type Store } from "./store.js";
|
|
3
|
+
import type { Chunker, Logger, LmgrepConfig, BuildOptions } from "./types.js";
|
|
4
|
+
export declare function build(cwd: string, store: Store, config: LmgrepConfig, embedder: Embedder, chunker: Chunker, opts?: BuildOptions, logger?: Logger): Promise<{
|
|
5
|
+
succeeded: number;
|
|
6
|
+
failed: number;
|
|
7
|
+
}>;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { ResilientEmbedder, EmbeddingAbortError, } from "./embedder.js";
|
|
2
|
+
import { walkFiles, detectChanges, filterByMtime } from "./scanner.js";
|
|
3
|
+
import { writeProjectMetadata } from "./store.js";
|
|
4
|
+
import { consoleLogger } from "./types.js";
|
|
5
|
+
function parseDuration(s) {
|
|
6
|
+
const match = s.match(/^(\d+)\s*(s|m|h|d)$/);
|
|
7
|
+
if (!match)
|
|
8
|
+
throw new Error(`Invalid duration "${s}". Use e.g. 10m, 2h, 1d`);
|
|
9
|
+
const n = Number.parseInt(match[1], 10);
|
|
10
|
+
const unit = match[2];
|
|
11
|
+
const multipliers = {
|
|
12
|
+
s: 1000,
|
|
13
|
+
m: 60_000,
|
|
14
|
+
h: 3_600_000,
|
|
15
|
+
d: 86_400_000,
|
|
16
|
+
};
|
|
17
|
+
return n * multipliers[unit];
|
|
18
|
+
}
|
|
19
|
+
export async function build(cwd, store, config, embedder, chunker, opts = {}, logger = consoleLogger) {
|
|
20
|
+
const log = logger.info.bind(logger);
|
|
21
|
+
const emit = opts.onProgress;
|
|
22
|
+
if (opts.reset) {
|
|
23
|
+
log("Resetting index...");
|
|
24
|
+
await store.reset();
|
|
25
|
+
}
|
|
26
|
+
// 1. Scan
|
|
27
|
+
let files;
|
|
28
|
+
if (opts.files && opts.files.length > 0) {
|
|
29
|
+
files = opts.files;
|
|
30
|
+
log(`Processing ${files.length} targeted files`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
files = walkFiles(cwd, config.ignore, config.extensions);
|
|
34
|
+
if (opts.since) {
|
|
35
|
+
const cutoff = Date.now() - parseDuration(opts.since);
|
|
36
|
+
const before = files.length;
|
|
37
|
+
files = filterByMtime(files, cwd, cutoff);
|
|
38
|
+
log(`Found ${files.length} files modified in the last ${opts.since} (out of ${before})`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
log(`Found ${files.length} files`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
emit?.({ phase: "scan", current: files.length, total: files.length });
|
|
45
|
+
// 2. Change detection
|
|
46
|
+
const storedHashes = await store.getFileHashes();
|
|
47
|
+
const { changed, currentHashes } = detectChanges(files, storedHashes, cwd, opts.force);
|
|
48
|
+
log(`${changed.length} files changed out of ${files.length}`);
|
|
49
|
+
if (changed.length === 0) {
|
|
50
|
+
log("No changes detected. Index is up to date.");
|
|
51
|
+
return { succeeded: 0, failed: 0 };
|
|
52
|
+
}
|
|
53
|
+
// 2b. Skip files whose content hash is already known (indexed on another branch)
|
|
54
|
+
const knownHashes = await store.filterKnownFileHashes(changed.map((f) => f.hash));
|
|
55
|
+
const alreadyKnown = [];
|
|
56
|
+
const trulyChanged = [];
|
|
57
|
+
for (const f of changed) {
|
|
58
|
+
if (knownHashes.has(f.hash)) {
|
|
59
|
+
alreadyKnown.push(f);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
trulyChanged.push(f);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (alreadyKnown.length > 0) {
|
|
66
|
+
// Register these files on the current branch without re-chunking
|
|
67
|
+
const hashEntries = alreadyKnown.map((f) => ({
|
|
68
|
+
filePath: f.path,
|
|
69
|
+
fileHash: f.hash,
|
|
70
|
+
}));
|
|
71
|
+
await store.upsertFileHashes(hashEntries);
|
|
72
|
+
log(`${alreadyKnown.length} files already indexed (content known from other branches)`);
|
|
73
|
+
}
|
|
74
|
+
if (trulyChanged.length === 0) {
|
|
75
|
+
log("No new content to index.");
|
|
76
|
+
return { succeeded: 0, failed: 0 };
|
|
77
|
+
}
|
|
78
|
+
// 3. Chunk changed files
|
|
79
|
+
const changedPaths = trulyChanged.map((f) => f.path);
|
|
80
|
+
const allChunks = [];
|
|
81
|
+
for (let i = 0; i < changedPaths.length; i++) {
|
|
82
|
+
try {
|
|
83
|
+
const chunks = await chunker.chunk(changedPaths[i], cwd);
|
|
84
|
+
allChunks.push(...chunks);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// skip files that fail to parse
|
|
88
|
+
}
|
|
89
|
+
if ((i + 1) % 1000 === 0 || i === changedPaths.length - 1) {
|
|
90
|
+
emit?.({
|
|
91
|
+
phase: "chunk",
|
|
92
|
+
current: i + 1,
|
|
93
|
+
total: changedPaths.length,
|
|
94
|
+
message: `${allChunks.length} chunks`,
|
|
95
|
+
});
|
|
96
|
+
log(`Chunking: ${i + 1}/${changedPaths.length} files, ${allChunks.length} chunks so far`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (allChunks.length === 0) {
|
|
100
|
+
log("No chunks produced. Index is up to date.");
|
|
101
|
+
return { succeeded: 0, failed: 0 };
|
|
102
|
+
}
|
|
103
|
+
if (opts.dry) {
|
|
104
|
+
for (const f of changedPaths)
|
|
105
|
+
log(` ${f}`);
|
|
106
|
+
return { succeeded: 0, failed: 0 };
|
|
107
|
+
}
|
|
108
|
+
// 4. Delete old chunks for changed files
|
|
109
|
+
await store.deleteChunksByFiles(changedPaths);
|
|
110
|
+
// 5. Filter out already-indexed chunks (by hash, queried in DB)
|
|
111
|
+
const existingHashes = await store.filterExistingChunkHashes(allChunks.map((c) => c.hash));
|
|
112
|
+
let newChunks = allChunks.filter((c) => !existingHashes.has(c.hash));
|
|
113
|
+
const alreadyIndexed = allChunks.length - newChunks.length;
|
|
114
|
+
// Filter oversized chunks
|
|
115
|
+
let skippedOversize = 0;
|
|
116
|
+
if (config.maxTokens) {
|
|
117
|
+
const before = newChunks.length;
|
|
118
|
+
newChunks = newChunks.filter((c) => {
|
|
119
|
+
const est = Math.ceil((c.context.length + c.content.length) / 4);
|
|
120
|
+
return est <= config.maxTokens;
|
|
121
|
+
});
|
|
122
|
+
skippedOversize = before - newChunks.length;
|
|
123
|
+
}
|
|
124
|
+
log(`${changedPaths.length} files changed, ${allChunks.length} chunks total, ${newChunks.length} to embed` +
|
|
125
|
+
` (${alreadyIndexed} already indexed${skippedOversize > 0 ? `, ${skippedOversize} oversized` : ""})`);
|
|
126
|
+
if (newChunks.length === 0) {
|
|
127
|
+
const hashEntries = changedPaths
|
|
128
|
+
.filter((fp) => currentHashes.has(fp))
|
|
129
|
+
.map((fp) => ({
|
|
130
|
+
filePath: fp,
|
|
131
|
+
fileHash: currentHashes.get(fp),
|
|
132
|
+
}));
|
|
133
|
+
if (hashEntries.length > 0)
|
|
134
|
+
await store.upsertFileHashes(hashEntries);
|
|
135
|
+
log("All chunks already indexed.");
|
|
136
|
+
return { succeeded: 0, failed: 0 };
|
|
137
|
+
}
|
|
138
|
+
// 6. Embed and store
|
|
139
|
+
const resilient = new ResilientEmbedder(embedder, config, {
|
|
140
|
+
onBatchStart(batchNum, total) {
|
|
141
|
+
emit?.({ phase: "embed", current: batchNum, total });
|
|
142
|
+
},
|
|
143
|
+
onBatchDone(batchNum, succeeded, failed) {
|
|
144
|
+
log(`Batch ${batchNum}: ${succeeded} ok / ${failed} err / ${newChunks.length} total`);
|
|
145
|
+
},
|
|
146
|
+
onReload(attempt, max) {
|
|
147
|
+
log(`Consecutive failures — reloading model (attempt ${attempt}/${max})...`);
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
const texts = newChunks.map((c) => `${c.context}\n${c.content}`);
|
|
151
|
+
let vectors;
|
|
152
|
+
let failedIndices;
|
|
153
|
+
let aborted = false;
|
|
154
|
+
try {
|
|
155
|
+
const result = await resilient.embedBatched(texts);
|
|
156
|
+
vectors = result.vectors;
|
|
157
|
+
failedIndices = result.failedIndices;
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
if (err instanceof EmbeddingAbortError) {
|
|
161
|
+
aborted = true;
|
|
162
|
+
vectors = err.vectors;
|
|
163
|
+
failedIndices = err.failedIndices;
|
|
164
|
+
logger.error(err.message);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Store successful chunks
|
|
171
|
+
const indexed = [];
|
|
172
|
+
const failedFiles = new Set();
|
|
173
|
+
let embeddingDimensions;
|
|
174
|
+
for (let i = 0; i < newChunks.length; i++) {
|
|
175
|
+
if (vectors[i] !== null) {
|
|
176
|
+
indexed.push({ ...newChunks[i], vector: vectors[i] });
|
|
177
|
+
if (embeddingDimensions === undefined) {
|
|
178
|
+
embeddingDimensions = vectors[i].length;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
failedFiles.add(newChunks[i].filePath);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (indexed.length > 0) {
|
|
186
|
+
const STORE_BATCH = 500;
|
|
187
|
+
for (let i = 0; i < indexed.length; i += STORE_BATCH) {
|
|
188
|
+
await store.addChunks(indexed.slice(i, i + STORE_BATCH));
|
|
189
|
+
emit?.({
|
|
190
|
+
phase: "store",
|
|
191
|
+
current: Math.min(i + STORE_BATCH, indexed.length),
|
|
192
|
+
total: indexed.length,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Save file hashes for files with no failures
|
|
197
|
+
const hashEntries = changedPaths
|
|
198
|
+
.filter((fp) => currentHashes.has(fp) && !failedFiles.has(fp))
|
|
199
|
+
.map((fp) => ({ filePath: fp, fileHash: currentHashes.get(fp) }));
|
|
200
|
+
if (hashEntries.length > 0)
|
|
201
|
+
await store.upsertFileHashes(hashEntries);
|
|
202
|
+
const succeeded = indexed.length;
|
|
203
|
+
const failed = failedIndices.size;
|
|
204
|
+
if (aborted) {
|
|
205
|
+
if (succeeded > 0) {
|
|
206
|
+
log(`Saved ${succeeded} chunks before aborting.`);
|
|
207
|
+
}
|
|
208
|
+
log(`Embedding failed. ${failed} chunks could not be embedded. ` +
|
|
209
|
+
`Fix your embedding provider and run \`lmgrep index\` to resume.`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
log(`Done: ${succeeded} chunks indexed from ${changedPaths.length} files` +
|
|
213
|
+
(failed > 0 ? ` (${failed} failed)` : ""));
|
|
214
|
+
}
|
|
215
|
+
// Update project metadata (preserve original model/dimensions as baseline)
|
|
216
|
+
writeProjectMetadata(cwd, {
|
|
217
|
+
model: config.model,
|
|
218
|
+
dimensions: embeddingDimensions,
|
|
219
|
+
});
|
|
220
|
+
return { succeeded, failed };
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/lib/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,6 @@ export interface ChunkContext {
|
|
|
13
13
|
}
|
|
14
14
|
/** Walk up from a node to collect typed parent scopes */
|
|
15
15
|
export declare function extractScope(node: Parser.SyntaxNode, langConfig: LanguageConfig): ScopeEntry[];
|
|
16
|
-
/** Extract import module names from the root of the tree */
|
|
17
|
-
export declare function extractImports(tree: Parser.Tree, langConfig: LanguageConfig): string[];
|
|
18
|
-
/** Extract sibling signatures from the same parent scope */
|
|
19
|
-
export declare function extractSiblingSignatures(node: Parser.SyntaxNode, langConfig: LanguageConfig): string[];
|
|
20
16
|
/** Extract leading comments and decorators immediately before a node */
|
|
21
17
|
export declare function extractLeadingComment(node: Parser.SyntaxNode, source: string): string | null;
|
|
22
18
|
/** Classify a chunk's structural role based on its AST node type */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Map AST node types to human-readable scope kinds */
|
|
2
1
|
const SCOPE_KIND_MAP = {
|
|
3
2
|
// TypeScript / JavaScript
|
|
4
3
|
class_declaration: "class",
|
|
@@ -29,7 +28,6 @@ const SCOPE_KIND_MAP = {
|
|
|
29
28
|
// Generic
|
|
30
29
|
ContainerDecl: "container",
|
|
31
30
|
};
|
|
32
|
-
/** AST node types that represent type/structure definitions */
|
|
33
31
|
const DEFINITION_TYPES = new Set([
|
|
34
32
|
"class_declaration",
|
|
35
33
|
"class_definition",
|
|
@@ -47,11 +45,9 @@ const DEFINITION_TYPES = new Set([
|
|
|
47
45
|
"type_definition",
|
|
48
46
|
"struct_declaration",
|
|
49
47
|
"protocol_declaration",
|
|
50
|
-
"class_definition",
|
|
51
48
|
"trait_definition",
|
|
52
49
|
"ContainerDecl",
|
|
53
50
|
]);
|
|
54
|
-
/** AST node types that typically orchestrate / glue logic */
|
|
55
51
|
const ORCHESTRATION_TYPES = new Set([
|
|
56
52
|
"export_statement",
|
|
57
53
|
"decorated_definition",
|
|
@@ -72,80 +68,11 @@ export function extractScope(node, langConfig) {
|
|
|
72
68
|
}
|
|
73
69
|
return scopes;
|
|
74
70
|
}
|
|
75
|
-
/** Extract import module names from the root of the tree */
|
|
76
|
-
export function extractImports(tree, langConfig) {
|
|
77
|
-
const modules = [];
|
|
78
|
-
for (const child of tree.rootNode.children) {
|
|
79
|
-
if (langConfig.importTypes.includes(child.type)) {
|
|
80
|
-
const mod = extractModuleName(child);
|
|
81
|
-
if (mod && !modules.includes(mod)) {
|
|
82
|
-
modules.push(mod);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return modules;
|
|
87
|
-
}
|
|
88
|
-
/** Pull out just the module/package name from an import node */
|
|
89
|
-
function extractModuleName(node) {
|
|
90
|
-
// Look for string children (the module specifier)
|
|
91
|
-
const stringNode = findDescendant(node, (n) => n.type === "string" ||
|
|
92
|
-
n.type === "string_literal" ||
|
|
93
|
-
n.type === "interpreted_string_literal");
|
|
94
|
-
if (stringNode) {
|
|
95
|
-
// Strip quotes
|
|
96
|
-
return stringNode.text.replace(/^["']|["']$/g, "");
|
|
97
|
-
}
|
|
98
|
-
// Python: import foo.bar / from foo.bar import baz
|
|
99
|
-
const dottedName = findDescendant(node, (n) => n.type === "dotted_name" || n.type === "module_name");
|
|
100
|
-
if (dottedName)
|
|
101
|
-
return dottedName.text;
|
|
102
|
-
// Rust: use crate::foo::bar
|
|
103
|
-
const path = findDescendant(node, (n) => n.type === "scoped_identifier" || n.type === "use_list");
|
|
104
|
-
if (path)
|
|
105
|
-
return path.text;
|
|
106
|
-
// C/C++: #include <foo.h> or "foo.h"
|
|
107
|
-
const sysLib = findDescendant(node, (n) => n.type === "system_lib_string" || n.type === "string_literal");
|
|
108
|
-
if (sysLib)
|
|
109
|
-
return sysLib.text.replace(/^[<"]|[>"]$/g, "");
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
function findDescendant(node, predicate) {
|
|
113
|
-
for (const child of node.children) {
|
|
114
|
-
if (predicate(child))
|
|
115
|
-
return child;
|
|
116
|
-
const found = findDescendant(child, predicate);
|
|
117
|
-
if (found)
|
|
118
|
-
return found;
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
/** Extract sibling signatures from the same parent scope */
|
|
123
|
-
export function extractSiblingSignatures(node, langConfig) {
|
|
124
|
-
const parent = node.parent;
|
|
125
|
-
if (!parent)
|
|
126
|
-
return [];
|
|
127
|
-
const siblings = [];
|
|
128
|
-
for (const child of parent.children) {
|
|
129
|
-
if (child.id === node.id)
|
|
130
|
-
continue;
|
|
131
|
-
if (!langConfig.chunkTypes.includes(child.type))
|
|
132
|
-
continue;
|
|
133
|
-
const name = extractNodeName(child);
|
|
134
|
-
if (name) {
|
|
135
|
-
const firstLine = child.text.split("\n")[0].trim();
|
|
136
|
-
if (firstLine.length < 200) {
|
|
137
|
-
siblings.push(firstLine);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return siblings.slice(0, 10);
|
|
142
|
-
}
|
|
143
71
|
/** Extract leading comments and decorators immediately before a node */
|
|
144
72
|
export function extractLeadingComment(node, source) {
|
|
145
73
|
const lines = source.split("\n");
|
|
146
74
|
const nodeStartLine = node.startPosition.row;
|
|
147
75
|
const collected = [];
|
|
148
|
-
// Walk backwards from the line before the node
|
|
149
76
|
for (let i = nodeStartLine - 1; i >= 0 && i >= nodeStartLine - 10; i--) {
|
|
150
77
|
const line = lines[i].trim();
|
|
151
78
|
if (line.startsWith("//") ||
|
|
@@ -161,7 +88,6 @@ export function extractLeadingComment(node, source) {
|
|
|
161
88
|
collected.unshift(lines[i]);
|
|
162
89
|
}
|
|
163
90
|
else if (line === "") {
|
|
164
|
-
// Allow one blank line gap
|
|
165
91
|
if (collected.length > 0)
|
|
166
92
|
break;
|
|
167
93
|
}
|
|
@@ -187,7 +113,9 @@ export function buildContextString(ctx) {
|
|
|
187
113
|
lines.push(`[file: ${ctx.filePath}]`);
|
|
188
114
|
lines.push(`[role: ${ctx.role}]`);
|
|
189
115
|
if (ctx.scope.length > 0) {
|
|
190
|
-
const scopeStr = ctx.scope
|
|
116
|
+
const scopeStr = ctx.scope
|
|
117
|
+
.map((s) => `${s.kind} ${s.name}`)
|
|
118
|
+
.join(" > ");
|
|
191
119
|
lines.push(`[scope: ${scopeStr}]`);
|
|
192
120
|
}
|
|
193
121
|
if (ctx.leadingComment) {
|
|
@@ -195,7 +123,6 @@ export function buildContextString(ctx) {
|
|
|
195
123
|
}
|
|
196
124
|
return lines.join("\n");
|
|
197
125
|
}
|
|
198
|
-
/** Try to extract a name identifier from an AST node */
|
|
199
126
|
function extractNodeName(node) {
|
|
200
127
|
const nameNode = node.childForFieldName("name") ??
|
|
201
128
|
node.children.find((c) => c.type === "identifier" || c.type === "type_identifier");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/lib/chunker/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Chunk, Chunker } from "../types.js";
|
|
2
|
+
/** Chunk a single file into context-enriched chunks */
|
|
3
|
+
export declare function chunkFile(filePath: string, cwd: string): Promise<Chunk[]>;
|
|
4
|
+
/** Default chunker using tree-sitter with sliding-window fallback */
|
|
5
|
+
export declare class TreeSitterChunker implements Chunker {
|
|
6
|
+
chunk(filePath: string, cwd: string): Promise<Chunk[]>;
|
|
7
|
+
}
|