@wrongstack/tools 0.66.13 → 0.73.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/dist/{codebase-stats-tool-C8ApERbn.d.ts → background-indexer-sbsseCCC.d.ts} +49 -1
- package/dist/builtin.js +122 -54
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.d.ts +35 -4
- package/dist/codebase-index/index.js +140 -12
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +145 -13
- package/dist/index.js.map +1 -1
- package/dist/pack.js +122 -54
- package/dist/pack.js.map +1 -1
- package/dist/tool-search.js +5 -1
- package/dist/tool-search.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { forgetTool, rememberTool } from './memory.js';
|
|
|
33
33
|
export { createModeTool } from './mode.js';
|
|
34
34
|
export { KillOpts, RegistryStats, TrackedProcess, _resetProcessRegistry, getProcessRegistry } from './process-registry.js';
|
|
35
35
|
export { CircuitBreaker, CircuitBreakerConfig, CircuitBreakerSnapshot } from './circuit-breaker.js';
|
|
36
|
-
export { g as
|
|
36
|
+
export { g as cancelPendingReindexes, h as codebaseIndexTool, i as codebaseSearchTool, j as codebaseStatsTool, k as enqueueReindex, l as isIndexableFile, r as runStartupIndex } from './background-indexer-sbsseCCC.js';
|
|
37
37
|
export { builtinTools } from './builtin.js';
|
|
38
38
|
export { builtinToolsPack } from './pack.js';
|
|
39
39
|
import 'node:child_process';
|
package/dist/index.js
CHANGED
|
@@ -3112,8 +3112,8 @@ var jsonTool = {
|
|
|
3112
3112
|
};
|
|
3113
3113
|
}
|
|
3114
3114
|
};
|
|
3115
|
-
function query(data,
|
|
3116
|
-
const parts =
|
|
3115
|
+
function query(data, path19) {
|
|
3116
|
+
const parts = path19.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
|
|
3117
3117
|
let current = data;
|
|
3118
3118
|
for (const part of parts) {
|
|
3119
3119
|
if (current === null || current === void 0) return void 0;
|
|
@@ -4404,7 +4404,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
4404
4404
|
}
|
|
4405
4405
|
var DOCKER_LOGS_TIMEOUT_MS = 3e3;
|
|
4406
4406
|
var MAX_TAIL_LINES = 1e5;
|
|
4407
|
-
async function fileLogs(
|
|
4407
|
+
async function fileLogs(path19, lines, filterRe, stream) {
|
|
4408
4408
|
const { createInterface } = await import('node:readline');
|
|
4409
4409
|
const { createReadStream } = await import('node:fs');
|
|
4410
4410
|
const entries = [];
|
|
@@ -4413,7 +4413,7 @@ async function fileLogs(path18, lines, filterRe, stream) {
|
|
|
4413
4413
|
let writeIdx = 0;
|
|
4414
4414
|
let totalLines = 0;
|
|
4415
4415
|
const rl = createInterface({
|
|
4416
|
-
input: createReadStream(
|
|
4416
|
+
input: createReadStream(path19),
|
|
4417
4417
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
4418
4418
|
});
|
|
4419
4419
|
for await (const line of rl) {
|
|
@@ -4434,7 +4434,7 @@ async function fileLogs(path18, lines, filterRe, stream) {
|
|
|
4434
4434
|
if (parsed) entries.push(parsed);
|
|
4435
4435
|
}
|
|
4436
4436
|
return {
|
|
4437
|
-
source:
|
|
4437
|
+
source: path19,
|
|
4438
4438
|
entries,
|
|
4439
4439
|
total: entries.length,
|
|
4440
4440
|
truncated: totalLines > effLines,
|
|
@@ -4874,10 +4874,14 @@ var toolSearchTool = {
|
|
|
4874
4874
|
permission: t.permission,
|
|
4875
4875
|
mutating: t.mutating
|
|
4876
4876
|
}));
|
|
4877
|
+
const totalAvailable = tools.length;
|
|
4878
|
+
const hint = results.length === 0 && query2 ? `No tools matched "${input.query}". Use tool-help (without arguments) to see all ${totalAvailable} available tools.` : void 0;
|
|
4877
4879
|
return {
|
|
4878
4880
|
tools: results,
|
|
4879
4881
|
total: filtered.length,
|
|
4880
|
-
truncated: filtered.length > limit
|
|
4882
|
+
truncated: filtered.length > limit,
|
|
4883
|
+
...hint ? { hint } : {},
|
|
4884
|
+
_available: totalAvailable
|
|
4881
4885
|
};
|
|
4882
4886
|
}
|
|
4883
4887
|
};
|
|
@@ -5565,6 +5569,17 @@ var IndexStore = class {
|
|
|
5565
5569
|
({ id, text }) => ({ id, text })
|
|
5566
5570
|
);
|
|
5567
5571
|
}
|
|
5572
|
+
/**
|
|
5573
|
+
* Largest symbol id currently in the table (0 when empty). New ids must be
|
|
5574
|
+
* allocated from this, NOT from `COUNT(*)`: incremental reindexes delete a
|
|
5575
|
+
* changed file's rows, so the row count drops below the max id and a
|
|
5576
|
+
* count-based id would collide with a surviving row (UNIQUE constraint on
|
|
5577
|
+
* `symbols.id`). Ids may have gaps — that is fine.
|
|
5578
|
+
*/
|
|
5579
|
+
getMaxSymbolId() {
|
|
5580
|
+
const rows = this.db.prepare("SELECT MAX(id) AS m FROM symbols").all();
|
|
5581
|
+
return rows[0]?.m ?? 0;
|
|
5582
|
+
}
|
|
5568
5583
|
// ─── Stats ───────────────────────────────────────────────────────────────────
|
|
5569
5584
|
getStats() {
|
|
5570
5585
|
const sizeBytes = this.sizeBytes();
|
|
@@ -6883,6 +6898,56 @@ function makeSymbol2(opts) {
|
|
|
6883
6898
|
text: `${opts.name} ${opts.signature}`.trim()
|
|
6884
6899
|
};
|
|
6885
6900
|
}
|
|
6901
|
+
function globBody(glob) {
|
|
6902
|
+
return compileGlob(glob).source.replace(/^\^/, "").replace(/\$$/, "");
|
|
6903
|
+
}
|
|
6904
|
+
function compileGitignore(lines) {
|
|
6905
|
+
const rules = [];
|
|
6906
|
+
for (const raw of lines) {
|
|
6907
|
+
let line = raw.replace(/\r$/, "");
|
|
6908
|
+
if (!line.trim() || line.trimStart().startsWith("#")) continue;
|
|
6909
|
+
line = line.trim();
|
|
6910
|
+
let negated = false;
|
|
6911
|
+
if (line.startsWith("!")) {
|
|
6912
|
+
negated = true;
|
|
6913
|
+
line = line.slice(1);
|
|
6914
|
+
}
|
|
6915
|
+
let dirOnly = false;
|
|
6916
|
+
if (line.endsWith("/")) {
|
|
6917
|
+
dirOnly = true;
|
|
6918
|
+
line = line.slice(0, -1);
|
|
6919
|
+
}
|
|
6920
|
+
if (!line) continue;
|
|
6921
|
+
const anchored = line.startsWith("/") || line.includes("/");
|
|
6922
|
+
if (line.startsWith("/")) line = line.slice(1);
|
|
6923
|
+
const body = globBody(line);
|
|
6924
|
+
const prefix = anchored ? "^" : "(?:^|.*/)";
|
|
6925
|
+
rules.push({
|
|
6926
|
+
eqOrUnder: new RegExp(`${prefix}${body}(?:/.*)?$`),
|
|
6927
|
+
under: new RegExp(`${prefix}${body}/.*$`),
|
|
6928
|
+
negated,
|
|
6929
|
+
dirOnly
|
|
6930
|
+
});
|
|
6931
|
+
}
|
|
6932
|
+
return (relPath, isDir) => {
|
|
6933
|
+
const p = relPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
6934
|
+
let ignored = false;
|
|
6935
|
+
for (const r of rules) {
|
|
6936
|
+
const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;
|
|
6937
|
+
if (re.test(p)) ignored = !r.negated;
|
|
6938
|
+
}
|
|
6939
|
+
return ignored;
|
|
6940
|
+
};
|
|
6941
|
+
}
|
|
6942
|
+
async function loadGitignoreMatcher(projectRoot) {
|
|
6943
|
+
let lines = [];
|
|
6944
|
+
try {
|
|
6945
|
+
const raw = await fs4.readFile(path.join(projectRoot, ".gitignore"), "utf8");
|
|
6946
|
+
lines = raw.split("\n");
|
|
6947
|
+
} catch {
|
|
6948
|
+
}
|
|
6949
|
+
return compileGitignore(lines);
|
|
6950
|
+
}
|
|
6886
6951
|
|
|
6887
6952
|
// src/codebase-index/indexer.ts
|
|
6888
6953
|
var DEFAULT_IGNORE5 = [
|
|
@@ -6896,7 +6961,7 @@ var DEFAULT_IGNORE5 = [
|
|
|
6896
6961
|
"__snapshots__",
|
|
6897
6962
|
".nyc_output"
|
|
6898
6963
|
];
|
|
6899
|
-
async function findSourceFiles(projectRoot, ignore) {
|
|
6964
|
+
async function findSourceFiles(projectRoot, ignore, isGitIgnored) {
|
|
6900
6965
|
const results = [];
|
|
6901
6966
|
const ignoreSet = /* @__PURE__ */ new Set([...DEFAULT_IGNORE5, ...ignore]);
|
|
6902
6967
|
const globs = [
|
|
@@ -6921,10 +6986,12 @@ async function findSourceFiles(projectRoot, ignore) {
|
|
|
6921
6986
|
for (const e of entries) {
|
|
6922
6987
|
if (ignoreSet.has(e.name)) continue;
|
|
6923
6988
|
const full = path.join(dir, e.name);
|
|
6989
|
+
const rel = path.relative(projectRoot, full).replace(/\\/g, "/");
|
|
6924
6990
|
if (e.isDirectory()) {
|
|
6991
|
+
if (isGitIgnored(rel, true)) continue;
|
|
6925
6992
|
await walk(full);
|
|
6926
6993
|
} else if (e.isFile()) {
|
|
6927
|
-
|
|
6994
|
+
if (isGitIgnored(rel, false)) continue;
|
|
6928
6995
|
const ext = path.extname(e.name);
|
|
6929
6996
|
for (const { ext: extName, pat } of globs) {
|
|
6930
6997
|
if (ext === extName && (pat.test(rel) || pat.test(e.name))) {
|
|
@@ -6967,11 +7034,12 @@ async function runIndexer(_ctx, opts) {
|
|
|
6967
7034
|
const langStats = {};
|
|
6968
7035
|
let filesIndexed = 0;
|
|
6969
7036
|
let symbolsIndexed = 0;
|
|
7037
|
+
const isGitIgnored = await loadGitignoreMatcher(projectRoot);
|
|
6970
7038
|
let files;
|
|
6971
7039
|
if (opts.files && opts.files.length > 0) {
|
|
6972
|
-
files = opts.files.map((f) => path.resolve(projectRoot, f));
|
|
7040
|
+
files = opts.files.map((f) => path.resolve(projectRoot, f)).filter((f) => !isGitIgnored(path.relative(projectRoot, f).replace(/\\/g, "/"), false));
|
|
6973
7041
|
} else {
|
|
6974
|
-
files = await findSourceFiles(projectRoot, ignore);
|
|
7042
|
+
files = await findSourceFiles(projectRoot, ignore, isGitIgnored);
|
|
6975
7043
|
}
|
|
6976
7044
|
if (langs && langs.length > 0) {
|
|
6977
7045
|
const langSet = new Set(langs);
|
|
@@ -7003,8 +7071,8 @@ async function runIndexer(_ctx, opts) {
|
|
|
7003
7071
|
filesIndexed++;
|
|
7004
7072
|
continue;
|
|
7005
7073
|
}
|
|
7006
|
-
store.deleteSymbolsForFile(file);
|
|
7007
7074
|
store.deleteRefsForFile(file);
|
|
7075
|
+
store.deleteSymbolsForFile(file);
|
|
7008
7076
|
let content;
|
|
7009
7077
|
try {
|
|
7010
7078
|
content = await fs4.readFile(file, "utf8");
|
|
@@ -7030,7 +7098,7 @@ async function runIndexer(_ctx, opts) {
|
|
|
7030
7098
|
filesIndexed++;
|
|
7031
7099
|
continue;
|
|
7032
7100
|
}
|
|
7033
|
-
const nextId = store.
|
|
7101
|
+
const nextId = store.getMaxSymbolId() + 1;
|
|
7034
7102
|
const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
|
|
7035
7103
|
store.insertSymbols(symbolsWithIds, nextId);
|
|
7036
7104
|
const count = symbolsWithIds.length;
|
|
@@ -7316,6 +7384,70 @@ var codebaseStatsTool = {
|
|
|
7316
7384
|
}
|
|
7317
7385
|
};
|
|
7318
7386
|
|
|
7387
|
+
// src/codebase-index/background-indexer.ts
|
|
7388
|
+
function stubCtx(projectRoot) {
|
|
7389
|
+
return {
|
|
7390
|
+
projectRoot,
|
|
7391
|
+
cwd: projectRoot,
|
|
7392
|
+
messages: [],
|
|
7393
|
+
todos: [],
|
|
7394
|
+
readFiles: /* @__PURE__ */ new Set(),
|
|
7395
|
+
fileMtimes: /* @__PURE__ */ new Map()
|
|
7396
|
+
};
|
|
7397
|
+
}
|
|
7398
|
+
var chain = Promise.resolve();
|
|
7399
|
+
function withMutex(job) {
|
|
7400
|
+
const run = chain.then(job, job);
|
|
7401
|
+
chain = run.then(
|
|
7402
|
+
() => void 0,
|
|
7403
|
+
() => void 0
|
|
7404
|
+
);
|
|
7405
|
+
return run;
|
|
7406
|
+
}
|
|
7407
|
+
var DEFAULT_DEBOUNCE_MS = 400;
|
|
7408
|
+
var debounceTimers = /* @__PURE__ */ new Map();
|
|
7409
|
+
function debounceKey(indexDir, file) {
|
|
7410
|
+
return `${indexDir ?? ""}|${file}`;
|
|
7411
|
+
}
|
|
7412
|
+
function isIndexableFile(filePath) {
|
|
7413
|
+
return detectLang(filePath) !== null;
|
|
7414
|
+
}
|
|
7415
|
+
function runStartupIndex(opts) {
|
|
7416
|
+
return withMutex(
|
|
7417
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7418
|
+
projectRoot: opts.projectRoot,
|
|
7419
|
+
indexDir: opts.indexDir,
|
|
7420
|
+
force: opts.force
|
|
7421
|
+
})
|
|
7422
|
+
);
|
|
7423
|
+
}
|
|
7424
|
+
function enqueueReindex(opts) {
|
|
7425
|
+
const files = opts.files.filter(isIndexableFile);
|
|
7426
|
+
if (files.length === 0) return;
|
|
7427
|
+
const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
7428
|
+
for (const file of files) {
|
|
7429
|
+
const key = debounceKey(opts.indexDir, file);
|
|
7430
|
+
const existing = debounceTimers.get(key);
|
|
7431
|
+
if (existing) clearTimeout(existing);
|
|
7432
|
+
const timer = setTimeout(() => {
|
|
7433
|
+
debounceTimers.delete(key);
|
|
7434
|
+
void withMutex(
|
|
7435
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7436
|
+
projectRoot: opts.projectRoot,
|
|
7437
|
+
files: [file],
|
|
7438
|
+
indexDir: opts.indexDir
|
|
7439
|
+
})
|
|
7440
|
+
).catch((err) => opts.onError?.(err));
|
|
7441
|
+
}, ms);
|
|
7442
|
+
timer.unref?.();
|
|
7443
|
+
debounceTimers.set(key, timer);
|
|
7444
|
+
}
|
|
7445
|
+
}
|
|
7446
|
+
function cancelPendingReindexes() {
|
|
7447
|
+
for (const t of debounceTimers.values()) clearTimeout(t);
|
|
7448
|
+
debounceTimers.clear();
|
|
7449
|
+
}
|
|
7450
|
+
|
|
7319
7451
|
// src/builtin.ts
|
|
7320
7452
|
var builtinTools = [
|
|
7321
7453
|
readTool,
|
|
@@ -7361,6 +7493,6 @@ var builtinToolsPack = {
|
|
|
7361
7493
|
tools: builtinTools
|
|
7362
7494
|
};
|
|
7363
7495
|
|
|
7364
|
-
export { CircuitBreaker, _resetProcessRegistry, auditTool, bashTool, batchToolUseTool, builtinTools, builtinToolsPack, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, createModeTool, diffTool, documentTool, editTool, execTool, fetchTool, forgetTool, formatTool, getProcessRegistry, gitTool, globTool, grepTool, installTool, jsonTool, lintTool, logsTool, outdatedTool, patchTool, planTool, readTool, rememberTool, replaceTool, scaffoldTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7496
|
+
export { CircuitBreaker, _resetProcessRegistry, auditTool, bashTool, batchToolUseTool, builtinTools, builtinToolsPack, cancelPendingReindexes, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, createModeTool, diffTool, documentTool, editTool, enqueueReindex, execTool, fetchTool, forgetTool, formatTool, getProcessRegistry, gitTool, globTool, grepTool, installTool, isIndexableFile, jsonTool, lintTool, logsTool, outdatedTool, patchTool, planTool, readTool, rememberTool, replaceTool, runStartupIndex, scaffoldTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7365
7497
|
//# sourceMappingURL=index.js.map
|
|
7366
7498
|
//# sourceMappingURL=index.js.map
|