@wrongstack/tools 0.68.0 → 0.77.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/{codebase-stats-tool-C8ApERbn.d.ts → background-indexer-C70RD7LU.d.ts} +81 -1
- package/dist/builtin.js +216 -56
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.d.ts +35 -4
- package/dist/codebase-index/index.js +267 -13
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +274 -15
- package/dist/index.js.map +1 -1
- package/dist/pack.js +216 -56
- package/dist/pack.js.map +1 -1
- package/dist/todo.js +2 -1
- package/dist/todo.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 getIndexState, m as isIndexReady, n as isIndexableFile, o as isIndexing, p as onIndexStateChange, r as runStartupIndex } from './background-indexer-C70RD7LU.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
|
@@ -2463,9 +2463,10 @@ var todoTool = {
|
|
|
2463
2463
|
name: "todo",
|
|
2464
2464
|
category: "Session",
|
|
2465
2465
|
description: "Manage the session-level todo list. This is the primary mechanism for tracking multi-step work. The list is fully replaced on every call (not appended).",
|
|
2466
|
-
usageHint: "BEST PRACTICE for complex tasks:\n- At the beginning of a non-trivial task, create a clear todo list with specific, actionable items.\n- Only **one** item should be `in_progress` at any time.\n- Update the list frequently as work progresses (mark items done, add new ones, change status).\n- The system and user can see this list, so keep it honest and up-to-date.\nThis tool is extremely valuable for maintaining focus and giving the user visibility into your plan.",
|
|
2466
|
+
usageHint: "BEST PRACTICE for complex tasks:\n- At the beginning of a non-trivial task, create a clear todo list with specific, actionable items.\n- Only **one** item should be `in_progress` at any time.\n- Update the list frequently as work progresses (mark items done, add new ones, change status).\n- **Re-order items** to reflect current priorities \u2014 the full list is replaced each call, so item order is entirely under your control.\n- When all items are completed the board auto-clears \u2014 you do NOT need to send an empty list.\n- The system and user can see this list, so keep it honest and up-to-date.\nThis tool is extremely valuable for maintaining focus and giving the user visibility into your plan.",
|
|
2467
2467
|
permission: "auto",
|
|
2468
2468
|
mutating: false,
|
|
2469
|
+
// mutates only conversation state (ctx.todos), not external state — no confirmation needed
|
|
2469
2470
|
timeoutMs: 1e3,
|
|
2470
2471
|
inputSchema: {
|
|
2471
2472
|
type: "object",
|
|
@@ -3112,8 +3113,8 @@ var jsonTool = {
|
|
|
3112
3113
|
};
|
|
3113
3114
|
}
|
|
3114
3115
|
};
|
|
3115
|
-
function query(data,
|
|
3116
|
-
const parts =
|
|
3116
|
+
function query(data, path19) {
|
|
3117
|
+
const parts = path19.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
|
|
3117
3118
|
let current = data;
|
|
3118
3119
|
for (const part of parts) {
|
|
3119
3120
|
if (current === null || current === void 0) return void 0;
|
|
@@ -4404,7 +4405,7 @@ async function dockerLogs(service, lines, filterRe, cwd, signal, since) {
|
|
|
4404
4405
|
}
|
|
4405
4406
|
var DOCKER_LOGS_TIMEOUT_MS = 3e3;
|
|
4406
4407
|
var MAX_TAIL_LINES = 1e5;
|
|
4407
|
-
async function fileLogs(
|
|
4408
|
+
async function fileLogs(path19, lines, filterRe, stream) {
|
|
4408
4409
|
const { createInterface } = await import('node:readline');
|
|
4409
4410
|
const { createReadStream } = await import('node:fs');
|
|
4410
4411
|
const entries = [];
|
|
@@ -4413,7 +4414,7 @@ async function fileLogs(path18, lines, filterRe, stream) {
|
|
|
4413
4414
|
let writeIdx = 0;
|
|
4414
4415
|
let totalLines = 0;
|
|
4415
4416
|
const rl = createInterface({
|
|
4416
|
-
input: createReadStream(
|
|
4417
|
+
input: createReadStream(path19),
|
|
4417
4418
|
crlfDelay: Number.POSITIVE_INFINITY
|
|
4418
4419
|
});
|
|
4419
4420
|
for await (const line of rl) {
|
|
@@ -4434,7 +4435,7 @@ async function fileLogs(path18, lines, filterRe, stream) {
|
|
|
4434
4435
|
if (parsed) entries.push(parsed);
|
|
4435
4436
|
}
|
|
4436
4437
|
return {
|
|
4437
|
-
source:
|
|
4438
|
+
source: path19,
|
|
4438
4439
|
entries,
|
|
4439
4440
|
total: entries.length,
|
|
4440
4441
|
truncated: totalLines > effLines,
|
|
@@ -4874,10 +4875,14 @@ var toolSearchTool = {
|
|
|
4874
4875
|
permission: t.permission,
|
|
4875
4876
|
mutating: t.mutating
|
|
4876
4877
|
}));
|
|
4878
|
+
const totalAvailable = tools.length;
|
|
4879
|
+
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
4880
|
return {
|
|
4878
4881
|
tools: results,
|
|
4879
4882
|
total: filtered.length,
|
|
4880
|
-
truncated: filtered.length > limit
|
|
4883
|
+
truncated: filtered.length > limit,
|
|
4884
|
+
...hint ? { hint } : {},
|
|
4885
|
+
_available: totalAvailable
|
|
4881
4886
|
};
|
|
4882
4887
|
}
|
|
4883
4888
|
};
|
|
@@ -5565,6 +5570,17 @@ var IndexStore = class {
|
|
|
5565
5570
|
({ id, text }) => ({ id, text })
|
|
5566
5571
|
);
|
|
5567
5572
|
}
|
|
5573
|
+
/**
|
|
5574
|
+
* Largest symbol id currently in the table (0 when empty). New ids must be
|
|
5575
|
+
* allocated from this, NOT from `COUNT(*)`: incremental reindexes delete a
|
|
5576
|
+
* changed file's rows, so the row count drops below the max id and a
|
|
5577
|
+
* count-based id would collide with a surviving row (UNIQUE constraint on
|
|
5578
|
+
* `symbols.id`). Ids may have gaps — that is fine.
|
|
5579
|
+
*/
|
|
5580
|
+
getMaxSymbolId() {
|
|
5581
|
+
const rows = this.db.prepare("SELECT MAX(id) AS m FROM symbols").all();
|
|
5582
|
+
return rows[0]?.m ?? 0;
|
|
5583
|
+
}
|
|
5568
5584
|
// ─── Stats ───────────────────────────────────────────────────────────────────
|
|
5569
5585
|
getStats() {
|
|
5570
5586
|
const sizeBytes = this.sizeBytes();
|
|
@@ -6883,8 +6899,181 @@ function makeSymbol2(opts) {
|
|
|
6883
6899
|
text: `${opts.name} ${opts.signature}`.trim()
|
|
6884
6900
|
};
|
|
6885
6901
|
}
|
|
6902
|
+
function globBody(glob) {
|
|
6903
|
+
return compileGlob(glob).source.replace(/^\^/, "").replace(/\$$/, "");
|
|
6904
|
+
}
|
|
6905
|
+
function compileGitignore(lines) {
|
|
6906
|
+
const rules = [];
|
|
6907
|
+
for (const raw of lines) {
|
|
6908
|
+
let line = raw.replace(/\r$/, "");
|
|
6909
|
+
if (!line.trim() || line.trimStart().startsWith("#")) continue;
|
|
6910
|
+
line = line.trim();
|
|
6911
|
+
let negated = false;
|
|
6912
|
+
if (line.startsWith("!")) {
|
|
6913
|
+
negated = true;
|
|
6914
|
+
line = line.slice(1);
|
|
6915
|
+
}
|
|
6916
|
+
let dirOnly = false;
|
|
6917
|
+
if (line.endsWith("/")) {
|
|
6918
|
+
dirOnly = true;
|
|
6919
|
+
line = line.slice(0, -1);
|
|
6920
|
+
}
|
|
6921
|
+
if (!line) continue;
|
|
6922
|
+
const anchored = line.startsWith("/") || line.includes("/");
|
|
6923
|
+
if (line.startsWith("/")) line = line.slice(1);
|
|
6924
|
+
const body = globBody(line);
|
|
6925
|
+
const prefix = anchored ? "^" : "(?:^|.*/)";
|
|
6926
|
+
rules.push({
|
|
6927
|
+
eqOrUnder: new RegExp(`${prefix}${body}(?:/.*)?$`),
|
|
6928
|
+
under: new RegExp(`${prefix}${body}/.*$`),
|
|
6929
|
+
negated,
|
|
6930
|
+
dirOnly
|
|
6931
|
+
});
|
|
6932
|
+
}
|
|
6933
|
+
return (relPath, isDir) => {
|
|
6934
|
+
const p = relPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
6935
|
+
let ignored = false;
|
|
6936
|
+
for (const r of rules) {
|
|
6937
|
+
const re = r.dirOnly && !isDir ? r.under : r.eqOrUnder;
|
|
6938
|
+
if (re.test(p)) ignored = !r.negated;
|
|
6939
|
+
}
|
|
6940
|
+
return ignored;
|
|
6941
|
+
};
|
|
6942
|
+
}
|
|
6943
|
+
async function loadGitignoreMatcher(projectRoot) {
|
|
6944
|
+
let lines = [];
|
|
6945
|
+
try {
|
|
6946
|
+
const raw = await fs4.readFile(path.join(projectRoot, ".gitignore"), "utf8");
|
|
6947
|
+
lines = raw.split("\n");
|
|
6948
|
+
} catch {
|
|
6949
|
+
}
|
|
6950
|
+
return compileGitignore(lines);
|
|
6951
|
+
}
|
|
6952
|
+
|
|
6953
|
+
// src/codebase-index/background-indexer.ts
|
|
6954
|
+
var _ready = false;
|
|
6955
|
+
var _indexing = false;
|
|
6956
|
+
var _currentFile = 0;
|
|
6957
|
+
var _totalFiles = 0;
|
|
6958
|
+
var _lastError = null;
|
|
6959
|
+
function isIndexReady() {
|
|
6960
|
+
return _ready;
|
|
6961
|
+
}
|
|
6962
|
+
function setIndexReady() {
|
|
6963
|
+
_ready = true;
|
|
6964
|
+
}
|
|
6965
|
+
function isIndexing() {
|
|
6966
|
+
return _indexing;
|
|
6967
|
+
}
|
|
6968
|
+
function getIndexState() {
|
|
6969
|
+
return {
|
|
6970
|
+
ready: _ready,
|
|
6971
|
+
indexing: _indexing,
|
|
6972
|
+
currentFile: _currentFile,
|
|
6973
|
+
totalFiles: _totalFiles,
|
|
6974
|
+
lastError: _lastError
|
|
6975
|
+
};
|
|
6976
|
+
}
|
|
6977
|
+
var _listeners = [];
|
|
6978
|
+
function onIndexStateChange(listener) {
|
|
6979
|
+
_listeners.push(listener);
|
|
6980
|
+
return () => {
|
|
6981
|
+
_listeners = _listeners.filter((l) => l !== listener);
|
|
6982
|
+
};
|
|
6983
|
+
}
|
|
6984
|
+
function emitState() {
|
|
6985
|
+
const state = getIndexState();
|
|
6986
|
+
for (const l of _listeners) l(state);
|
|
6987
|
+
}
|
|
6988
|
+
function _setIndexProgress(current, total) {
|
|
6989
|
+
_currentFile = current;
|
|
6990
|
+
_totalFiles = total;
|
|
6991
|
+
emitState();
|
|
6992
|
+
}
|
|
6993
|
+
function stubCtx(projectRoot) {
|
|
6994
|
+
return {
|
|
6995
|
+
projectRoot,
|
|
6996
|
+
cwd: projectRoot,
|
|
6997
|
+
messages: [],
|
|
6998
|
+
todos: [],
|
|
6999
|
+
readFiles: /* @__PURE__ */ new Set(),
|
|
7000
|
+
fileMtimes: /* @__PURE__ */ new Map()
|
|
7001
|
+
};
|
|
7002
|
+
}
|
|
7003
|
+
var chain = Promise.resolve();
|
|
7004
|
+
function withMutex(job) {
|
|
7005
|
+
const run = chain.then(job, job);
|
|
7006
|
+
chain = run.then(
|
|
7007
|
+
() => void 0,
|
|
7008
|
+
() => void 0
|
|
7009
|
+
);
|
|
7010
|
+
return run;
|
|
7011
|
+
}
|
|
7012
|
+
var DEFAULT_DEBOUNCE_MS = 400;
|
|
7013
|
+
var debounceTimers = /* @__PURE__ */ new Map();
|
|
7014
|
+
function debounceKey(indexDir, file) {
|
|
7015
|
+
return `${indexDir ?? ""}|${file}`;
|
|
7016
|
+
}
|
|
7017
|
+
function isIndexableFile(filePath) {
|
|
7018
|
+
return detectLang(filePath) !== null;
|
|
7019
|
+
}
|
|
7020
|
+
async function runStartupIndex(opts) {
|
|
7021
|
+
_indexing = true;
|
|
7022
|
+
_currentFile = 0;
|
|
7023
|
+
_totalFiles = 0;
|
|
7024
|
+
_lastError = null;
|
|
7025
|
+
emitState();
|
|
7026
|
+
try {
|
|
7027
|
+
const result = await withMutex(
|
|
7028
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7029
|
+
projectRoot: opts.projectRoot,
|
|
7030
|
+
indexDir: opts.indexDir,
|
|
7031
|
+
force: opts.force
|
|
7032
|
+
})
|
|
7033
|
+
);
|
|
7034
|
+
_ready = true;
|
|
7035
|
+
return result;
|
|
7036
|
+
} catch (err) {
|
|
7037
|
+
_lastError = err instanceof Error ? err.message : String(err);
|
|
7038
|
+
_ready = true;
|
|
7039
|
+
throw err;
|
|
7040
|
+
} finally {
|
|
7041
|
+
_indexing = false;
|
|
7042
|
+
emitState();
|
|
7043
|
+
}
|
|
7044
|
+
}
|
|
7045
|
+
function enqueueReindex(opts) {
|
|
7046
|
+
const files = opts.files.filter(isIndexableFile);
|
|
7047
|
+
if (files.length === 0) return;
|
|
7048
|
+
const ms = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
7049
|
+
for (const file of files) {
|
|
7050
|
+
const key = debounceKey(opts.indexDir, file);
|
|
7051
|
+
const existing = debounceTimers.get(key);
|
|
7052
|
+
if (existing) clearTimeout(existing);
|
|
7053
|
+
const timer = setTimeout(() => {
|
|
7054
|
+
debounceTimers.delete(key);
|
|
7055
|
+
void withMutex(
|
|
7056
|
+
() => runIndexer(stubCtx(opts.projectRoot), {
|
|
7057
|
+
projectRoot: opts.projectRoot,
|
|
7058
|
+
files: [file],
|
|
7059
|
+
indexDir: opts.indexDir
|
|
7060
|
+
})
|
|
7061
|
+
).catch((err) => opts.onError?.(err));
|
|
7062
|
+
}, ms);
|
|
7063
|
+
timer.unref?.();
|
|
7064
|
+
debounceTimers.set(key, timer);
|
|
7065
|
+
}
|
|
7066
|
+
}
|
|
7067
|
+
function cancelPendingReindexes() {
|
|
7068
|
+
for (const t of debounceTimers.values()) clearTimeout(t);
|
|
7069
|
+
debounceTimers.clear();
|
|
7070
|
+
}
|
|
6886
7071
|
|
|
6887
7072
|
// src/codebase-index/indexer.ts
|
|
7073
|
+
var YIELD_EVERY_N = 50;
|
|
7074
|
+
function yieldEventLoop() {
|
|
7075
|
+
return new Promise((resolve7) => setImmediate(resolve7));
|
|
7076
|
+
}
|
|
6888
7077
|
var DEFAULT_IGNORE5 = [
|
|
6889
7078
|
"node_modules",
|
|
6890
7079
|
".git",
|
|
@@ -6896,7 +7085,7 @@ var DEFAULT_IGNORE5 = [
|
|
|
6896
7085
|
"__snapshots__",
|
|
6897
7086
|
".nyc_output"
|
|
6898
7087
|
];
|
|
6899
|
-
async function findSourceFiles(projectRoot, ignore) {
|
|
7088
|
+
async function findSourceFiles(projectRoot, ignore, isGitIgnored) {
|
|
6900
7089
|
const results = [];
|
|
6901
7090
|
const ignoreSet = /* @__PURE__ */ new Set([...DEFAULT_IGNORE5, ...ignore]);
|
|
6902
7091
|
const globs = [
|
|
@@ -6921,10 +7110,12 @@ async function findSourceFiles(projectRoot, ignore) {
|
|
|
6921
7110
|
for (const e of entries) {
|
|
6922
7111
|
if (ignoreSet.has(e.name)) continue;
|
|
6923
7112
|
const full = path.join(dir, e.name);
|
|
7113
|
+
const rel = path.relative(projectRoot, full).replace(/\\/g, "/");
|
|
6924
7114
|
if (e.isDirectory()) {
|
|
7115
|
+
if (isGitIgnored(rel, true)) continue;
|
|
6925
7116
|
await walk(full);
|
|
6926
7117
|
} else if (e.isFile()) {
|
|
6927
|
-
|
|
7118
|
+
if (isGitIgnored(rel, false)) continue;
|
|
6928
7119
|
const ext = path.extname(e.name);
|
|
6929
7120
|
for (const { ext: extName, pat } of globs) {
|
|
6930
7121
|
if (ext === extName && (pat.test(rel) || pat.test(e.name))) {
|
|
@@ -6967,11 +7158,12 @@ async function runIndexer(_ctx, opts) {
|
|
|
6967
7158
|
const langStats = {};
|
|
6968
7159
|
let filesIndexed = 0;
|
|
6969
7160
|
let symbolsIndexed = 0;
|
|
7161
|
+
const isGitIgnored = await loadGitignoreMatcher(projectRoot);
|
|
6970
7162
|
let files;
|
|
6971
7163
|
if (opts.files && opts.files.length > 0) {
|
|
6972
|
-
files = opts.files.map((f) => path.resolve(projectRoot, f));
|
|
7164
|
+
files = opts.files.map((f) => path.resolve(projectRoot, f)).filter((f) => !isGitIgnored(path.relative(projectRoot, f).replace(/\\/g, "/"), false));
|
|
6973
7165
|
} else {
|
|
6974
|
-
files = await findSourceFiles(projectRoot, ignore);
|
|
7166
|
+
files = await findSourceFiles(projectRoot, ignore, isGitIgnored);
|
|
6975
7167
|
}
|
|
6976
7168
|
if (langs && langs.length > 0) {
|
|
6977
7169
|
const langSet = new Set(langs);
|
|
@@ -6985,7 +7177,12 @@ async function runIndexer(_ctx, opts) {
|
|
|
6985
7177
|
if (!force) {
|
|
6986
7178
|
for (const meta of store.getAllFileMetas()) existingMeta.set(meta.file, meta);
|
|
6987
7179
|
}
|
|
6988
|
-
for (
|
|
7180
|
+
for (let fi = 0; fi < files.length; fi++) {
|
|
7181
|
+
const file = files[fi];
|
|
7182
|
+
_setIndexProgress(fi + 1, files.length);
|
|
7183
|
+
if (fi > 0 && fi % YIELD_EVERY_N === 0) {
|
|
7184
|
+
await yieldEventLoop();
|
|
7185
|
+
}
|
|
6989
7186
|
let stat10;
|
|
6990
7187
|
try {
|
|
6991
7188
|
stat10 = await fs4.stat(file);
|
|
@@ -7003,8 +7200,8 @@ async function runIndexer(_ctx, opts) {
|
|
|
7003
7200
|
filesIndexed++;
|
|
7004
7201
|
continue;
|
|
7005
7202
|
}
|
|
7006
|
-
store.deleteSymbolsForFile(file);
|
|
7007
7203
|
store.deleteRefsForFile(file);
|
|
7204
|
+
store.deleteSymbolsForFile(file);
|
|
7008
7205
|
let content;
|
|
7009
7206
|
try {
|
|
7010
7207
|
content = await fs4.readFile(file, "utf8");
|
|
@@ -7030,7 +7227,7 @@ async function runIndexer(_ctx, opts) {
|
|
|
7030
7227
|
filesIndexed++;
|
|
7031
7228
|
continue;
|
|
7032
7229
|
}
|
|
7033
|
-
const nextId = store.
|
|
7230
|
+
const nextId = store.getMaxSymbolId() + 1;
|
|
7034
7231
|
const symbolsWithIds = parsed.symbols.map((s, i) => ({ ...s, id: nextId + i }));
|
|
7035
7232
|
store.insertSymbols(symbolsWithIds, nextId);
|
|
7036
7233
|
const count = symbolsWithIds.length;
|
|
@@ -7099,12 +7296,23 @@ var codebaseIndexTool = {
|
|
|
7099
7296
|
}
|
|
7100
7297
|
},
|
|
7101
7298
|
async execute(input, ctx) {
|
|
7299
|
+
if (isIndexing()) {
|
|
7300
|
+
return {
|
|
7301
|
+
filesIndexed: 0,
|
|
7302
|
+
symbolsIndexed: 0,
|
|
7303
|
+
langStats: {},
|
|
7304
|
+
durationMs: 0,
|
|
7305
|
+
errors: [],
|
|
7306
|
+
note: "A full index is already in progress. Retry codebase-index after it completes (check codebase-stats)."
|
|
7307
|
+
};
|
|
7308
|
+
}
|
|
7102
7309
|
const result = await runIndexer(ctx, {
|
|
7103
7310
|
projectRoot: ctx.projectRoot,
|
|
7104
7311
|
force: input.force ?? false,
|
|
7105
7312
|
langs: input.langs,
|
|
7106
7313
|
indexDir: codebaseIndexDirOverride(ctx)
|
|
7107
7314
|
});
|
|
7315
|
+
setIndexReady();
|
|
7108
7316
|
return result;
|
|
7109
7317
|
}
|
|
7110
7318
|
};
|
|
@@ -7240,6 +7448,31 @@ var codebaseSearchTool = {
|
|
|
7240
7448
|
required: ["query"]
|
|
7241
7449
|
},
|
|
7242
7450
|
async execute(input, ctx) {
|
|
7451
|
+
const state = getIndexState();
|
|
7452
|
+
if (!state.ready) {
|
|
7453
|
+
return {
|
|
7454
|
+
results: [],
|
|
7455
|
+
total: 0,
|
|
7456
|
+
query: input.query,
|
|
7457
|
+
indexStatus: state.indexing ? `Indexing in progress (${state.currentFile}/${state.totalFiles} files) \u2014 retry in a moment.` : "Index not yet built. The codebase is being indexed at startup \u2014 search will be available shortly."
|
|
7458
|
+
};
|
|
7459
|
+
}
|
|
7460
|
+
if (state.indexing) {
|
|
7461
|
+
return {
|
|
7462
|
+
results: [],
|
|
7463
|
+
total: 0,
|
|
7464
|
+
query: input.query,
|
|
7465
|
+
indexStatus: `Index refresh in progress (${state.currentFile}/${state.totalFiles} files). Results may be incomplete.`
|
|
7466
|
+
};
|
|
7467
|
+
}
|
|
7468
|
+
if (state.lastError) {
|
|
7469
|
+
return {
|
|
7470
|
+
results: [],
|
|
7471
|
+
total: 0,
|
|
7472
|
+
query: input.query,
|
|
7473
|
+
indexStatus: `Index build failed: ${state.lastError}. Try /codebase-reindex.`
|
|
7474
|
+
};
|
|
7475
|
+
}
|
|
7243
7476
|
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7244
7477
|
try {
|
|
7245
7478
|
const limit = Math.min(input.limit ?? 20, 100);
|
|
@@ -7297,6 +7530,32 @@ var codebaseStatsTool = {
|
|
|
7297
7530
|
additionalProperties: false
|
|
7298
7531
|
},
|
|
7299
7532
|
async execute(_input, ctx) {
|
|
7533
|
+
const idxState = getIndexState();
|
|
7534
|
+
if (!idxState.ready) {
|
|
7535
|
+
return {
|
|
7536
|
+
totalSymbols: 0,
|
|
7537
|
+
totalFiles: 0,
|
|
7538
|
+
byLang: {},
|
|
7539
|
+
byKind: {},
|
|
7540
|
+
lastIndexed: null,
|
|
7541
|
+
sizeBytes: 0,
|
|
7542
|
+
indexPath: "",
|
|
7543
|
+
version: SCHEMA_VERSION,
|
|
7544
|
+
indexStatus: idxState.indexing ? `Indexing in progress (${idxState.currentFile}/${idxState.totalFiles} files).` : "Index not yet built."
|
|
7545
|
+
};
|
|
7546
|
+
}
|
|
7547
|
+
if (idxState.indexing) {
|
|
7548
|
+
const store2 = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7549
|
+
try {
|
|
7550
|
+
const stats = store2.getStats();
|
|
7551
|
+
return {
|
|
7552
|
+
...stats,
|
|
7553
|
+
indexStatus: `Index refresh in progress (${idxState.currentFile}/${idxState.totalFiles} files). Stats may be incomplete.`
|
|
7554
|
+
};
|
|
7555
|
+
} finally {
|
|
7556
|
+
store2.close();
|
|
7557
|
+
}
|
|
7558
|
+
}
|
|
7300
7559
|
const store = new IndexStore(ctx.projectRoot, { indexDir: codebaseIndexDirOverride(ctx) });
|
|
7301
7560
|
try {
|
|
7302
7561
|
const stats = store.getStats();
|
|
@@ -7361,6 +7620,6 @@ var builtinToolsPack = {
|
|
|
7361
7620
|
tools: builtinTools
|
|
7362
7621
|
};
|
|
7363
7622
|
|
|
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 };
|
|
7623
|
+
export { CircuitBreaker, _resetProcessRegistry, auditTool, bashTool, batchToolUseTool, builtinTools, builtinToolsPack, cancelPendingReindexes, codebaseIndexTool, codebaseSearchTool, codebaseStatsTool, createModeTool, diffTool, documentTool, editTool, enqueueReindex, execTool, fetchTool, forgetTool, formatTool, getIndexState, getProcessRegistry, gitTool, globTool, grepTool, installTool, isIndexReady, isIndexableFile, isIndexing, jsonTool, lintTool, logsTool, onIndexStateChange, outdatedTool, patchTool, planTool, readTool, rememberTool, replaceTool, runStartupIndex, scaffoldTool, searchTool, testTool, todoTool, toolHelpTool, toolSearchTool, toolUseTool, treeTool, typecheckTool, writeTool };
|
|
7365
7624
|
//# sourceMappingURL=index.js.map
|
|
7366
7625
|
//# sourceMappingURL=index.js.map
|