token-goat 2.6.26 → 2.6.27
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 +9 -9
- package/dist/token-goat-hook.mjs +253 -54
- package/dist/token-goat.mjs +269 -59
- package/package.json +3 -3
package/dist/token-goat-hook.mjs
CHANGED
|
@@ -49,7 +49,7 @@ var init_define_import_meta_env = __esm({
|
|
|
49
49
|
import { createRequire } from "node:module";
|
|
50
50
|
function resolveVersion() {
|
|
51
51
|
if (true) {
|
|
52
|
-
return "2.6.
|
|
52
|
+
return "2.6.27";
|
|
53
53
|
}
|
|
54
54
|
const require2 = createRequire(import.meta.url);
|
|
55
55
|
const pkg = require2("../package.json");
|
|
@@ -1901,6 +1901,12 @@ function grepFilteredToEmptyNotice(preFilterCount, grep, nounSingular, nounPlura
|
|
|
1901
1901
|
const verb = preFilterCount === 1 ? "was" : "were";
|
|
1902
1902
|
return ` (all ${preFilterCount} ${noun} ${verb} filtered out by --grep ${grep} -- widen or drop the filter to see them)`;
|
|
1903
1903
|
}
|
|
1904
|
+
function countNoun(count, singular, plural2 = `${singular}s`) {
|
|
1905
|
+
return `${count} ${count === 1 ? singular : plural2}`;
|
|
1906
|
+
}
|
|
1907
|
+
function excludeTestsHiddenNote(count) {
|
|
1908
|
+
return `${count} in test ${count === 1 ? "file" : "files"} hidden by --exclude-tests`;
|
|
1909
|
+
}
|
|
1904
1910
|
function escapeRegExp(s) {
|
|
1905
1911
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1906
1912
|
}
|
|
@@ -3406,6 +3412,8 @@ function writeGuidance(filePath) {
|
|
|
3406
3412
|
BEGIN,
|
|
3407
3413
|
buildGuidanceBody("VS Code\u2019s supported MCP integration and its built-in file-read tools"),
|
|
3408
3414
|
"",
|
|
3415
|
+
"**Compressed payloads:** a message containing a token-goat payload block (recognizable by a `recovery: token-goat retrieve <id>` line) is compressed text, not an answer. Call the MCP tool `retrieve_text` with that id to recover the original text, then answer the question the message asks using the recovered text. Never present the raw payload to the user as the response; if the `retrieve_text` tool is unavailable (the MCP server is not running, or the chat is not in Agent mode), say so plainly and ask the user to switch to Agent mode or run `token-goat install --vscode`.",
|
|
3416
|
+
"",
|
|
3409
3417
|
"VS Code support: token-goat install --vscode configures a project-local stdio MCP server in .vscode/mcp.json under the servers root key. VS Code may call these MCP tools when selected; MCP does not intercept VS Code\u2019s built-in file reads.",
|
|
3410
3418
|
END
|
|
3411
3419
|
].join("\n");
|
|
@@ -20834,6 +20842,22 @@ function dirtyQueuePathFor(dir) {
|
|
|
20834
20842
|
function drainHeartbeatPathFor(dir) {
|
|
20835
20843
|
return path30.join(dir, "queue", "drain-heartbeat");
|
|
20836
20844
|
}
|
|
20845
|
+
function hasFreshWorkerHeartbeat(dir, pid) {
|
|
20846
|
+
try {
|
|
20847
|
+
const heartbeatPath = drainHeartbeatPathFor(dir);
|
|
20848
|
+
if (Date.now() - fs26.statSync(heartbeatPath).mtimeMs > WORKER_HEARTBEAT_STALE_MS) return false;
|
|
20849
|
+
return fs26.readFileSync(heartbeatPath, "utf8").trim() === String(pid);
|
|
20850
|
+
} catch {
|
|
20851
|
+
return false;
|
|
20852
|
+
}
|
|
20853
|
+
}
|
|
20854
|
+
function pidFileIsWithinStartupGrace(dir) {
|
|
20855
|
+
try {
|
|
20856
|
+
return Date.now() - fs26.statSync(workerPidPath(dir)).mtimeMs < WORKER_STARTUP_GRACE_MS;
|
|
20857
|
+
} catch {
|
|
20858
|
+
return false;
|
|
20859
|
+
}
|
|
20860
|
+
}
|
|
20837
20861
|
function parseDirtyQueueLines(raw) {
|
|
20838
20862
|
const seen = /* @__PURE__ */ new Set();
|
|
20839
20863
|
const out2 = [];
|
|
@@ -20889,7 +20913,7 @@ function readPidFile(dir) {
|
|
|
20889
20913
|
function isWorkerRunning(dir = dataDir()) {
|
|
20890
20914
|
const pid = readPidFile(dir);
|
|
20891
20915
|
if (pid === null) return false;
|
|
20892
|
-
return pidAlive(pid);
|
|
20916
|
+
return pidAlive(pid) && hasFreshWorkerHeartbeat(dir, pid);
|
|
20893
20917
|
}
|
|
20894
20918
|
function workerHealthCheckMarkerPath(dir) {
|
|
20895
20919
|
return path30.join(dir, "worker-healthcheck.marker");
|
|
@@ -20925,8 +20949,8 @@ function ensureWorkerAlive(dir = dataDir()) {
|
|
|
20925
20949
|
function stopWorker(dir = dataDir()) {
|
|
20926
20950
|
const pid = readPidFile(dir);
|
|
20927
20951
|
if (pid === null) return false;
|
|
20928
|
-
const
|
|
20929
|
-
if (
|
|
20952
|
+
const running = isWorkerRunning(dir);
|
|
20953
|
+
if (running) {
|
|
20930
20954
|
try {
|
|
20931
20955
|
process.kill(pid);
|
|
20932
20956
|
} catch {
|
|
@@ -20938,7 +20962,7 @@ function stopWorker(dir = dataDir()) {
|
|
|
20938
20962
|
} catch {
|
|
20939
20963
|
}
|
|
20940
20964
|
}
|
|
20941
|
-
return
|
|
20965
|
+
return running;
|
|
20942
20966
|
}
|
|
20943
20967
|
function claimWorkerPidFile(dir, pid) {
|
|
20944
20968
|
const pidPath = workerPidPath(dir);
|
|
@@ -20950,7 +20974,7 @@ function claimWorkerPidFile(dir, pid) {
|
|
|
20950
20974
|
if (e.code !== "EEXIST") throw e;
|
|
20951
20975
|
}
|
|
20952
20976
|
const existingPid = readPidFile(dir);
|
|
20953
|
-
if (existingPid !== null && pidAlive(existingPid)) {
|
|
20977
|
+
if (existingPid !== null && pidAlive(existingPid) && (hasFreshWorkerHeartbeat(dir, existingPid) || pidFileIsWithinStartupGrace(dir))) {
|
|
20954
20978
|
return false;
|
|
20955
20979
|
}
|
|
20956
20980
|
try {
|
|
@@ -21003,7 +21027,7 @@ function startDetachedWorker(opts) {
|
|
|
21003
21027
|
child.unref();
|
|
21004
21028
|
return pid;
|
|
21005
21029
|
}
|
|
21006
|
-
var DEFAULT_POLL_INTERVAL_MS, SNAPSHOT_CLEANUP_INTERVAL_MS, WORKER_ERROR_LOG_MAX_BYTES, CORRUPT_QUARANTINE_MAX_AGE_MS, INDEX_FAILED, activeEmbedSlots, embedSlotWaiters, WORKER_HEALTHCHECK_MIN_INTERVAL_MS, WorkerAlreadyRunningError, KNOWN_ROOTS_SWEEP_INTERVAL_MS;
|
|
21030
|
+
var DEFAULT_POLL_INTERVAL_MS, WORKER_HEARTBEAT_STALE_MS, WORKER_STARTUP_GRACE_MS, SNAPSHOT_CLEANUP_INTERVAL_MS, WORKER_ERROR_LOG_MAX_BYTES, CORRUPT_QUARANTINE_MAX_AGE_MS, INDEX_FAILED, activeEmbedSlots, embedSlotWaiters, WORKER_HEALTHCHECK_MIN_INTERVAL_MS, WorkerAlreadyRunningError, KNOWN_ROOTS_SWEEP_INTERVAL_MS;
|
|
21007
21031
|
var init_worker = __esm({
|
|
21008
21032
|
"src/worker.ts"() {
|
|
21009
21033
|
"use strict";
|
|
@@ -21023,6 +21047,8 @@ var init_worker = __esm({
|
|
|
21023
21047
|
init_project();
|
|
21024
21048
|
init_reset();
|
|
21025
21049
|
DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
21050
|
+
WORKER_HEARTBEAT_STALE_MS = 6e4;
|
|
21051
|
+
WORKER_STARTUP_GRACE_MS = 1e4;
|
|
21026
21052
|
SNAPSHOT_CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
|
|
21027
21053
|
WORKER_ERROR_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
21028
21054
|
CORRUPT_QUARANTINE_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
@@ -28434,6 +28460,12 @@ function didYouMean(candidates) {
|
|
|
28434
28460
|
}
|
|
28435
28461
|
return lines2.join("\n");
|
|
28436
28462
|
}
|
|
28463
|
+
function unknownSymbolSuggestion(name2, rootDir) {
|
|
28464
|
+
const rawSymbols = querySymbols({ limit: FIND_SCAN_LIMIT, rootDir });
|
|
28465
|
+
const candidates = rankSimilarNames(rawSymbols.map((s) => s.name), name2);
|
|
28466
|
+
return candidates.length > 0 ? `
|
|
28467
|
+
${didYouMean(candidates)}` : "";
|
|
28468
|
+
}
|
|
28437
28469
|
function formatBareNameSpecError(command, name2, projectRoot) {
|
|
28438
28470
|
const rootDir = projectRoot ?? resolveProjectRoot({ project: process.cwd() });
|
|
28439
28471
|
const matches2 = querySymbols({ name: name2, limit: 50, rootDir });
|
|
@@ -28507,6 +28539,17 @@ function runSymbol(opts) {
|
|
|
28507
28539
|
if (opts.limit !== void 0 && opts.limit <= 0) {
|
|
28508
28540
|
return { text: `--limit must be a positive number, got: ${opts.limit}`, code: 1 };
|
|
28509
28541
|
}
|
|
28542
|
+
if (opts.name !== void 0 && opts.grep !== void 0) {
|
|
28543
|
+
return {
|
|
28544
|
+
text: "symbol: --grep cannot be combined with a name; drop the name to search by pattern, or drop --grep to search by exact name",
|
|
28545
|
+
code: 1
|
|
28546
|
+
};
|
|
28547
|
+
}
|
|
28548
|
+
if (opts.name === void 0 && opts.grep === void 0) {
|
|
28549
|
+
return { text: "symbol requires a name or --grep <pattern>", code: 1 };
|
|
28550
|
+
}
|
|
28551
|
+
const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
|
|
28552
|
+
const excludeTests = opts.excludeTests === true;
|
|
28510
28553
|
const queryOpts = {};
|
|
28511
28554
|
if (opts.name !== void 0) queryOpts.name = opts.name;
|
|
28512
28555
|
if (opts.file !== void 0) {
|
|
@@ -28514,11 +28557,36 @@ function runSymbol(opts) {
|
|
|
28514
28557
|
healStaleIndex(queryOpts.filePath);
|
|
28515
28558
|
}
|
|
28516
28559
|
if (opts.kind !== void 0) queryOpts.kind = opts.kind;
|
|
28517
|
-
if (
|
|
28560
|
+
if (matchesGrep !== void 0 || excludeTests) {
|
|
28561
|
+
queryOpts.limit = FIND_SCAN_LIMIT;
|
|
28562
|
+
} else if (opts.limit !== void 0) {
|
|
28563
|
+
queryOpts.limit = opts.limit;
|
|
28564
|
+
}
|
|
28518
28565
|
if (opts.file === void 0 && opts.projectRoot !== void 0) queryOpts.rootDir = opts.projectRoot;
|
|
28519
|
-
const
|
|
28566
|
+
const rawResults = querySymbols(queryOpts);
|
|
28567
|
+
const preFilterCount = rawResults.length;
|
|
28568
|
+
const effectiveLimit = opts.limit ?? 100;
|
|
28569
|
+
const anyClientFilter = matchesGrep !== void 0 || excludeTests;
|
|
28570
|
+
const filtered = anyClientFilter ? rawResults.filter((s) => (matchesGrep === void 0 || matchesGrep(s.name)) && !(excludeTests && isTestFile(s.filePath))) : rawResults;
|
|
28571
|
+
const results = anyClientFilter ? filtered.slice(0, effectiveLimit) : filtered;
|
|
28572
|
+
const hiddenByExcludeTests = excludeTests ? rawResults.filter((s) => (matchesGrep === void 0 || matchesGrep(s.name)) && isTestFile(s.filePath)).length : 0;
|
|
28573
|
+
if (excludeTests && filtered.length === 0 && hiddenByExcludeTests > 0) {
|
|
28574
|
+
const label = opts.name ?? opts.grep ?? "*";
|
|
28575
|
+
const notice = `no non-test matches for '${label}' (${excludeTestsHiddenNote(hiddenByExcludeTests)})`;
|
|
28576
|
+
if (opts.json === true) {
|
|
28577
|
+
return { text: JSON.stringify({ items: [], truncated: false, totalCount: 0 }, null, 2), code: 0 };
|
|
28578
|
+
}
|
|
28579
|
+
return { text: `token-goat: ${notice}`, code: 0 };
|
|
28580
|
+
}
|
|
28581
|
+
if (matchesGrep !== void 0 && filtered.length === 0 && preFilterCount > 0) {
|
|
28582
|
+
if (opts.json === true) {
|
|
28583
|
+
const text2 = JSON.stringify({ items: [], truncated: false, totalCount: 0 }, null, 2);
|
|
28584
|
+
return { text: text2, code: 0 };
|
|
28585
|
+
}
|
|
28586
|
+
return { text: grepFilteredToEmptyNotice(preFilterCount, opts.grep ?? "", "symbol", "symbols"), code: 0 };
|
|
28587
|
+
}
|
|
28520
28588
|
if (results.length === 0) {
|
|
28521
|
-
let text2 = `No matches for '${opts.name ?? "*"}'`;
|
|
28589
|
+
let text2 = `No matches for '${opts.name ?? opts.grep ?? "*"}'`;
|
|
28522
28590
|
const emptyIndexRoot = opts.json !== true ? opts.projectRoot ?? resolveProjectRoot({ project: process.cwd() }) : null;
|
|
28523
28591
|
const indexEmpty = emptyIndexRoot !== null && isIndexEmptyForProject(globalDbPath(), emptyIndexRoot);
|
|
28524
28592
|
if (opts.name !== void 0 && emptyIndexRoot !== null) {
|
|
@@ -28539,11 +28607,19 @@ ${emptyIndexMessage(emptyIndexRoot)}`;
|
|
|
28539
28607
|
const symbolDisplayRoot = getDisplayRoot(opts.projectRoot);
|
|
28540
28608
|
if (opts.json === true) {
|
|
28541
28609
|
const capped = guardJsonRows(results);
|
|
28542
|
-
|
|
28610
|
+
let trueTotal;
|
|
28611
|
+
let truncatedFlag;
|
|
28612
|
+
if (anyClientFilter) {
|
|
28613
|
+
trueTotal = filtered.length;
|
|
28614
|
+
truncatedFlag = capped.truncated || results.length < filtered.length;
|
|
28615
|
+
} else {
|
|
28616
|
+
trueTotal = countSymbols(queryOpts);
|
|
28617
|
+
truncatedFlag = capped.truncated || trueTotal > results.length;
|
|
28618
|
+
}
|
|
28543
28619
|
const items = capped.items.map((s) => ({ ...s, filePath: toDisplayPath(symbolDisplayRoot, s.filePath) }));
|
|
28544
|
-
const payload = { items, truncated:
|
|
28620
|
+
const payload = { items, truncated: truncatedFlag, totalCount: trueTotal };
|
|
28545
28621
|
const text2 = JSON.stringify(payload, null, 2);
|
|
28546
|
-
recordReadStat("symbol_lookup", fullSourceBytes, text2, opts.name ?? opts.file);
|
|
28622
|
+
recordReadStat("symbol_lookup", fullSourceBytes, text2, opts.name ?? opts.file ?? opts.grep);
|
|
28547
28623
|
return { text: text2, code: 0 };
|
|
28548
28624
|
}
|
|
28549
28625
|
const blocks = results.map((sym) => {
|
|
@@ -28555,7 +28631,7 @@ ${preview}` : header;
|
|
|
28555
28631
|
});
|
|
28556
28632
|
const warning = opts.file !== void 0 ? staleWarning(resolveIndexPath(opts.file, opts.projectRoot ?? process.cwd())) : "";
|
|
28557
28633
|
const text = guardText(warning + blocks.join("\n\n"), "symbol");
|
|
28558
|
-
recordReadStat("symbol_lookup", fullSourceBytes, text, opts.name ?? opts.file);
|
|
28634
|
+
recordReadStat("symbol_lookup", fullSourceBytes, text, opts.name ?? opts.file ?? opts.grep);
|
|
28559
28635
|
return { text, code: 0 };
|
|
28560
28636
|
}
|
|
28561
28637
|
function parseReadSpec(spec) {
|
|
@@ -28624,7 +28700,7 @@ function runLineRange(range2, opts) {
|
|
|
28624
28700
|
const allLines = text.split(/\r?\n/);
|
|
28625
28701
|
if (allLines.length > 1 && allLines[allLines.length - 1] === "") allLines.pop();
|
|
28626
28702
|
if (start > allLines.length) {
|
|
28627
|
-
return { text: `Line ${start} is past end of file (${allLines.length
|
|
28703
|
+
return { text: `Line ${start} is past end of file (${countNoun(allLines.length, "line")}): ${file2}`, code: 1 };
|
|
28628
28704
|
}
|
|
28629
28705
|
const clampedEnd = Math.min(end, allLines.length);
|
|
28630
28706
|
const slice = allLines.slice(start - 1, clampedEnd);
|
|
@@ -28660,13 +28736,13 @@ function formatAmbiguity(symbol3, file2, candidates, explicitRoot, commandName =
|
|
|
28660
28736
|
const multiFile = new Set(candidates.map((c) => c.filePath)).size > 1;
|
|
28661
28737
|
const displayRoot = getDisplayRoot(explicitRoot);
|
|
28662
28738
|
const lines2 = [
|
|
28663
|
-
`Ambiguous symbol '${symbol3}' in '${file2}': ${candidates.length}
|
|
28739
|
+
`Ambiguous symbol '${symbol3}' in '${file2}': ${countNoun(candidates.length, "definition")} match. Retry with one of the qualified commands below to pick one:`
|
|
28664
28740
|
];
|
|
28665
28741
|
const fileSymCache = /* @__PURE__ */ new Map();
|
|
28666
28742
|
const getFileSyms = (filePath) => {
|
|
28667
28743
|
let fileSyms = fileSymCache.get(filePath);
|
|
28668
28744
|
if (fileSyms === void 0) {
|
|
28669
|
-
fileSyms = querySymbols({ filePath, limit:
|
|
28745
|
+
fileSyms = querySymbols({ filePath, limit: FIND_SCAN_LIMIT });
|
|
28670
28746
|
fileSymCache.set(filePath, fileSyms);
|
|
28671
28747
|
}
|
|
28672
28748
|
return fileSyms;
|
|
@@ -29052,17 +29128,17 @@ function runRefs(opts) {
|
|
|
29052
29128
|
lines2.push(`${sym}: ${grepFilteredToEmptyNotice(preGrepCount, opts.grep ?? "", "reference", "references").trim()}`);
|
|
29053
29129
|
continue;
|
|
29054
29130
|
}
|
|
29055
|
-
lines2.push(opts.excludeTests === true && suppressed > 0 ? `${sym}: (no non-test references found; ${suppressed}
|
|
29131
|
+
lines2.push(opts.excludeTests === true && suppressed > 0 ? `${sym}: (no non-test references found; ${excludeTestsHiddenNote(suppressed)})` : `${sym}: (no references found)`);
|
|
29056
29132
|
continue;
|
|
29057
29133
|
}
|
|
29058
29134
|
lines2.push(`${sym}:`);
|
|
29059
29135
|
if (opts.top !== void 0) {
|
|
29060
29136
|
lines2.push(...renderTopFilesSummary(results, opts.top, suppressed));
|
|
29061
29137
|
} else if (opts.callers === true) {
|
|
29062
|
-
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${results.length}
|
|
29138
|
+
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`);
|
|
29063
29139
|
lines2.push(...renderCallerGroups(results, opts.context ?? 0));
|
|
29064
29140
|
} else {
|
|
29065
|
-
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${results.length}
|
|
29141
|
+
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`);
|
|
29066
29142
|
for (const ref2 of results) lines2.push(...renderRefLines(ref2, opts.context ?? 0));
|
|
29067
29143
|
}
|
|
29068
29144
|
}
|
|
@@ -29123,17 +29199,17 @@ function runRefsCrossFile(pairs, opts) {
|
|
|
29123
29199
|
lines2.push(`${key}: ${grepFilteredToEmptyNotice(preGrepCount, opts.grep ?? "", "reference", "references").trim()}`);
|
|
29124
29200
|
continue;
|
|
29125
29201
|
}
|
|
29126
|
-
lines2.push(opts.excludeTests === true && suppressed > 0 ? `${key}: (no non-test references found; ${suppressed}
|
|
29202
|
+
lines2.push(opts.excludeTests === true && suppressed > 0 ? `${key}: (no non-test references found; ${excludeTestsHiddenNote(suppressed)})` : `${key}: (no references found)`);
|
|
29127
29203
|
continue;
|
|
29128
29204
|
}
|
|
29129
29205
|
lines2.push(`${key}:`);
|
|
29130
29206
|
if (opts.top !== void 0) {
|
|
29131
29207
|
lines2.push(...renderTopFilesSummary(results, opts.top, suppressed));
|
|
29132
29208
|
} else if (opts.callers === true) {
|
|
29133
|
-
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${results.length}
|
|
29209
|
+
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`);
|
|
29134
29210
|
lines2.push(...renderCallerGroups(results, opts.context ?? 0));
|
|
29135
29211
|
} else {
|
|
29136
|
-
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${results.length}
|
|
29212
|
+
if (opts.excludeTests === true && suppressed > 0) lines2.push(` ${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`);
|
|
29137
29213
|
for (const ref2 of results) lines2.push(...renderRefLines(ref2, opts.context ?? 0));
|
|
29138
29214
|
}
|
|
29139
29215
|
}
|
|
@@ -29174,16 +29250,25 @@ function runRefsSingle(opts) {
|
|
|
29174
29250
|
}
|
|
29175
29251
|
if (results.length === 0) {
|
|
29176
29252
|
if (matchesGrep !== void 0 && preGrepCount > 0) {
|
|
29253
|
+
if (opts.json === true) {
|
|
29254
|
+
emit2(JSON.stringify({ items: [], truncated: false, totalCount: 0 }, null, 2));
|
|
29255
|
+
return 0;
|
|
29256
|
+
}
|
|
29177
29257
|
emit2(grepFilteredToEmptyNotice(preGrepCount, opts.grep ?? "", "reference", "references"));
|
|
29178
29258
|
return 0;
|
|
29179
29259
|
}
|
|
29180
29260
|
if (opts.excludeTests === true && suppressed > 0) {
|
|
29181
|
-
emitErr(`No non-test references found for '${symName}' (${suppressed}
|
|
29261
|
+
emitErr(`No non-test references found for '${symName}' (${excludeTestsHiddenNote(suppressed)})`);
|
|
29262
|
+
return 1;
|
|
29263
|
+
}
|
|
29264
|
+
const rootDir = resolveProjectRoot({ project: process.cwd() });
|
|
29265
|
+
if (querySymbols({ name: symName, rootDir, limit: 1 }).length === 0) {
|
|
29266
|
+
emitErr(`Symbol not found: ${symName}${unknownSymbolSuggestion(symName, rootDir)}`);
|
|
29267
|
+
if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr(emptyIndexMessage(rootDir));
|
|
29182
29268
|
return 1;
|
|
29183
29269
|
}
|
|
29184
29270
|
emitErr(`No references found for '${symName}'`);
|
|
29185
29271
|
if (opts.json !== true) {
|
|
29186
|
-
const rootDir = resolveProjectRoot({ project: process.cwd() });
|
|
29187
29272
|
if (isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr(emptyIndexMessage(rootDir));
|
|
29188
29273
|
}
|
|
29189
29274
|
return 1;
|
|
@@ -29203,7 +29288,7 @@ function runRefsSingle(opts) {
|
|
|
29203
29288
|
recordReadStat("symbol_read", fullSourceBytes, text2, symName);
|
|
29204
29289
|
return 0;
|
|
29205
29290
|
}
|
|
29206
|
-
const lines2 = opts.top !== void 0 ? renderTopFilesSummary(results, opts.top, suppressed) : opts.callers === true ? [...opts.excludeTests === true && suppressed > 0 ? [`${results.length}
|
|
29291
|
+
const lines2 = opts.top !== void 0 ? renderTopFilesSummary(results, opts.top, suppressed) : opts.callers === true ? [...opts.excludeTests === true && suppressed > 0 ? [`${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`] : [], ...renderCallerGroups(results, opts.context ?? 0)] : [...opts.excludeTests === true && suppressed > 0 ? [`${countNoun(results.length, "reference")} (${excludeTestsHiddenNote(suppressed)})`] : [], ...results.flatMap((ref2) => renderRefLines(ref2, opts.context ?? 0, ""))];
|
|
29207
29292
|
const text = lines2.join("\n");
|
|
29208
29293
|
emitGuarded(text, "symbol");
|
|
29209
29294
|
recordReadStat("symbol_read", fullSourceBytes, text, symName);
|
|
@@ -29221,8 +29306,8 @@ function groupRefsByFile(refs) {
|
|
|
29221
29306
|
function renderTopFilesSummary(refs, topN, suppressed) {
|
|
29222
29307
|
const grouped = groupRefsByFile(refs);
|
|
29223
29308
|
const shown = grouped.slice(0, topN);
|
|
29224
|
-
const suppressedNote = suppressed !== void 0 && suppressed > 0 ? ` (${suppressed}
|
|
29225
|
-
const lines2 = [`${refs.length}
|
|
29309
|
+
const suppressedNote = suppressed !== void 0 && suppressed > 0 ? ` (${excludeTestsHiddenNote(suppressed)})` : "";
|
|
29310
|
+
const lines2 = [`${countNoun(refs.length, "reference")} across ${countNoun(grouped.length, "file")} (showing top ${shown.length})${suppressedNote}`];
|
|
29226
29311
|
for (const { file: file2, count } of shown) lines2.push(` ${count} ${refsDisplayPath(file2)}`);
|
|
29227
29312
|
const omittedFiles = grouped.length - shown.length;
|
|
29228
29313
|
if (omittedFiles > 0) {
|
|
@@ -29371,7 +29456,7 @@ function runSkeleton(opts) {
|
|
|
29371
29456
|
return { text: text2, code: 0 };
|
|
29372
29457
|
}
|
|
29373
29458
|
const totalLines = filtered.length > 0 ? Math.max(...filtered.map((s) => s.lineEnd)) : 0;
|
|
29374
|
-
const lines2 = [`# Skeleton: ${opts.file} (${filtered.length}
|
|
29459
|
+
const lines2 = [`# Skeleton: ${opts.file} (${countNoun(filtered.length, "symbol")}, ${countNoun(totalLines, "line")})`];
|
|
29375
29460
|
if (filtered.length === 0 && preFilterCount > 0) lines2.push(filteredToEmptyNotice(preFilterCount, opts.minLines, opts.grep));
|
|
29376
29461
|
for (const sym of filtered) {
|
|
29377
29462
|
const lineStr = sym.lineStart.toString().padStart(6);
|
|
@@ -29411,7 +29496,7 @@ function runOutline(opts) {
|
|
|
29411
29496
|
recordReadStat("outline", fullSourceBytes, text2, opts.file);
|
|
29412
29497
|
return { text: text2, code: 0 };
|
|
29413
29498
|
}
|
|
29414
|
-
const lines2 = [`# Outline: ${opts.file} (${filtered.length
|
|
29499
|
+
const lines2 = [`# Outline: ${opts.file} (${countNoun(filtered.length, "symbol")})`];
|
|
29415
29500
|
if (filtered.length === 0 && preFilterCount > 0) lines2.push(filteredToEmptyNotice(preFilterCount, opts.minLines, opts.grep));
|
|
29416
29501
|
for (const sym of filtered) {
|
|
29417
29502
|
const rangeStr = `${sym.lineStart.toString().padStart(4)}-${sym.lineEnd.toString().padEnd(6)}`;
|
|
@@ -30118,16 +30203,25 @@ function runFind(opts) {
|
|
|
30118
30203
|
const symbols = rawSymbols.filter(
|
|
30119
30204
|
(s) => s.name.toLowerCase().includes(patternLower)
|
|
30120
30205
|
);
|
|
30121
|
-
|
|
30206
|
+
let fuzzyNames = [];
|
|
30207
|
+
if (symbols.length === 0) {
|
|
30208
|
+
fuzzyNames = rankSimilarNames(rawSymbols.map((s) => s.name), opts.pattern);
|
|
30209
|
+
}
|
|
30210
|
+
const matched = fuzzyNames.length > 0 ? fuzzyNames.flatMap((n) => rawSymbols.filter((s) => s.name === n)) : symbols;
|
|
30211
|
+
const files = [...new Set(matched.map((s) => s.filePath))].slice(0, opts.limit ?? 50);
|
|
30122
30212
|
const truncated = rawSymbols.length === FIND_SCAN_LIMIT;
|
|
30123
30213
|
if (files.length === 0) {
|
|
30124
30214
|
emitErr(`No indexed files match '${opts.pattern}'`);
|
|
30125
30215
|
return 1;
|
|
30126
30216
|
}
|
|
30127
30217
|
if (opts.json === true) {
|
|
30128
|
-
|
|
30218
|
+
const fuzzyPayload = fuzzyNames.length > 0 ? { fuzzy: true, matchedNames: fuzzyNames } : {};
|
|
30219
|
+
emit2(JSON.stringify({ files, truncated, ...fuzzyPayload }, null, 2));
|
|
30129
30220
|
return 0;
|
|
30130
30221
|
}
|
|
30222
|
+
if (fuzzyNames.length > 0) {
|
|
30223
|
+
emitErr(`No symbol name contains '${opts.pattern}'; showing files for the nearest indexed ${fuzzyNames.length === 1 ? "name" : "names"}: ${fuzzyNames.join(", ")}`);
|
|
30224
|
+
}
|
|
30131
30225
|
for (const f of files) {
|
|
30132
30226
|
emit2(toDisplayPath(rootDir, f));
|
|
30133
30227
|
}
|
|
@@ -30231,7 +30325,12 @@ function runChanged(opts = {}) {
|
|
|
30231
30325
|
emitErr(`Could not run git diff against '${ref2}'`);
|
|
30232
30326
|
return 1;
|
|
30233
30327
|
}
|
|
30328
|
+
const emptyEnvelope = () => {
|
|
30329
|
+
emit2(JSON.stringify({ items: [], truncated: false, totalCount: 0 }, null, 2));
|
|
30330
|
+
return 0;
|
|
30331
|
+
};
|
|
30234
30332
|
if (changedFiles.length === 0) {
|
|
30333
|
+
if (opts.json === true) return emptyEnvelope();
|
|
30235
30334
|
emit2("No files changed.");
|
|
30236
30335
|
return 0;
|
|
30237
30336
|
}
|
|
@@ -30239,9 +30338,29 @@ function runChanged(opts = {}) {
|
|
|
30239
30338
|
const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
|
|
30240
30339
|
if (matchesGrep !== void 0) changedFiles = changedFiles.filter((f) => matchesGrep(f));
|
|
30241
30340
|
if (matchesGrep !== void 0 && changedFiles.length === 0) {
|
|
30341
|
+
if (opts.json === true) return emptyEnvelope();
|
|
30242
30342
|
emit2(grepFilteredToEmptyNotice(preGrepFileCount, opts.grep ?? "", "changed file", "changed files"));
|
|
30243
30343
|
return 0;
|
|
30244
30344
|
}
|
|
30345
|
+
const postGrepFileCount = changedFiles.length;
|
|
30346
|
+
let hiddenTestFiles = 0;
|
|
30347
|
+
if (opts.excludeTests === true) {
|
|
30348
|
+
const kept = changedFiles.filter((f) => !isTestFile(f));
|
|
30349
|
+
hiddenTestFiles = changedFiles.length - kept.length;
|
|
30350
|
+
changedFiles = kept;
|
|
30351
|
+
}
|
|
30352
|
+
if (changedFiles.length === 0 && hiddenTestFiles > 0) {
|
|
30353
|
+
if (opts.json === true) return emptyEnvelope();
|
|
30354
|
+
const grepRemoved = preGrepFileCount - postGrepFileCount;
|
|
30355
|
+
if (matchesGrep !== void 0 && grepRemoved > 0) {
|
|
30356
|
+
emit2(
|
|
30357
|
+
`No non-test files matched --grep ${opts.grep ?? ""} (${excludeTestsHiddenNote(hiddenTestFiles)}; ${countNoun(grepRemoved, "other changed file")} did not match the filter)`
|
|
30358
|
+
);
|
|
30359
|
+
return 0;
|
|
30360
|
+
}
|
|
30361
|
+
emit2(`No non-test files changed (${excludeTestsHiddenNote(hiddenTestFiles)})`);
|
|
30362
|
+
return 0;
|
|
30363
|
+
}
|
|
30245
30364
|
if (opts.symbolMode === true) {
|
|
30246
30365
|
let hunksByFile = /* @__PURE__ */ new Map();
|
|
30247
30366
|
try {
|
|
@@ -30253,12 +30372,13 @@ function runChanged(opts = {}) {
|
|
|
30253
30372
|
}
|
|
30254
30373
|
const allSymbols = [];
|
|
30255
30374
|
for (const f of changedFiles) {
|
|
30256
|
-
const fileSymbols = querySymbols({ filePath: resolveIndexPath(f, projectRoot), limit:
|
|
30375
|
+
const fileSymbols = querySymbols({ filePath: resolveIndexPath(f, projectRoot), limit: FIND_SCAN_LIMIT });
|
|
30257
30376
|
const hunks = hunksByFile.get(f);
|
|
30258
30377
|
const scoped = hunks === void 0 ? fileSymbols : fileSymbols.filter((s) => hunks.some((h) => h.start <= s.lineEnd && h.end >= s.lineStart));
|
|
30259
30378
|
allSymbols.push(...scoped);
|
|
30260
30379
|
}
|
|
30261
30380
|
if (allSymbols.length === 0) {
|
|
30381
|
+
if (opts.json === true) return emptyEnvelope();
|
|
30262
30382
|
emit2("No symbols changed.");
|
|
30263
30383
|
return 0;
|
|
30264
30384
|
}
|
|
@@ -31237,7 +31357,17 @@ async function runSemantic(query, opts) {
|
|
|
31237
31357
|
void 0,
|
|
31238
31358
|
rootDir
|
|
31239
31359
|
);
|
|
31240
|
-
const
|
|
31360
|
+
const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
|
|
31361
|
+
const mergedHits = mergeNearbyHits(rawHits);
|
|
31362
|
+
const preGrepHitCount = mergedHits.length;
|
|
31363
|
+
const keepHit = (h) => {
|
|
31364
|
+
if (opts.excludeTests === true && isTestFile(h.filePath)) return false;
|
|
31365
|
+
return matchesGrep === void 0 || matchesGrep(toDisplayPath(rootDir, h.filePath));
|
|
31366
|
+
};
|
|
31367
|
+
const anyFilter = matchesGrep !== void 0 || opts.excludeTests === true;
|
|
31368
|
+
const filteredHits = anyFilter ? mergedHits.filter(keepHit) : mergedHits;
|
|
31369
|
+
const suppressedHits = opts.excludeTests === true ? mergedHits.filter((h) => (matchesGrep === void 0 || matchesGrep(toDisplayPath(rootDir, h.filePath))) && isTestFile(h.filePath)).length : 0;
|
|
31370
|
+
const hits = filteredHits.slice(0, n);
|
|
31241
31371
|
if (hits.length > 0) {
|
|
31242
31372
|
const enclosing = hits.map((h) => resolveEnclosingSymbol(h.filePath, h.startLine));
|
|
31243
31373
|
if (opts.json === true) {
|
|
@@ -31265,8 +31395,41 @@ ${previewLines(h.text, 3)}`;
|
|
|
31265
31395
|
recordReadStat("semantic_search", sumFileSizes(hits.map((h) => h.filePath)), text2, query);
|
|
31266
31396
|
return { text: text2, code: 0 };
|
|
31267
31397
|
}
|
|
31268
|
-
|
|
31398
|
+
let results;
|
|
31399
|
+
let preGrepFtsCount = 0;
|
|
31400
|
+
let suppressedFts = 0;
|
|
31401
|
+
if (anyFilter) {
|
|
31402
|
+
const overFetchFts = Math.min(MAX_OVER_FETCH, n * OVER_FETCH_FACTOR);
|
|
31403
|
+
const rawResults = searchSymbolsFts(query, overFetchFts, void 0, rootDir);
|
|
31404
|
+
preGrepFtsCount = rawResults.length;
|
|
31405
|
+
if (opts.excludeTests === true) {
|
|
31406
|
+
suppressedFts = rawResults.filter((s) => (matchesGrep === void 0 || matchesGrep(toDisplayPath(rootDir, s.filePath))) && isTestFile(s.filePath)).length;
|
|
31407
|
+
}
|
|
31408
|
+
results = rawResults.filter(keepHit).slice(0, n);
|
|
31409
|
+
} else {
|
|
31410
|
+
results = searchSymbolsFts(query, n, void 0, rootDir);
|
|
31411
|
+
}
|
|
31269
31412
|
if (results.length === 0) {
|
|
31413
|
+
const preGrepTotal = preGrepHitCount + preGrepFtsCount;
|
|
31414
|
+
if (matchesGrep !== void 0 && preGrepTotal > 0) {
|
|
31415
|
+
const notice = grepFilteredToEmptyNotice(preGrepTotal, opts.grep ?? "", "match", "matches");
|
|
31416
|
+
if (opts.json === true) {
|
|
31417
|
+
const payload = { source: "fts", items: [], truncated: false, totalCount: 0, grepFilteredToEmpty: true, hint: notice.trim() };
|
|
31418
|
+
return { text: JSON.stringify(payload, null, 2), code: 0 };
|
|
31419
|
+
}
|
|
31420
|
+
return { text: `token-goat: ${notice.trim()}`, code: 0 };
|
|
31421
|
+
}
|
|
31422
|
+
if (opts.excludeTests === true) {
|
|
31423
|
+
const suppressedTotal = suppressedHits + suppressedFts;
|
|
31424
|
+
if (suppressedTotal > 0) {
|
|
31425
|
+
const notice = `no non-test matches for '${query}' (${excludeTestsHiddenNote(suppressedTotal)})`;
|
|
31426
|
+
if (opts.json === true) {
|
|
31427
|
+
const payload = { source: "fts", items: [], truncated: false, totalCount: 0, excludeTestsFilteredToEmpty: true, hint: notice };
|
|
31428
|
+
return { text: JSON.stringify(payload, null, 2), code: 0 };
|
|
31429
|
+
}
|
|
31430
|
+
return { text: `token-goat: ${notice}`, code: 0 };
|
|
31431
|
+
}
|
|
31432
|
+
}
|
|
31270
31433
|
const indexEmpty = isIndexEmptyForProject(globalDbPath(), rootDir);
|
|
31271
31434
|
if (opts.json === true) {
|
|
31272
31435
|
const payload = indexEmpty ? { source: "fts", items: [], truncated: false, totalCount: 0, indexEmpty: true, hint: emptyIndexMessage(rootDir) } : { source: "fts", items: [], truncated: false, totalCount: 0 };
|
|
@@ -31526,7 +31689,7 @@ function fileDefinesName(fp, name2, getSyms) {
|
|
|
31526
31689
|
return getSyms(fp).some((s) => s.name === name2);
|
|
31527
31690
|
}
|
|
31528
31691
|
function filterRefsForSymbol(refs, name2, filePath, getSyms) {
|
|
31529
|
-
return refs.filter((ref2) => ref2.filePath === filePath || !fileDefinesName(ref2.filePath, name2, getSyms));
|
|
31692
|
+
return refs.filter((ref2) => foldPath(ref2.filePath) === foldPath(filePath) || !fileDefinesName(ref2.filePath, name2, getSyms));
|
|
31530
31693
|
}
|
|
31531
31694
|
function resolveCallers(name2, limit, filePath, rootDir, excludeTests) {
|
|
31532
31695
|
const resolvedRootDir = rootDir ?? resolveProjectRoot({ project: process.cwd() });
|
|
@@ -31574,7 +31737,12 @@ function runCallers(opts) {
|
|
|
31574
31737
|
return 0;
|
|
31575
31738
|
}
|
|
31576
31739
|
if (opts.excludeTests === true && suppressed > 0) {
|
|
31577
|
-
emitErr2(`No non-test references found for '${opts.symbol}' (${suppressed}
|
|
31740
|
+
emitErr2(`No non-test references found for '${opts.symbol}' (${excludeTestsHiddenNote(suppressed)})`);
|
|
31741
|
+
return 1;
|
|
31742
|
+
}
|
|
31743
|
+
if (querySymbols({ name: name2, rootDir, limit: 1 }).length === 0) {
|
|
31744
|
+
emitErr2(`Symbol not found: ${opts.symbol}${unknownSymbolSuggestion(name2, rootDir)}`);
|
|
31745
|
+
if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr2(emptyIndexMessage(rootDir));
|
|
31578
31746
|
return 1;
|
|
31579
31747
|
}
|
|
31580
31748
|
emitErr2(`No references found for '${opts.symbol}'`);
|
|
@@ -31594,7 +31762,7 @@ function runCallers(opts) {
|
|
|
31594
31762
|
return 0;
|
|
31595
31763
|
}
|
|
31596
31764
|
if (opts.excludeTests === true && suppressed > 0) {
|
|
31597
|
-
emit3(`${entries.length}
|
|
31765
|
+
emit3(`${countNoun(entries.length, "caller")} found (${excludeTestsHiddenNote(suppressed)})`);
|
|
31598
31766
|
}
|
|
31599
31767
|
for (const e of entries) {
|
|
31600
31768
|
const displayPath = toDisplayPath(rootDir, e.file);
|
|
@@ -31620,17 +31788,22 @@ function runCallChain(opts) {
|
|
|
31620
31788
|
return 1;
|
|
31621
31789
|
}
|
|
31622
31790
|
} else if (querySymbols({ name: name2, rootDir, limit: 1 }).length === 0) {
|
|
31623
|
-
emitErr2(`Symbol not found: ${opts.symbol}`);
|
|
31791
|
+
emitErr2(`Symbol not found: ${opts.symbol}${unknownSymbolSuggestion(name2, rootDir)}`);
|
|
31624
31792
|
if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr2(emptyIndexMessage(rootDir));
|
|
31625
31793
|
return 1;
|
|
31626
31794
|
}
|
|
31627
31795
|
const getSyms = buildFileSymCache();
|
|
31796
|
+
let suppressedCount = 0;
|
|
31628
31797
|
const callersOf = (n) => {
|
|
31629
31798
|
const refs = queryRefs({ name: n, limit: DEFAULT_REF_QUERY_LIMIT, rootDir });
|
|
31630
31799
|
if (refs.length === 0) return [];
|
|
31631
31800
|
const scoped = fileHint !== void 0 && n === name2 ? filterRefsForSymbol(refs, n, fileHint, getSyms) : refs;
|
|
31632
31801
|
const names = /* @__PURE__ */ new Set();
|
|
31633
31802
|
for (const ref2 of scoped) {
|
|
31803
|
+
if (opts.excludeTests === true && isTestFile(ref2.filePath)) {
|
|
31804
|
+
suppressedCount += 1;
|
|
31805
|
+
continue;
|
|
31806
|
+
}
|
|
31634
31807
|
const enc = enclosingSymbol(getSyms(ref2.filePath), ref2.line);
|
|
31635
31808
|
if (enc !== null) names.add(enc.name);
|
|
31636
31809
|
}
|
|
@@ -31642,6 +31815,10 @@ function runCallChain(opts) {
|
|
|
31642
31815
|
return 0;
|
|
31643
31816
|
}
|
|
31644
31817
|
if (chains.length === 1 && chains[0]?.length === 1 && chains[0][0] === name2) {
|
|
31818
|
+
if (opts.excludeTests === true && suppressedCount > 0) {
|
|
31819
|
+
emit3(`${name2} (no non-test callers; ${excludeTestsHiddenNote(suppressedCount)})`);
|
|
31820
|
+
return 0;
|
|
31821
|
+
}
|
|
31645
31822
|
emit3(`${name2} (no callers)`);
|
|
31646
31823
|
return 0;
|
|
31647
31824
|
}
|
|
@@ -31671,6 +31848,7 @@ function runImpact(opts) {
|
|
|
31671
31848
|
const getSyms = buildFileSymCache();
|
|
31672
31849
|
const hops = /* @__PURE__ */ new Map([[rootName, 0]]);
|
|
31673
31850
|
const queue = [[rootName, 0]];
|
|
31851
|
+
let suppressedCount = 0;
|
|
31674
31852
|
while (queue.length > 0) {
|
|
31675
31853
|
const item = queue.shift();
|
|
31676
31854
|
if (item === void 0) break;
|
|
@@ -31679,6 +31857,10 @@ function runImpact(opts) {
|
|
|
31679
31857
|
const refs = queryRefs({ name: name2, limit: DEFAULT_REF_QUERY_LIMIT, rootDir });
|
|
31680
31858
|
const scoped = fileHint !== void 0 && name2 === rootName ? filterRefsForSymbol(refs, name2, fileHint, getSyms) : refs;
|
|
31681
31859
|
for (const ref2 of scoped) {
|
|
31860
|
+
if (opts.excludeTests === true && isTestFile(ref2.filePath)) {
|
|
31861
|
+
suppressedCount += 1;
|
|
31862
|
+
continue;
|
|
31863
|
+
}
|
|
31682
31864
|
const newHop = depth + 1;
|
|
31683
31865
|
const enc = enclosingSymbol(getSyms(ref2.filePath), ref2.line);
|
|
31684
31866
|
if (enc === null) {
|
|
@@ -31698,6 +31880,14 @@ function runImpact(opts) {
|
|
|
31698
31880
|
hops.delete(rootName);
|
|
31699
31881
|
const sorted = [...hops.entries()].sort(compareHopEntries).slice(0, top);
|
|
31700
31882
|
if (sorted.length === 0) {
|
|
31883
|
+
if (opts.excludeTests === true && suppressedCount > 0) {
|
|
31884
|
+
emitErr2(`No non-test impact found for '${opts.symbol}' (${excludeTestsHiddenNote(suppressedCount)})`);
|
|
31885
|
+
return 1;
|
|
31886
|
+
}
|
|
31887
|
+
if (querySymbols({ name: rootName, rootDir, limit: 1 }).length === 0) {
|
|
31888
|
+
emitErr2(`Symbol not found: ${opts.symbol}${unknownSymbolSuggestion(rootName, rootDir)}`);
|
|
31889
|
+
return 1;
|
|
31890
|
+
}
|
|
31701
31891
|
emitErr2(`No callers found for '${opts.symbol}'`);
|
|
31702
31892
|
return 1;
|
|
31703
31893
|
}
|
|
@@ -31794,7 +31984,7 @@ function runDead(opts) {
|
|
|
31794
31984
|
return 0;
|
|
31795
31985
|
}
|
|
31796
31986
|
if (opts.excludeTests === true && suppressed > 0) {
|
|
31797
|
-
emit3(`No dead symbols found (${suppressed}
|
|
31987
|
+
emit3(`No dead symbols found (${excludeTestsHiddenNote(suppressed)}).`);
|
|
31798
31988
|
} else {
|
|
31799
31989
|
emit3("No dead symbols found.");
|
|
31800
31990
|
}
|
|
@@ -31802,7 +31992,7 @@ function runDead(opts) {
|
|
|
31802
31992
|
return 0;
|
|
31803
31993
|
}
|
|
31804
31994
|
if (opts.excludeTests === true && suppressed > 0) {
|
|
31805
|
-
emit3(`${sliced.length
|
|
31995
|
+
emit3(`${countNoun(sliced.length, "dead symbol")} (${excludeTestsHiddenNote(suppressed)})`);
|
|
31806
31996
|
}
|
|
31807
31997
|
for (const r of sliced) {
|
|
31808
31998
|
emit3(`${r.name} ${toDisplayPath(rootDir, r.file)}:${r.line}`);
|
|
@@ -67309,7 +67499,6 @@ function checkSymbolCount(dbPath, rootDir) {
|
|
|
67309
67499
|
}
|
|
67310
67500
|
}
|
|
67311
67501
|
var DIRTY_QUEUE_BACKLOG_WARN_THRESHOLD = 500;
|
|
67312
|
-
var DRAIN_HEARTBEAT_STALE_MS = 6e4;
|
|
67313
67502
|
function checkDirtyQueueHealth(dataDir2) {
|
|
67314
67503
|
let pendingCount = 0;
|
|
67315
67504
|
try {
|
|
@@ -67332,7 +67521,7 @@ function checkDirtyQueueHealth(dataDir2) {
|
|
|
67332
67521
|
heartbeatAgeMs = Date.now() - fs47.statSync(drainHeartbeatPathFor(dataDir2)).mtimeMs;
|
|
67333
67522
|
} catch {
|
|
67334
67523
|
}
|
|
67335
|
-
if (heartbeatAgeMs !== null && heartbeatAgeMs >
|
|
67524
|
+
if (heartbeatAgeMs !== null && heartbeatAgeMs > WORKER_HEARTBEAT_STALE_MS) {
|
|
67336
67525
|
return {
|
|
67337
67526
|
name: "Dirty queue",
|
|
67338
67527
|
status: "warn",
|
|
@@ -73409,7 +73598,12 @@ function requirePositiveInt(flag, raw) {
|
|
|
73409
73598
|
}
|
|
73410
73599
|
async function cmdSemantic(query, opts) {
|
|
73411
73600
|
const limit = opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20;
|
|
73412
|
-
const { text, code } = await runSemantic(query, {
|
|
73601
|
+
const { text, code } = await runSemantic(query, {
|
|
73602
|
+
limit,
|
|
73603
|
+
...opts.json === true ? { json: true } : {},
|
|
73604
|
+
...opts.grep !== void 0 ? { grep: opts.grep } : {},
|
|
73605
|
+
...opts.excludeTests === true ? { excludeTests: true } : {}
|
|
73606
|
+
});
|
|
73413
73607
|
(opts.json === true || code === 0 ? out : err)(text);
|
|
73414
73608
|
process.exitCode = code;
|
|
73415
73609
|
}
|
|
@@ -75344,7 +75538,7 @@ function buildProgram() {
|
|
|
75344
75538
|
process.exitCode = 1;
|
|
75345
75539
|
}
|
|
75346
75540
|
};
|
|
75347
|
-
program2.command("symbol
|
|
75541
|
+
program2.command("symbol [name]").description("search for a symbol by name, or project-wide by --grep name pattern").option("-l, --limit <n>", "max results").option("-f, --file <path>", "restrict to one file").option("-k, --kind <kind>", "restrict to one kind (function, class, ...)").option("-p, --project [path]", "scope search to one project root instead of the global index (defaults to cwd)").option("-j, --json", "output as JSON").option("--grep <pattern>", "only show symbols whose name matches this regex (literal substring if it is not valid regex); cannot be combined with <name>").option("--exclude-tests", "hide symbols defined in a test file (opt-in; default output is unchanged)").action((name2, opts) => {
|
|
75348
75542
|
let projectRoot;
|
|
75349
75543
|
if (opts.project === true) {
|
|
75350
75544
|
projectRoot = resolveProjectRoot({ project: process.cwd() });
|
|
@@ -75353,12 +75547,14 @@ function buildProgram() {
|
|
|
75353
75547
|
}
|
|
75354
75548
|
return runExitText(
|
|
75355
75549
|
() => runSymbol({
|
|
75356
|
-
name: name2,
|
|
75550
|
+
...name2 !== void 0 ? { name: name2 } : {},
|
|
75357
75551
|
limit: opts.limit !== void 0 ? requireNonNegativeInt("--limit", opts.limit) : 20,
|
|
75358
75552
|
...opts.file !== void 0 ? { file: opts.file } : {},
|
|
75359
75553
|
...opts.kind !== void 0 ? { kind: opts.kind } : {},
|
|
75360
75554
|
...projectRoot !== void 0 ? { projectRoot } : {},
|
|
75361
|
-
...opts.json === true ? { json: true } : {}
|
|
75555
|
+
...opts.json === true ? { json: true } : {},
|
|
75556
|
+
...opts.grep !== void 0 ? { grep: opts.grep } : {},
|
|
75557
|
+
...opts.excludeTests === true ? { excludeTests: true } : {}
|
|
75362
75558
|
})
|
|
75363
75559
|
);
|
|
75364
75560
|
});
|
|
@@ -75391,7 +75587,7 @@ function buildProgram() {
|
|
|
75391
75587
|
).option("-j, --json", "output as JSON").option("--list", "list all section headings in the file instead of reading one").action(
|
|
75392
75588
|
(spec, opts) => opts.list === true ? runExit(() => runListSections({ file: spec, ...opts.json === true ? { json: true } : {} })) : runExitText(() => runSection({ spec, ...opts.json === true ? { json: true } : {} }))
|
|
75393
75589
|
);
|
|
75394
|
-
program2.command("semantic <query>").description("semantic search (falls back to full-text search)").option("-l, --limit <n>", "max results").option("-j, --json", "output as JSON").action(guard(cmdSemantic));
|
|
75590
|
+
program2.command("semantic <query>").description("semantic search (falls back to full-text search)").option("-l, --limit <n>", "max results").option("-j, --json", "output as JSON").option("--grep <pattern>", "filter to hits whose file path matches this regex (literal substring if it is not valid regex); matched against the path as rendered").option("--exclude-tests", "hide hits whose file is a test file (opt-in; default output is unchanged)").action(guard(cmdSemantic));
|
|
75395
75591
|
program2.command("skeleton <file> [more...]").description('list all symbols in a file without bodies (also accepts a comma-separated file list "a,b,c" for one headed block per file)').option("-j, --json", "output as JSON").option("--min-lines <n>", "only show symbols at least N lines long").option("--grep <pattern>", "only show symbols whose name matches this regex (literal substring if it is not valid regex)").option("--force-refresh", "reparse file from disk before querying (ignore stale index)").option("--stats", "add per-symbol reference count and doc-coverage flag").action(
|
|
75396
75592
|
(file2, more, opts) => runExitText(
|
|
75397
75593
|
() => noteExtraFileArgs(
|
|
@@ -75527,21 +75723,23 @@ function buildProgram() {
|
|
|
75527
75723
|
})
|
|
75528
75724
|
)
|
|
75529
75725
|
);
|
|
75530
|
-
program2.command("call-chain <symbol>").description("transitive callers up toward entry points (BFS, cycle-safe; accepts file::symbol to disambiguate which same-named definition is meant)").option("-d, --depth <n>", "max BFS depth (default 8)").option("-j, --json", "output as JSON").action(
|
|
75726
|
+
program2.command("call-chain <symbol>").description("transitive callers up toward entry points (BFS, cycle-safe; accepts file::symbol to disambiguate which same-named definition is meant)").option("-d, --depth <n>", "max BFS depth (default 8)").option("-j, --json", "output as JSON").option("--exclude-tests", "hide callers whose call site lives in a test file (opt-in; default output is unchanged)").action(
|
|
75531
75727
|
(symbol3, opts) => runExit(
|
|
75532
75728
|
() => runCallChain({
|
|
75533
75729
|
symbol: symbol3,
|
|
75534
75730
|
...opts.depth !== void 0 ? { depth: requireInt("--depth", opts.depth) } : {},
|
|
75535
|
-
...opts.json === true ? { json: true } : {}
|
|
75731
|
+
...opts.json === true ? { json: true } : {},
|
|
75732
|
+
...opts.excludeTests === true ? { excludeTests: true } : {}
|
|
75536
75733
|
})
|
|
75537
75734
|
)
|
|
75538
75735
|
);
|
|
75539
|
-
program2.command("impact <symbol>").description("transitive set of callers impacted by a change (with hop depth; accepts file::symbol to disambiguate which same-named definition is meant)").option("--top <n>", "limit output to top N results").option("-j, --json", "output as JSON").action(
|
|
75736
|
+
program2.command("impact <symbol>").description("transitive set of callers impacted by a change (with hop depth; accepts file::symbol to disambiguate which same-named definition is meant)").option("--top <n>", "limit output to top N results").option("-j, --json", "output as JSON").option("--exclude-tests", "hide callers whose call site lives in a test file (opt-in; default output is unchanged)").action(
|
|
75540
75737
|
(symbol3, opts) => runExit(
|
|
75541
75738
|
() => runImpact({
|
|
75542
75739
|
symbol: symbol3,
|
|
75543
75740
|
...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
|
|
75544
|
-
...opts.json === true ? { json: true } : {}
|
|
75741
|
+
...opts.json === true ? { json: true } : {},
|
|
75742
|
+
...opts.excludeTests === true ? { excludeTests: true } : {}
|
|
75545
75743
|
})
|
|
75546
75744
|
)
|
|
75547
75745
|
);
|
|
@@ -75698,13 +75896,14 @@ function buildProgram() {
|
|
|
75698
75896
|
}))());
|
|
75699
75897
|
program2.command("fetch-image <url>").description("fetch an image URL and shrink it (saves to --out path or a temp file)").option("--out <path>", "output file path").option("-j, --json", "output as JSON").action((url2, opts) => guard(() => cmdFetchImage({ url: url2, ...opts.out !== void 0 ? { out: opts.out } : {}, ...opts.json === true ? { json: true } : {} }))());
|
|
75700
75898
|
program2.command("history").description("show recent session history: bash commands and web fetches (current-session or recent cache)").option("--limit <n>", "max entries to show (default: 30)").option("-j, --json", "output as JSON").action((opts) => guard(() => cmdHistory(opts))());
|
|
75701
|
-
program2.command("changed [ref]").description("list files or symbols changed since a git ref").option("--since <ref>", "git ref to compare against (default: HEAD~5)").option("--symbol", "list symbols instead of files").option("-j, --json", "output as JSON").option("--grep <pattern>", "filter to changed files whose path matches this regex (falls back to a literal substring match when the pattern does not compile); applies to file paths even in --symbol mode").action(
|
|
75899
|
+
program2.command("changed [ref]").description("list files or symbols changed since a git ref").option("--since <ref>", "git ref to compare against (default: HEAD~5)").option("--symbol", "list symbols instead of files").option("-j, --json", "output as JSON").option("--grep <pattern>", "filter to changed files whose path matches this regex (falls back to a literal substring match when the pattern does not compile); applies to file paths even in --symbol mode").option("--exclude-tests", "hide changed files that live in a test file (opt-in; default output is unchanged); applies to file paths even in --symbol mode").action(
|
|
75702
75900
|
(ref2, opts) => runExit(
|
|
75703
75901
|
() => runChanged({
|
|
75704
75902
|
ref: opts.since ?? ref2 ?? "HEAD~5",
|
|
75705
75903
|
...opts.symbol === true ? { symbolMode: true } : {},
|
|
75706
75904
|
...opts.json === true ? { json: true } : {},
|
|
75707
|
-
...opts.grep !== void 0 ? { grep: opts.grep } : {}
|
|
75905
|
+
...opts.grep !== void 0 ? { grep: opts.grep } : {},
|
|
75906
|
+
...opts.excludeTests === true ? { excludeTests: true } : {}
|
|
75708
75907
|
})
|
|
75709
75908
|
)
|
|
75710
75909
|
);
|