token-goat 2.9.4 → 2.9.6

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.
@@ -7,11 +7,11 @@ import {
7
7
  expandGlobs,
8
8
  leftoverIntegrations,
9
9
  run
10
- } from "./token-goat-chunk-6MU6FHE3.mjs";
11
- import "./token-goat-chunk-US57I7GN.mjs";
12
- import "./token-goat-chunk-FSC44QOH.mjs";
13
- import "./token-goat-chunk-CBO45DYZ.mjs";
14
- import "./token-goat-chunk-3ZR4NLB3.mjs";
10
+ } from "./token-goat-chunk-J7LGMKF3.mjs";
11
+ import "./token-goat-chunk-46VKOCUH.mjs";
12
+ import "./token-goat-chunk-7GJBID7S.mjs";
13
+ import "./token-goat-chunk-3HJQR4OO.mjs";
14
+ import "./token-goat-chunk-T2OE7MYM.mjs";
15
15
  import "./token-goat-chunk-EEIDFMEM.mjs";
16
16
  import "./token-goat-chunk-A37V4PBF.mjs";
17
17
  export {
@@ -1,6 +1,7 @@
1
1
  import { createRequire as __cjsRequire } from 'node:module';
2
2
  const require = __cjsRequire(import.meta.url);
3
3
  import {
4
+ DEFAULT_QUERY_LIMIT,
4
5
  IMPORT_RE,
5
6
  ImageDecodeError,
6
7
  MAX_OVER_FETCH,
@@ -8,7 +9,6 @@ import {
8
9
  MAX_ZIP_OUTPUT_BYTES,
9
10
  OVER_FETCH_FACTOR,
10
11
  SKIP_DIRS,
11
- UNTRUSTED_GITHUB_TAG,
12
12
  ZipInputTooLargeError,
13
13
  ZipOutputTooLargeError,
14
14
  capJsonRows,
@@ -24,7 +24,6 @@ import {
24
24
  extractPdfOutline,
25
25
  extractPdfText,
26
26
  fenceUntrusted,
27
- fenceUntrustedContent,
28
27
  formatCsvProfile,
29
28
  formatCsvTable,
30
29
  getEmbeddingCoverage,
@@ -68,10 +67,11 @@ import {
68
67
  walkProject,
69
68
  yamlLineClosesQuote,
70
69
  yamlOpenQuoteAfter
71
- } from "./token-goat-chunk-CBO45DYZ.mjs";
70
+ } from "./token-goat-chunk-3HJQR4OO.mjs";
72
71
  import {
73
72
  Database,
74
73
  PER_FILE_COUNTERFACTUAL_CEILING,
74
+ UNTRUSTED_GITHUB_TAG,
75
75
  _detectOpenQuote,
76
76
  _lineClosesQuote,
77
77
  atomicWriteBytes,
@@ -87,6 +87,8 @@ import {
87
87
  escapeRegExp,
88
88
  excludeTestsHiddenNote,
89
89
  extractErrorMessage,
90
+ fenceUntrustedContent,
91
+ fenceUntrustedFileContent,
90
92
  fileIsAbsent,
91
93
  filtersFilteredToEmptyNotice,
92
94
  findHtmlHeadingMatches,
@@ -112,6 +114,7 @@ import {
112
114
  requireNonNegativeStrictInt,
113
115
  requirePositiveStrictInt,
114
116
  resolveIndexPath,
117
+ resolveOnPath,
115
118
  resolveProjectRoot,
116
119
  runGit,
117
120
  savedTokensFromBytes,
@@ -122,7 +125,7 @@ import {
122
125
  unsupportedLanguageName,
123
126
  windowsCmdQuoteArg,
124
127
  withExtension
125
- } from "./token-goat-chunk-3ZR4NLB3.mjs";
128
+ } from "./token-goat-chunk-T2OE7MYM.mjs";
126
129
  import {
127
130
  registerReset
128
131
  } from "./token-goat-chunk-EEIDFMEM.mjs";
@@ -455,9 +458,72 @@ init_define_import_meta_env();
455
458
  import * as fs6 from "node:fs";
456
459
  import * as os from "node:os";
457
460
  import * as path6 from "node:path";
458
- import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
461
+ import { spawnSync as spawnSync2 } from "node:child_process";
459
462
  import { randomUUID } from "node:crypto";
460
463
 
464
+ // src/ref_blindness.ts
465
+ init_define_import_meta_env();
466
+ var REF_INDEXED_LANGUAGES = /* @__PURE__ */ new Set([
467
+ "typescript",
468
+ "javascript",
469
+ "python",
470
+ "go",
471
+ "rust",
472
+ "java",
473
+ "c",
474
+ "cpp",
475
+ "ruby"
476
+ ]);
477
+ function isRefIndexedLanguage(language) {
478
+ return REF_INDEXED_LANGUAGES.has(language);
479
+ }
480
+ function isRefIndexedFile(filePath) {
481
+ return isRefIndexedLanguage(detectLanguage(filePath));
482
+ }
483
+ var LANGUAGE_LABELS = /* @__PURE__ */ new Map([
484
+ ["csharp", "C#"],
485
+ ["cpp", "C++"],
486
+ ["c", "C"],
487
+ ["php", "PHP"],
488
+ ["powershell", "PowerShell"],
489
+ ["sql", "SQL"],
490
+ ["graphql", "GraphQL"],
491
+ ["proto", "Protocol Buffers"],
492
+ ["html", "HTML"],
493
+ ["css", "CSS"],
494
+ ["toml", "TOML"],
495
+ ["json", "JSON"],
496
+ ["yaml", "YAML"],
497
+ ["ini", "INI"],
498
+ ["env_file", "env file"],
499
+ ["ipynb", "Jupyter notebook"],
500
+ ["salesforce_metadata", "Salesforce metadata"],
501
+ ["salesforce_markup", "Salesforce markup"],
502
+ ["unknown", "this file type"]
503
+ ]);
504
+ function languageLabel(language) {
505
+ return LANGUAGE_LABELS.get(language) ?? language;
506
+ }
507
+ function refBlindLanguageNotice(symbolName, language, displayPath) {
508
+ return `Cannot determine references for '${symbolName}': ${languageLabel(language)} call sites are not indexed (${displayPath}). This is a gap in token-goat's index, not evidence the symbol is unreferenced. Search the source directly instead, e.g. \`rg -n -w ${symbolName}\`.`;
509
+ }
510
+ var REF_BLIND_KIND_REASON = "the index records value-position references only (calls, `new`, macro invocations), never type annotations, so a type declaration has no ref rows however widely it is used";
511
+ var REF_BLIND_DEF_PROBE_LIMIT = 50;
512
+ function kindWithArticle(kind) {
513
+ return `${/^[aeiou]/.test(kind) ? "an" : "a"} ${kind}`;
514
+ }
515
+ function refBlindKindClause(symbolName, kinds) {
516
+ const first = kinds[0];
517
+ if (kinds.length === 1 && first !== void 0) return `'${symbolName}' is ${kindWithArticle(first)}`;
518
+ return `every definition of '${symbolName}' is a type declaration (${kinds.map((k) => `'${k}'`).join(", ")})`;
519
+ }
520
+ function refBlindKindNotice(symbolName, kinds) {
521
+ return `Cannot determine references for '${symbolName}': ${refBlindKindClause(symbolName, kinds)}, and ${REF_BLIND_KIND_REASON}. This is a gap in token-goat's index, not evidence the symbol is unreferenced. Search the source directly instead, e.g. \`rg -n -w ${symbolName}\`.`;
522
+ }
523
+ function refBlindKindPartialNote(symbolName, kinds, blindCount, totalCount) {
524
+ return `Note: ${blindCount} of ${totalCount} definitions of '${symbolName}' (${kinds.map((k) => `'${k}'`).join(", ")}) are not covered by this result -- ${REF_BLIND_KIND_REASON}. The empty result above speaks only for the other ${totalCount - blindCount}; for the rest, search the source directly, e.g. \`rg -n -w ${symbolName}\`.`;
525
+ }
526
+
461
527
  // src/read_commands.ts
462
528
  init_define_import_meta_env();
463
529
  import * as fs4 from "node:fs";
@@ -3762,6 +3828,14 @@ function parseGithubRepoFromRemoteUrl(url) {
3762
3828
  if (https?.[1] !== void 0) return https[1];
3763
3829
  return null;
3764
3830
  }
3831
+ function isSafeRepoSlug(repo) {
3832
+ const parts = repo.split("/");
3833
+ if (parts.length !== 2) return false;
3834
+ return parts.every((p) => /^[A-Za-z0-9._-]+$/.test(p) && p !== "." && p !== ".." && !p.startsWith("-"));
3835
+ }
3836
+ function isSafePrNumber(pr) {
3837
+ return /^[0-9]+$/.test(pr);
3838
+ }
3765
3839
  function parsePrSliceArg(raw) {
3766
3840
  if (raw === "files") return { kind: "files" };
3767
3841
  if (raw === "comments") return { kind: "comments" };
@@ -5435,6 +5509,15 @@ function guardJsonRows(items) {
5435
5509
  if (!cfg.overflow_guard.enabled) return { items: [...items], truncated: false, totalCount: items.length };
5436
5510
  return capJsonRows(items, cfg.overflow_guard.max_tokens);
5437
5511
  }
5512
+ function changedDiffBaselineBytes(cwd, ref, files) {
5513
+ if (files.length === 0) return 0;
5514
+ try {
5515
+ const result = runGit(["diff", ref, "--unified=0", "--", ...files], { cwd });
5516
+ if (result.exitCode === 0) return Buffer.byteLength(result.stdout, "utf8");
5517
+ } catch {
5518
+ }
5519
+ return 0;
5520
+ }
5438
5521
  function sumFileSizes(filePaths) {
5439
5522
  let total = 0;
5440
5523
  for (const fp of new Set(filePaths)) {
@@ -5822,9 +5905,9 @@ function truncationFooter(shown, limit, total, plural, flag) {
5822
5905
 
5823
5906
  token-goat: ${notice}`;
5824
5907
  }
5825
- function refsTotal(clientFiltered, filteredTotal, shown, countExact, preScanCount) {
5908
+ function refsTotal(clientFiltered, filteredTotal, shown, countExact, preScanCount, scanLimit) {
5826
5909
  if (!clientFiltered) return { count: countExact(), exact: true };
5827
- return { count: filteredTotal ?? shown, exact: preScanCount < REFS_TOP_SCAN_LIMIT };
5910
+ return { count: filteredTotal ?? shown, exact: preScanCount < scanLimit };
5828
5911
  }
5829
5912
  function truncationNotice(shown, limit, total, plural, flag) {
5830
5913
  if (shown < limit) return null;
@@ -6037,9 +6120,11 @@ function resolveSymbolSpec(spec, forceRefresh, projectRoot) {
6037
6120
  });
6038
6121
  }
6039
6122
  if (methodName !== void 0 && candidates.length > 1) {
6123
+ const containerBaseName = file.slice(Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\")) + 1);
6040
6124
  const containers = querySymbols({
6041
6125
  name: symBase,
6042
6126
  limit: 50,
6127
+ ...containerBaseName !== "" ? { fileBaseName: containerBaseName } : {},
6043
6128
  ...projectRoot !== void 0 ? { rootDir: projectRoot } : {}
6044
6129
  });
6045
6130
  const symBaseLower = symBase.toLowerCase();
@@ -6355,7 +6440,9 @@ function renderRefsTargets(targets, opts, {
6355
6440
  if (rootDir !== void 0) queryOpts.rootDir = rootDir;
6356
6441
  const scanned = queryRefs(queryOpts);
6357
6442
  const preScanCount = scanned.length;
6443
+ const scanLimit = queryOpts.limit ?? DEFAULT_QUERY_LIMIT;
6358
6444
  let results = applyTypedRefsTier(symbol, file, scanned);
6445
+ const typedFilterDropped = results.length < scanned.length;
6359
6446
  let suppressed = 0;
6360
6447
  if (opts.excludeTests === true) {
6361
6448
  const f = applyExcludeTestsFilter(results);
@@ -6365,9 +6452,10 @@ function renderRefsTargets(targets, opts, {
6365
6452
  const preGrepCount = results.length;
6366
6453
  const matchesGrep = refGrepFilter(opts.grep);
6367
6454
  if (matchesGrep !== void 0) results = results.filter(matchesGrep);
6455
+ const clientFiltered = opts.excludeTests === true || matchesGrep !== void 0 || typedFilterDropped;
6368
6456
  let filteredTotal;
6369
- if (opts.excludeTests === true || matchesGrep !== void 0) filteredTotal = results.length;
6370
- if ((opts.excludeTests === true || matchesGrep !== void 0) && opts.top === void 0) {
6457
+ if (clientFiltered) filteredTotal = results.length;
6458
+ if (clientFiltered && opts.top === void 0) {
6371
6459
  results = results.slice(0, opts.limit ?? 100);
6372
6460
  }
6373
6461
  if (results.length > 0) anyFound = true;
@@ -6379,7 +6467,7 @@ function renderRefsTargets(targets, opts, {
6379
6467
  jsonOut[key] = withHidden(topFilesJsonPayload(results, opts.top));
6380
6468
  } else {
6381
6469
  const capped = guardJsonRows(results);
6382
- const trueTotal = opts.excludeTests === true || matchesGrep !== void 0 ? filteredTotal ?? results.length : countRefs(queryOpts);
6470
+ const trueTotal = clientFiltered ? filteredTotal ?? results.length : countRefs(queryOpts);
6383
6471
  jsonOut[key] = withHidden({ items: refsJsonItems(capped.items, opts.context ?? 0), truncated: capped.truncated || trueTotal > results.length, totalCount: trueTotal });
6384
6472
  }
6385
6473
  continue;
@@ -6406,7 +6494,7 @@ function renderRefsTargets(targets, opts, {
6406
6494
  const notice = truncationNotice(
6407
6495
  results.length,
6408
6496
  opts.limit ?? 100,
6409
- () => refsTotal(opts.excludeTests === true || matchesGrep !== void 0, filteredTotal, results.length, () => countRefs(queryOpts), preScanCount),
6497
+ () => refsTotal(clientFiltered, filteredTotal, results.length, () => countRefs(queryOpts), preScanCount, scanLimit),
6410
6498
  "references",
6411
6499
  "--limit"
6412
6500
  );
@@ -6482,7 +6570,9 @@ function runRefsSingle(opts) {
6482
6570
  if (rootDir !== void 0) queryOpts.rootDir = rootDir;
6483
6571
  const scanned = queryRefs(queryOpts);
6484
6572
  const preScanCount = scanned.length;
6573
+ const scanLimit = queryOpts.limit ?? DEFAULT_QUERY_LIMIT;
6485
6574
  let results = applyTypedRefsTier(symName, defFileHint, scanned);
6575
+ const typedFilterDropped = results.length < scanned.length;
6486
6576
  let suppressed = 0;
6487
6577
  if (opts.excludeTests === true) {
6488
6578
  const f = applyExcludeTestsFilter(results);
@@ -6492,9 +6582,10 @@ function runRefsSingle(opts) {
6492
6582
  const preGrepCount = results.length;
6493
6583
  const matchesGrep = refGrepFilter(opts.grep);
6494
6584
  if (matchesGrep !== void 0) results = results.filter(matchesGrep);
6585
+ const clientFiltered = opts.excludeTests === true || matchesGrep !== void 0 || typedFilterDropped;
6495
6586
  let filteredTotal;
6496
- if (opts.excludeTests === true || matchesGrep !== void 0) filteredTotal = results.length;
6497
- if ((opts.excludeTests === true || matchesGrep !== void 0) && opts.top === void 0) {
6587
+ if (clientFiltered) filteredTotal = results.length;
6588
+ if (clientFiltered && opts.top === void 0) {
6498
6589
  results = results.slice(0, opts.limit ?? 100);
6499
6590
  }
6500
6591
  if (results.length === 0) {
@@ -6511,12 +6602,26 @@ function runRefsSingle(opts) {
6511
6602
  return 1;
6512
6603
  }
6513
6604
  const rootDir2 = opts.projectRoot ?? resolveProjectRoot({ project: process.cwd() });
6514
- if (querySymbols({ name: symName, rootDir: rootDir2, limit: 1 }).length === 0) {
6605
+ const defRows = querySymbols({ name: symName, rootDir: rootDir2, limit: REF_BLIND_DEF_PROBE_LIMIT });
6606
+ if (defRows.length === 0) {
6515
6607
  emitErr(`Symbol not found: ${symName}${unknownSymbolSuggestion(symName, rootDir2)}`);
6516
6608
  if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir2)) emitErr(emptyIndexMessage(rootDir2));
6517
6609
  return 1;
6518
6610
  }
6611
+ const defPaths = defFileHint !== void 0 ? [defFileHint] : defRows.map((r) => r.filePath);
6612
+ const firstDefPath = defPaths[0];
6613
+ if (firstDefPath !== void 0 && defPaths.every((fp) => !isRefIndexedFile(fp))) {
6614
+ emitErr(refBlindLanguageNotice(symName, detectLanguage(firstDefPath), refsDisplayPath(firstDefPath)));
6615
+ return 1;
6616
+ }
6617
+ const kindRows = defFileHint !== void 0 ? querySymbols({ name: symName, filePath: defFileHint, rootDir: rootDir2, limit: REF_BLIND_DEF_PROBE_LIMIT }) : defRows;
6618
+ const kindVerdict = refBlindKindVerdict(kindRows);
6619
+ if (kindVerdict.allBlind) {
6620
+ emitErr(refBlindKindNotice(symName, kindVerdict.blindKinds));
6621
+ return 1;
6622
+ }
6519
6623
  emitErr(`No references found for '${symName}'`);
6624
+ if (kindVerdict.blindCount > 0) emitErr(refBlindKindPartialNote(symName, kindVerdict.blindKinds, kindVerdict.blindCount, kindRows.length));
6520
6625
  if (opts.json !== true) {
6521
6626
  if (isIndexEmptyForProject(globalDbPath(), rootDir2)) emitErr(emptyIndexMessage(rootDir2));
6522
6627
  }
@@ -6529,7 +6634,7 @@ function runRefsSingle(opts) {
6529
6634
  payload = topFilesJsonPayload(results, opts.top);
6530
6635
  } else {
6531
6636
  const capped = guardJsonRows(results);
6532
- const trueTotal = opts.excludeTests === true || matchesGrep !== void 0 ? filteredTotal ?? results.length : countRefs(queryOpts);
6637
+ const trueTotal = clientFiltered ? filteredTotal ?? results.length : countRefs(queryOpts);
6533
6638
  payload = { items: refsJsonItems(capped.items, opts.context ?? 0), truncated: capped.truncated || trueTotal > results.length, totalCount: trueTotal };
6534
6639
  }
6535
6640
  const hiddenByGrep = matchesGrep !== void 0 ? preGrepCount - (filteredTotal ?? results.length) : 0;
@@ -6539,7 +6644,7 @@ function runRefsSingle(opts) {
6539
6644
  return 0;
6540
6645
  }
6541
6646
  const lines = 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((ref) => renderRefLines(ref, opts.context ?? 0, ""))];
6542
- const refsFooter = opts.top !== void 0 ? "" : truncationFooter(results.length, opts.limit ?? 100, () => refsTotal(opts.excludeTests === true || matchesGrep !== void 0, filteredTotal, results.length, () => countRefs(queryOpts), preScanCount), "references", "--limit");
6647
+ const refsFooter = opts.top !== void 0 ? "" : truncationFooter(results.length, opts.limit ?? 100, () => refsTotal(clientFiltered, filteredTotal, results.length, () => countRefs(queryOpts), preScanCount, scanLimit), "references", "--limit");
6543
6648
  const text = lines.join("\n");
6544
6649
  emit(guardText(text, "symbol") + refsFooter);
6545
6650
  recordReadStat("symbol_read", fullSourceBytes, text + refsFooter, symName);
@@ -6726,7 +6831,23 @@ function runSkeleton(opts) {
6726
6831
  return { text, code: 0 };
6727
6832
  }
6728
6833
  var DOC_SUMMARY_MAX_CHARS = 140;
6834
+ function firstSentenceEnd(line) {
6835
+ const MIN_SENTENCE_CHARS = 30;
6836
+ const ABBREV = new RegExp("(?:\\b(?:e\\.g|i\\.e|vs|cf|etc|approx|al|Dr|Mr|Ms|St|Fig|No)\\.|\\b\\p{L}\\.)$", "u");
6837
+ for (const m of line.matchAll(/[.!?](?=\s|$)/gu)) {
6838
+ const end = m.index + 1;
6839
+ if (end < MIN_SENTENCE_CHARS) continue;
6840
+ const head = line.slice(0, end);
6841
+ if (ABBREV.test(head)) continue;
6842
+ return end;
6843
+ }
6844
+ return null;
6845
+ }
6729
6846
  function clipDocSummary(firstLine) {
6847
+ const sentence = firstSentenceEnd(firstLine);
6848
+ if (sentence !== null && sentence <= DOC_SUMMARY_MAX_CHARS) {
6849
+ return sentence === firstLine.length ? firstLine : `${firstLine.slice(0, sentence)}\u2026`;
6850
+ }
6730
6851
  if (firstLine.length <= DOC_SUMMARY_MAX_CHARS) return firstLine;
6731
6852
  const cut = firstLine.lastIndexOf(" ", DOC_SUMMARY_MAX_CHARS);
6732
6853
  return `${firstLine.slice(0, cut > 40 ? cut : DOC_SUMMARY_MAX_CHARS).trimEnd()}\u2026`;
@@ -7259,6 +7380,14 @@ function runPrSlice(opts) {
7259
7380
  }
7260
7381
  repo = resolved;
7261
7382
  }
7383
+ if (!isSafeRepoSlug(repo)) {
7384
+ emitErr(`"${repo}" is not a plain owner/name repository slug -- pass --repo owner/repo`);
7385
+ return 1;
7386
+ }
7387
+ if (!isSafePrNumber(opts.pr)) {
7388
+ emitErr(`"${opts.pr}" is not a pull request number`);
7389
+ return 1;
7390
+ }
7262
7391
  if (!isGhAuthenticated()) {
7263
7392
  emitErr("gh is not authenticated -- run `gh auth login`");
7264
7393
  return 1;
@@ -7930,10 +8059,12 @@ function runChanged(opts = {}) {
7930
8059
  }
7931
8060
  if (opts.symbolMode === true) {
7932
8061
  let hunksByFile = /* @__PURE__ */ new Map();
8062
+ let symbolDiffBaselineBytes = 0;
7933
8063
  try {
7934
- const diffResult = runGit(["diff", ref, "--unified=0"], { cwd });
8064
+ const diffResult = runGit(["diff", ref, "--unified=0", "--", ...changedFiles], { cwd });
7935
8065
  if (diffResult.exitCode === 0) {
7936
8066
  hunksByFile = parseDiffHunks(diffResult.stdout);
8067
+ symbolDiffBaselineBytes = Buffer.byteLength(diffResult.stdout, "utf8");
7937
8068
  }
7938
8069
  } catch {
7939
8070
  }
@@ -7949,7 +8080,7 @@ function runChanged(opts = {}) {
7949
8080
  emit("No symbols changed.");
7950
8081
  return 0;
7951
8082
  }
7952
- const symbolFullBytes = sumFileSizes(changedFiles.map((f) => resolveIndexPath(f, projectRoot)));
8083
+ const symbolFullBytes = symbolDiffBaselineBytes;
7953
8084
  if (opts.json === true) {
7954
8085
  const capped = guardJsonRows(allSymbols);
7955
8086
  const text = JSON.stringify({ items: capped.items, truncated: capped.truncated, totalCount: capped.totalCount }, null, 2);
@@ -7964,7 +8095,7 @@ function runChanged(opts = {}) {
7964
8095
  recordReadStat("changed_lookup", symbolFullBytes, symbolText, ref);
7965
8096
  return 0;
7966
8097
  }
7967
- const fullBytes = sumFileSizes(changedFiles.map((f) => resolveIndexPath(f, projectRoot)));
8098
+ const fullBytes = changedDiffBaselineBytes(cwd, ref, changedFiles);
7968
8099
  if (opts.json === true) {
7969
8100
  const capped = guardJsonRows(changedFiles);
7970
8101
  const text = JSON.stringify({ items: capped.items, truncated: capped.truncated, totalCount: capped.totalCount }, null, 2);
@@ -9701,12 +9832,26 @@ function runCallers(opts) {
9701
9832
  emitErr2(`No non-test references found for '${opts.symbol}' (${excludeTestsHiddenNote(suppressed)})`);
9702
9833
  return 1;
9703
9834
  }
9704
- if (querySymbols({ name, rootDir, limit: 1 }).length === 0) {
9835
+ const defRows = querySymbols({ name, rootDir, limit: REF_BLIND_DEF_PROBE_LIMIT });
9836
+ if (defRows.length === 0) {
9705
9837
  emitErr2(`Symbol not found: ${opts.symbol}${unknownSymbolSuggestion(name, rootDir)}`);
9706
9838
  if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr2(emptyIndexMessage(rootDir));
9707
9839
  return 1;
9708
9840
  }
9841
+ const defPaths = fileHint !== void 0 ? [fileHint] : defRows.map((r) => r.filePath);
9842
+ const firstDefPath = defPaths[0];
9843
+ if (firstDefPath !== void 0 && defPaths.every((fp) => !isRefIndexedFile(fp))) {
9844
+ emitErr2(refBlindLanguageNotice(name, detectLanguage(firstDefPath), toDisplayPath(rootDir, firstDefPath)));
9845
+ return 1;
9846
+ }
9847
+ const kindRows = fileHint !== void 0 ? querySymbols({ name, filePath: fileHint, limit: REF_BLIND_DEF_PROBE_LIMIT }) : defRows;
9848
+ const kindVerdict = refBlindKindVerdict(kindRows);
9849
+ if (kindVerdict.allBlind) {
9850
+ emitErr2(refBlindKindNotice(name, kindVerdict.blindKinds));
9851
+ return 1;
9852
+ }
9709
9853
  emitErr2(`No references found for '${opts.symbol}'`);
9854
+ if (kindVerdict.blindCount > 0) emitErr2(refBlindKindPartialNote(name, kindVerdict.blindKinds, kindVerdict.blindCount, kindRows.length));
9710
9855
  if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr2(emptyIndexMessage(rootDir));
9711
9856
  return 1;
9712
9857
  }
@@ -9754,6 +9899,14 @@ function runCallChain(opts) {
9754
9899
  if (opts.json !== true && isIndexEmptyForProject(globalDbPath(), rootDir)) emitErr2(emptyIndexMessage(rootDir));
9755
9900
  return 1;
9756
9901
  }
9902
+ const refBlindRootPath = () => {
9903
+ const paths = fileHint !== void 0 ? [fileHint] : querySymbols({ name, rootDir, limit: REF_BLIND_DEF_PROBE_LIMIT }).map((r) => r.filePath);
9904
+ return paths.length > 0 && paths.every((fp) => !isRefIndexedFile(fp)) ? paths[0] : void 0;
9905
+ };
9906
+ const refBlindRootKinds = () => {
9907
+ const rows = fileHint !== void 0 ? querySymbols({ name, filePath: fileHint, limit: REF_BLIND_DEF_PROBE_LIMIT }) : querySymbols({ name, rootDir, limit: REF_BLIND_DEF_PROBE_LIMIT });
9908
+ return { ...refBlindKindVerdict(rows), total: rows.length };
9909
+ };
9757
9910
  const getSyms = buildFileSymCache();
9758
9911
  let suppressedCount = 0;
9759
9912
  const callersOf = (n) => {
@@ -9778,7 +9931,10 @@ function runCallChain(opts) {
9778
9931
  if (opts.json === true) {
9779
9932
  const hiddenByGrep = chains.length - filteredChains.length;
9780
9933
  const hiddenByExcludeTests = noCallers && opts.excludeTests === true ? suppressedCount : 0;
9781
- emit2(JSON.stringify({ chains: filteredChains, ...hiddenByGrep > 0 ? { hiddenByGrep } : {}, ...hiddenByExcludeTests > 0 ? { hiddenByExcludeTests } : {} }, null, 2));
9934
+ const refBlindKinds = noCallers ? refBlindRootKinds().blindKinds : [];
9935
+ const blindRootPath = noCallers ? refBlindRootPath() : void 0;
9936
+ const refBlindLanguage = blindRootPath !== void 0 ? { language: detectLanguage(blindRootPath), definedIn: toDisplayPath(rootDir, blindRootPath) } : void 0;
9937
+ emit2(JSON.stringify({ chains: filteredChains, ...hiddenByGrep > 0 ? { hiddenByGrep } : {}, ...hiddenByExcludeTests > 0 ? { hiddenByExcludeTests } : {}, ...refBlindKinds.length > 0 ? { refBlindKinds } : {}, ...refBlindLanguage !== void 0 ? { refBlindLanguage } : {} }, null, 2));
9782
9938
  return 0;
9783
9939
  }
9784
9940
  if (noCallers) {
@@ -9786,7 +9942,20 @@ function runCallChain(opts) {
9786
9942
  emit2(`${name} (no non-test callers; ${excludeTestsHiddenNote(suppressedCount)})`);
9787
9943
  return 0;
9788
9944
  }
9945
+ const blindRoot = refBlindRootPath();
9946
+ if (blindRoot !== void 0) {
9947
+ emitErr2(refBlindLanguageNotice(name, detectLanguage(blindRoot), toDisplayPath(rootDir, blindRoot)));
9948
+ emit2(`${name} (no callers recorded)`);
9949
+ return 0;
9950
+ }
9951
+ const rootKinds = refBlindRootKinds();
9952
+ if (rootKinds.allBlind) {
9953
+ emitErr2(refBlindKindNotice(name, rootKinds.blindKinds));
9954
+ emit2(`${name} (no callers recorded)`);
9955
+ return 0;
9956
+ }
9789
9957
  emit2(`${name} (no callers)`);
9958
+ if (rootKinds.blindCount > 0) emitErr2(refBlindKindPartialNote(name, rootKinds.blindKinds, rootKinds.blindCount, rootKinds.total));
9790
9959
  return 0;
9791
9960
  }
9792
9961
  if (matchesGrep !== void 0 && filteredChains.length === 0) {
@@ -9881,11 +10050,25 @@ function runImpact(opts) {
9881
10050
  emitErr2(`No non-test impact found for '${opts.symbol}' (${excludeTestsHiddenNote(suppressedCount)})`);
9882
10051
  return 1;
9883
10052
  }
9884
- if (querySymbols({ name: rootName, rootDir, limit: 1 }).length === 0) {
10053
+ const defRows = querySymbols({ name: rootName, rootDir, limit: REF_BLIND_DEF_PROBE_LIMIT });
10054
+ if (defRows.length === 0) {
9885
10055
  emitErr2(`Symbol not found: ${opts.symbol}${unknownSymbolSuggestion(rootName, rootDir)}`);
9886
10056
  return 1;
9887
10057
  }
10058
+ const defPaths = fileHint !== void 0 ? [fileHint] : defRows.map((r) => r.filePath);
10059
+ const firstDefPath = defPaths[0];
10060
+ if (firstDefPath !== void 0 && defPaths.every((fp) => !isRefIndexedFile(fp))) {
10061
+ emitErr2(refBlindLanguageNotice(rootName, detectLanguage(firstDefPath), toDisplayPath(rootDir, firstDefPath)));
10062
+ return 1;
10063
+ }
10064
+ const kindRows = fileHint !== void 0 ? querySymbols({ name: rootName, filePath: fileHint, limit: REF_BLIND_DEF_PROBE_LIMIT }) : defRows;
10065
+ const kindVerdict = refBlindKindVerdict(kindRows);
10066
+ if (kindVerdict.allBlind) {
10067
+ emitErr2(refBlindKindNotice(rootName, kindVerdict.blindKinds));
10068
+ return 1;
10069
+ }
9888
10070
  emitErr2(`No callers found for '${opts.symbol}'`);
10071
+ if (kindVerdict.blindCount > 0) emitErr2(refBlindKindPartialNote(rootName, kindVerdict.blindKinds, kindVerdict.blindCount, kindRows.length));
9889
10072
  return 1;
9890
10073
  }
9891
10074
  if (opts.json === true) {
@@ -9918,7 +10101,10 @@ function hasAncestorDispatchRef(methodName, scopeName, classFile, rootDir) {
9918
10101
  const baseSyms = querySymbols({ name: baseName, kind: "class", limit: 1, rootDir });
9919
10102
  const baseSym = baseSyms[0];
9920
10103
  if (baseSym === void 0) return false;
9921
- const baseRefs = queryRefs({ name: methodName, filePath: baseSym.filePath, limit: DEFAULT_REF_QUERY_LIMIT, rootDir });
10104
+ let baseRefs = queryRefs({ name: methodName, filePath: baseSym.filePath, limit: DEFAULT_REF_QUERY_LIMIT, rootDir });
10105
+ if (baseRefs.length >= DEFAULT_REF_QUERY_LIMIT && !baseRefs.some((ref) => ref.line >= baseSym.lineStart && ref.line <= baseSym.lineEnd)) {
10106
+ baseRefs = queryRefs({ name: methodName, filePath: baseSym.filePath, limit: UNBOUNDED_REF_LIMIT, rootDir });
10107
+ }
9922
10108
  if (baseRefs.some((ref) => ref.line >= baseSym.lineStart && ref.line <= baseSym.lineEnd)) return true;
9923
10109
  currentName = baseName;
9924
10110
  currentFile = baseSym.filePath;
@@ -9992,11 +10178,26 @@ function runDead(opts) {
9992
10178
  }
9993
10179
  return 1;
9994
10180
  }
9995
- const syms = kinds.flatMap((k) => querySymbols({ kind: k, limit: UNBOUNDED_REF_LIMIT, rootDir }));
10181
+ const blindKinds = kinds.filter((k) => REF_BLIND_KINDS.includes(k));
10182
+ const assessableKinds = kinds.filter((k) => !REF_BLIND_KINDS.includes(k));
10183
+ if (blindKinds.length > 0 && assessableKinds.length === 0) {
10184
+ const blindLabel = blindKinds.length === 1 ? "kind" : "kinds";
10185
+ emitErr2(`Cannot assess deadness for ${blindLabel}: ${blindKinds.map((k) => `'${k}'`).join(", ")} -- ${REF_BLIND_KIND_REASON}.`);
10186
+ emitErr2(`Every symbol of ${blindKinds.length === 1 ? "this kind" : "these kinds"} would be reported dead, so no result is emitted rather than a wrong one. To hunt unused type declarations, list them with 'token-goat types --json' and search the source for each name directly.`);
10187
+ return 1;
10188
+ }
10189
+ const blindKindNote = blindKinds.length > 0 ? `Note: ${blindKinds.map((k) => `'${k}'`).join(", ")} excluded -- ${REF_BLIND_KIND_REASON}.` : void 0;
10190
+ if (blindKindNote !== void 0 && opts.json !== true) emitErr2(blindKindNote);
10191
+ const syms = assessableKinds.flatMap((k) => querySymbols({ kind: k, limit: UNBOUNDED_REF_LIMIT, rootDir }));
9996
10192
  const getSyms = buildFileSymCache();
9997
10193
  const results = [];
9998
10194
  let suppressed = 0;
10195
+ let refBlindByLanguage = 0;
9999
10196
  for (const sym of syms) {
10197
+ if (!isRefIndexedFile(sym.filePath)) {
10198
+ refBlindByLanguage += 1;
10199
+ continue;
10200
+ }
10000
10201
  if (opts.includePrivate !== true && sym.name.startsWith("_")) continue;
10001
10202
  const refs = queryRefs({ name: sym.name, limit: DEFAULT_REF_QUERY_LIMIT, rootDir });
10002
10203
  let scoped = filterRefsForSymbol(refs, sym.name, sym.filePath, getSyms);
@@ -10014,6 +10215,9 @@ function runDead(opts) {
10014
10215
  }
10015
10216
  results.push({ name: sym.name, kind: sym.kind, file: sym.filePath, line: sym.lineStart });
10016
10217
  }
10218
+ if (refBlindByLanguage > 0 && opts.json !== true) {
10219
+ emitErr2(`Note: ${countNoun(refBlindByLanguage, "symbol")} skipped -- defined in a language whose call sites token-goat does not index, so deadness cannot be determined for them.`);
10220
+ }
10017
10221
  const preGrepCount = results.length;
10018
10222
  const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
10019
10223
  const grepped = matchesGrep !== void 0 ? results.filter((r) => matchesGrep(r.name)) : results;
@@ -10025,7 +10229,7 @@ function runDead(opts) {
10025
10229
  }));
10026
10230
  const topTruncated = sliced.length < grepped.length;
10027
10231
  const hiddenByGrep = preGrepCount - grepped.length;
10028
- emit2(JSON.stringify({ items: capped.items, truncated: capped.truncated || topTruncated, totalCount: grepped.length, ...hiddenByGrep > 0 ? { hiddenByGrep } : {}, ...opts.excludeTests === true && suppressed > 0 ? { hiddenByExcludeTests: suppressed } : {} }, null, 2));
10232
+ emit2(JSON.stringify({ items: capped.items, truncated: capped.truncated || topTruncated, totalCount: grepped.length, ...hiddenByGrep > 0 ? { hiddenByGrep } : {}, ...opts.excludeTests === true && suppressed > 0 ? { hiddenByExcludeTests: suppressed } : {}, ...blindKinds.length > 0 ? { excludedKinds: blindKinds, excludedKindsReason: REF_BLIND_KIND_REASON } : {}, ...refBlindByLanguage > 0 ? { unassessableByLanguage: refBlindByLanguage } : {} }, null, 2));
10029
10233
  return 0;
10030
10234
  }
10031
10235
  if (sliced.length === 0) {
@@ -10220,6 +10424,15 @@ var TYPE_KINDS = [
10220
10424
  // Kotlin/Scala object.
10221
10425
  "graphql_extend"
10222
10426
  ];
10427
+ var REF_BLIND_KINDS = [.../* @__PURE__ */ new Set([...TYPE_KINDS, "impl"])];
10428
+ function refBlindKindVerdict(rows) {
10429
+ const blind = rows.filter((r) => REF_BLIND_KINDS.includes(r.kind));
10430
+ return {
10431
+ blindKinds: [...new Set(blind.map((r) => r.kind))],
10432
+ blindCount: blind.length,
10433
+ allBlind: rows.length > 0 && blind.length === rows.length
10434
+ };
10435
+ }
10223
10436
  var CORE_SYMBOL_KINDS = [
10224
10437
  .../* @__PURE__ */ new Set([...GENERIC_SYMBOL_KINDS, ...TYPE_KINDS, ...OTHER_ADAPTER_SYMBOL_KINDS])
10225
10438
  ];
@@ -10720,16 +10933,11 @@ function runAsk(opts) {
10720
10933
  return degrade(`${BACKEND_ENV}=${backendLabel} is set, but no indexed symbol matched this question, so there is no context to answer from -- try different wording or token-goat semantic`);
10721
10934
  }
10722
10935
  const isWin = process.platform === "win32";
10723
- let backendPath = null;
10724
- try {
10725
- const whichOut = execFileSync(isWin ? "where.exe" : "which", [backendLabel], { encoding: "utf8" });
10726
- const found = (whichOut ?? "").trim().split("\n")[0]?.trim() ?? "";
10727
- if (found) backendPath = found;
10728
- } catch {
10729
- }
10936
+ const backendPath = resolveOnPath(backendLabel);
10730
10937
  if (!backendPath) return degrade(`${BACKEND_ENV}=${backendLabel} is set, but '${backendLabel}' was not found on PATH`);
10731
- const context = hits.map((h, i) => `[${i + 1}] ${h.filePath}
10938
+ const rawContext = hits.map((h, i) => `[${i + 1}] ${h.filePath}
10732
10939
  ${h.body ?? ""}`).join("\n\n");
10940
+ const context = fenceUntrustedFileContent(redactSecrets(rawContext).text);
10733
10941
  const prompt = `Answer the QUESTION using only the CODE SNIPPETS below.
10734
10942
  QUESTION: ${opts.question}
10735
10943
 
@@ -9,7 +9,7 @@ import {
9
9
  isBlobStale,
10
10
  loadBlob,
11
11
  storeBlob
12
- } from "./token-goat-chunk-CBO45DYZ.mjs";
12
+ } from "./token-goat-chunk-3HJQR4OO.mjs";
13
13
  import {
14
14
  SYMBOL_BODY_CHAR_CAP,
15
15
  copilotCliMcpToolsDir,
@@ -24,7 +24,7 @@ import {
24
24
  resolveIndexPath,
25
25
  shortFingerprint,
26
26
  toDisplayPath
27
- } from "./token-goat-chunk-3ZR4NLB3.mjs";
27
+ } from "./token-goat-chunk-T2OE7MYM.mjs";
28
28
  import {
29
29
  registerReset
30
30
  } from "./token-goat-chunk-EEIDFMEM.mjs";
@@ -25,7 +25,7 @@ import {
25
25
  runSkeleton,
26
26
  runSymbol,
27
27
  withPinnedReads
28
- } from "./token-goat-chunk-US57I7GN.mjs";
28
+ } from "./token-goat-chunk-46VKOCUH.mjs";
29
29
  import {
30
30
  buildProjectMap,
31
31
  embeddingsDepsAvailable,
@@ -34,7 +34,7 @@ import {
34
34
  getProjectIndexCounts,
35
35
  isWorkerRunning,
36
36
  mapLookupBytesSaved
37
- } from "./token-goat-chunk-CBO45DYZ.mjs";
37
+ } from "./token-goat-chunk-3HJQR4OO.mjs";
38
38
  import {
39
39
  ENV_KEYS,
40
40
  VERSION,
@@ -48,7 +48,7 @@ import {
48
48
  recordStat,
49
49
  resolveProjectRoot,
50
50
  savedTokensFromBytes
51
- } from "./token-goat-chunk-3ZR4NLB3.mjs";
51
+ } from "./token-goat-chunk-T2OE7MYM.mjs";
52
52
  import "./token-goat-chunk-EEIDFMEM.mjs";
53
53
  import {
54
54
  init_define_import_meta_env