@wrongstack/tools 0.267.0 → 0.269.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/batch-tool-use.js.map +1 -1
- package/dist/builtin.js +147 -131
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +101 -85
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/codebase-index/worker.js +101 -85
- package/dist/codebase-index/worker.js.map +1 -1
- package/dist/exec.js +63 -12
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js.map +1 -1
- package/dist/index.js +147 -131
- package/dist/index.js.map +1 -1
- package/dist/pack.js +147 -131
- package/dist/pack.js.map +1 -1
- package/dist/search.js.map +1 -1
- package/package.json +2 -2
|
@@ -339,7 +339,7 @@ var IndexStore = class {
|
|
|
339
339
|
throw new LockError(`SQLite lock conflict after ${MAX_LOCK_RETRIES} retries: ${msg}`);
|
|
340
340
|
}
|
|
341
341
|
const delay = Math.min(
|
|
342
|
-
LOCK_RETRY_BASE_DELAY_MS *
|
|
342
|
+
LOCK_RETRY_BASE_DELAY_MS * 2 ** attempt,
|
|
343
343
|
LOCK_RETRY_MAX_DELAY_MS
|
|
344
344
|
);
|
|
345
345
|
sleepSync(delay);
|
|
@@ -632,14 +632,15 @@ var IndexStore = class {
|
|
|
632
632
|
if (!query.trim()) {
|
|
633
633
|
return { results: candidates.slice(0, limit), total: candidates.length };
|
|
634
634
|
}
|
|
635
|
+
const candidateById = new Map(candidates.map((c) => [c.id, c]));
|
|
635
636
|
const bm25 = buildBm25Index(
|
|
636
637
|
candidates.map((c) => ({ id: c.id, text: buildIndexableText(c.name, c.signature, c.docComment) }))
|
|
637
638
|
);
|
|
638
|
-
const scored = bm25.score(query, (id) =>
|
|
639
|
+
const scored = bm25.score(query, (id) => candidateById.has(id));
|
|
639
640
|
scored.sort((a, b) => b.score - a.score);
|
|
640
641
|
const qTokens = tokenise(query);
|
|
641
642
|
const results = scored.slice(0, limit).map(({ id, score }) => {
|
|
642
|
-
const c = expectDefined(
|
|
643
|
+
const c = expectDefined(candidateById.get(id));
|
|
643
644
|
return { ...c, score, snippet: bm25.extractSnippet(id, qTokens) };
|
|
644
645
|
});
|
|
645
646
|
return { results, total: candidates.length };
|
|
@@ -2056,6 +2057,7 @@ async function loadGitignoreMatcher(projectRoot) {
|
|
|
2056
2057
|
|
|
2057
2058
|
// src/codebase-index/indexer.ts
|
|
2058
2059
|
var YIELD_EVERY_N = 50;
|
|
2060
|
+
var PARALLEL_BATCH = 20;
|
|
2059
2061
|
function yieldEventLoop() {
|
|
2060
2062
|
return new Promise((resolve2) => setImmediate(resolve2));
|
|
2061
2063
|
}
|
|
@@ -2189,97 +2191,111 @@ async function runIndexerWithStore(store, opts) {
|
|
|
2189
2191
|
if (!force) {
|
|
2190
2192
|
for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
|
|
2191
2193
|
}
|
|
2192
|
-
for (let
|
|
2193
|
-
const
|
|
2194
|
-
|
|
2195
|
-
|
|
2194
|
+
for (let batchStart = 0; batchStart < files.length; batchStart += PARALLEL_BATCH) {
|
|
2195
|
+
const batchEnd = Math.min(batchStart + PARALLEL_BATCH, files.length);
|
|
2196
|
+
const batchFiles = files.slice(batchStart, batchEnd);
|
|
2197
|
+
opts.onProgress?.(batchEnd, files.length);
|
|
2198
|
+
if (batchStart > 0 && batchStart % YIELD_EVERY_N === 0) {
|
|
2196
2199
|
await yieldEventLoop();
|
|
2197
2200
|
throwIfAborted(signal);
|
|
2198
2201
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
let parsed;
|
|
2229
|
-
try {
|
|
2230
|
-
parsed = await parseFile(file, content, lang);
|
|
2231
|
-
} catch (e) {
|
|
2232
|
-
errors.push(`parse error: ${file}: ${e instanceof Error ? e.message : String(e)}`);
|
|
2233
|
-
continue;
|
|
2234
|
-
}
|
|
2235
|
-
if (parsed.symbols.length === 0) {
|
|
2236
|
-
store.upsertFile({
|
|
2237
|
-
file,
|
|
2238
|
-
lang,
|
|
2239
|
-
mtimeMs: Math.floor(stat2.mtimeMs),
|
|
2240
|
-
symbolCount: 0,
|
|
2241
|
-
lastIndexed: Date.now()
|
|
2242
|
-
});
|
|
2243
|
-
filesIndexed++;
|
|
2244
|
-
continue;
|
|
2245
|
-
}
|
|
2246
|
-
const nextId = store.getMaxSymbolId() + 1;
|
|
2247
|
-
const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
|
|
2248
|
-
store.insertSymbols(symbolsWithIds, nextId);
|
|
2249
|
-
const count = symbolsWithIds.length;
|
|
2250
|
-
symbolsIndexed += count;
|
|
2251
|
-
langStats[lang] = (langStats[lang] ?? 0) + count;
|
|
2252
|
-
if (parsed.refs && parsed.refs.length > 0) {
|
|
2253
|
-
const refsByLine = /* @__PURE__ */ new Map();
|
|
2254
|
-
for (const r of parsed.refs) {
|
|
2255
|
-
let arr = refsByLine.get(r.line);
|
|
2256
|
-
if (!arr) {
|
|
2257
|
-
arr = [];
|
|
2258
|
-
refsByLine.set(r.line, arr);
|
|
2202
|
+
const statOpts = signal ? { signal } : {};
|
|
2203
|
+
const statReadParse = await Promise.allSettled(
|
|
2204
|
+
batchFiles.map(async (file) => {
|
|
2205
|
+
let stat2;
|
|
2206
|
+
try {
|
|
2207
|
+
stat2 = await fs3.stat(file, statOpts);
|
|
2208
|
+
} catch (e) {
|
|
2209
|
+
if (isAbortError(e)) throw e;
|
|
2210
|
+
return { file, stat: null, lang: "", parsed: null, error: `stat error: ${e instanceof Error ? e.message : String(e)}` };
|
|
2211
|
+
}
|
|
2212
|
+
if (!stat2.isFile()) return { file, stat: stat2, lang: "", parsed: null };
|
|
2213
|
+
const lang = detectLang(file);
|
|
2214
|
+
if (!lang) return { file, stat: stat2, lang: "", parsed: null };
|
|
2215
|
+
const meta = existingMeta.get(file);
|
|
2216
|
+
if (!force && meta && meta.mtimeMs === Math.floor(stat2.mtimeMs)) {
|
|
2217
|
+
return { file, stat: stat2, lang, parsed: null, skippedMeta: meta };
|
|
2218
|
+
}
|
|
2219
|
+
let content;
|
|
2220
|
+
try {
|
|
2221
|
+
content = await fs3.readFile(file, { encoding: "utf8", signal });
|
|
2222
|
+
} catch (e) {
|
|
2223
|
+
if (isAbortError(e)) throw e;
|
|
2224
|
+
return { file, stat: stat2, lang, parsed: null, error: `read error: ${e instanceof Error ? e.message : String(e)}` };
|
|
2225
|
+
}
|
|
2226
|
+
let parsed;
|
|
2227
|
+
try {
|
|
2228
|
+
parsed = await parseFile(file, content, lang);
|
|
2229
|
+
} catch (e) {
|
|
2230
|
+
return { file, stat: stat2, lang, parsed: null, error: `parse error: ${e instanceof Error ? e.message : String(e)}` };
|
|
2259
2231
|
}
|
|
2260
|
-
|
|
2232
|
+
return { file, stat: stat2, lang, parsed, content };
|
|
2233
|
+
})
|
|
2234
|
+
);
|
|
2235
|
+
for (let fi = 0; fi < statReadParse.length; fi++) {
|
|
2236
|
+
const settled = statReadParse[fi];
|
|
2237
|
+
const file = expectDefined(batchFiles[fi]);
|
|
2238
|
+
if (settled.status === "rejected") {
|
|
2239
|
+
const err = settled.reason;
|
|
2240
|
+
if (err instanceof Error && isAbortError(err)) throw err;
|
|
2241
|
+
errors.push(`batch error: ${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2242
|
+
continue;
|
|
2261
2243
|
}
|
|
2262
|
-
const
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
if (
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2244
|
+
const result = settled.value;
|
|
2245
|
+
if (result.error) {
|
|
2246
|
+
if (result.stat) store.deleteFile(file);
|
|
2247
|
+
if (result.error.includes("error:")) errors.push(result.error);
|
|
2248
|
+
continue;
|
|
2249
|
+
}
|
|
2250
|
+
const { stat: stat2, lang, parsed } = result;
|
|
2251
|
+
if (result.skippedMeta) {
|
|
2252
|
+
langStats[lang] = (langStats[lang] ?? 0) + result.skippedMeta.symbolCount;
|
|
2253
|
+
symbolsIndexed += result.skippedMeta.symbolCount;
|
|
2254
|
+
filesIndexed++;
|
|
2255
|
+
continue;
|
|
2256
|
+
}
|
|
2257
|
+
if (!lang || !parsed) {
|
|
2258
|
+
if (lang) {
|
|
2259
|
+
store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: 0, lastIndexed: Date.now() });
|
|
2260
|
+
filesIndexed++;
|
|
2269
2261
|
}
|
|
2262
|
+
continue;
|
|
2270
2263
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2264
|
+
store.deleteRefsForFile(file);
|
|
2265
|
+
store.deleteSymbolsForFile(file);
|
|
2266
|
+
if (parsed.symbols.length === 0) {
|
|
2267
|
+
store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: 0, lastIndexed: Date.now() });
|
|
2268
|
+
filesIndexed++;
|
|
2269
|
+
continue;
|
|
2273
2270
|
}
|
|
2271
|
+
const nextId = store.getMaxSymbolId() + 1;
|
|
2272
|
+
const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
|
|
2273
|
+
store.insertSymbols(symbolsWithIds, nextId);
|
|
2274
|
+
const count = symbolsWithIds.length;
|
|
2275
|
+
symbolsIndexed += count;
|
|
2276
|
+
langStats[lang] = (langStats[lang] ?? 0) + count;
|
|
2277
|
+
if (parsed.refs && parsed.refs.length > 0) {
|
|
2278
|
+
const refsByLine = /* @__PURE__ */ new Map();
|
|
2279
|
+
for (const r of parsed.refs) {
|
|
2280
|
+
let arr = refsByLine.get(r.line);
|
|
2281
|
+
if (!arr) {
|
|
2282
|
+
arr = [];
|
|
2283
|
+
refsByLine.set(r.line, arr);
|
|
2284
|
+
}
|
|
2285
|
+
arr.push(r);
|
|
2286
|
+
}
|
|
2287
|
+
const batch = [];
|
|
2288
|
+
for (const sym of symbolsWithIds) {
|
|
2289
|
+
const symRefs = refsByLine.get(sym.line);
|
|
2290
|
+
if (symRefs) {
|
|
2291
|
+
for (const r of symRefs) batch.push({ ...r, fromId: sym.id });
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (batch.length > 0) store.insertRefsBatch(batch);
|
|
2295
|
+
}
|
|
2296
|
+
store.upsertFile({ file, lang, mtimeMs: Math.floor(stat2.mtimeMs), symbolCount: count, lastIndexed: Date.now() });
|
|
2297
|
+
filesIndexed++;
|
|
2274
2298
|
}
|
|
2275
|
-
store.upsertFile({
|
|
2276
|
-
file,
|
|
2277
|
-
lang,
|
|
2278
|
-
mtimeMs: Math.floor(stat2.mtimeMs),
|
|
2279
|
-
symbolCount: count,
|
|
2280
|
-
lastIndexed: Date.now()
|
|
2281
|
-
});
|
|
2282
|
-
filesIndexed++;
|
|
2283
2299
|
}
|
|
2284
2300
|
for (const [file_] of existingMeta) {
|
|
2285
2301
|
try {
|