token-goat 2.6.28 → 2.6.29

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.
@@ -985,7 +985,7 @@ var require_command = __commonJS({
985
985
  init_define_import_meta_env();
986
986
  var EventEmitter = __require("node:events").EventEmitter;
987
987
  var childProcess = __require("node:child_process");
988
- var path69 = __require("node:path");
988
+ var path70 = __require("node:path");
989
989
  var fs61 = __require("node:fs");
990
990
  var process4 = __require("node:process");
991
991
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -1918,9 +1918,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
1918
1918
  let launchWithNode = false;
1919
1919
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1920
1920
  function findFile(baseDir, baseName) {
1921
- const localBin = path69.resolve(baseDir, baseName);
1921
+ const localBin = path70.resolve(baseDir, baseName);
1922
1922
  if (fs61.existsSync(localBin)) return localBin;
1923
- if (sourceExt.includes(path69.extname(baseName))) return void 0;
1923
+ if (sourceExt.includes(path70.extname(baseName))) return void 0;
1924
1924
  const foundExt = sourceExt.find(
1925
1925
  (ext2) => fs61.existsSync(`${localBin}${ext2}`)
1926
1926
  );
@@ -1938,17 +1938,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
1938
1938
  } catch (err2) {
1939
1939
  resolvedScriptPath = this._scriptPath;
1940
1940
  }
1941
- executableDir = path69.resolve(
1942
- path69.dirname(resolvedScriptPath),
1941
+ executableDir = path70.resolve(
1942
+ path70.dirname(resolvedScriptPath),
1943
1943
  executableDir
1944
1944
  );
1945
1945
  }
1946
1946
  if (executableDir) {
1947
1947
  let localFile = findFile(executableDir, executableFile);
1948
1948
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1949
- const legacyName = path69.basename(
1949
+ const legacyName = path70.basename(
1950
1950
  this._scriptPath,
1951
- path69.extname(this._scriptPath)
1951
+ path70.extname(this._scriptPath)
1952
1952
  );
1953
1953
  if (legacyName !== this._name) {
1954
1954
  localFile = findFile(
@@ -1959,7 +1959,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1959
1959
  }
1960
1960
  executableFile = localFile || executableFile;
1961
1961
  }
1962
- launchWithNode = sourceExt.includes(path69.extname(executableFile));
1962
+ launchWithNode = sourceExt.includes(path70.extname(executableFile));
1963
1963
  let proc;
1964
1964
  if (process4.platform !== "win32") {
1965
1965
  if (launchWithNode) {
@@ -2799,7 +2799,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2799
2799
  * @return {Command}
2800
2800
  */
2801
2801
  nameFromFilename(filename) {
2802
- this._name = path69.basename(filename, path69.extname(filename));
2802
+ this._name = path70.basename(filename, path70.extname(filename));
2803
2803
  return this;
2804
2804
  }
2805
2805
  /**
@@ -2813,9 +2813,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2813
2813
  * @param {string} [path]
2814
2814
  * @return {(string|null|Command)}
2815
2815
  */
2816
- executableDir(path70) {
2817
- if (path70 === void 0) return this._executableDir;
2818
- this._executableDir = path70;
2816
+ executableDir(path71) {
2817
+ if (path71 === void 0) return this._executableDir;
2818
+ this._executableDir = path71;
2819
2819
  return this;
2820
2820
  }
2821
2821
  /**
@@ -3050,7 +3050,7 @@ var require_commander = __commonJS({
3050
3050
  import { createRequire } from "node:module";
3051
3051
  function resolveVersion() {
3052
3052
  if (true) {
3053
- return "2.6.28";
3053
+ return "2.6.29";
3054
3054
  }
3055
3055
  const require2 = createRequire(import.meta.url);
3056
3056
  const pkg = require2("../package.json");
@@ -4176,6 +4176,12 @@ function envInt(key, defaultVal, min, max) {
4176
4176
  if (max !== void 0) clamped = Math.min(max, clamped);
4177
4177
  return clamped;
4178
4178
  }
4179
+ function envStrList(key, defaultVal, delimiter3) {
4180
+ const raw = process.env[key];
4181
+ if (raw === void 0) return defaultVal;
4182
+ const entries = raw.split(delimiter3).map((s) => s.trim()).filter((s) => s !== "");
4183
+ return entries.length > 0 ? entries : defaultVal;
4184
+ }
4179
4185
  var FALSY_ENV_VALUES, TRUTHY_ENV_VALUES;
4180
4186
  var init_env = __esm({
4181
4187
  "src/env.ts"() {
@@ -5159,6 +5165,7 @@ var init_project = __esm({
5159
5165
 
5160
5166
  // src/config.ts
5161
5167
  import * as fs4 from "node:fs";
5168
+ import * as path5 from "node:path";
5162
5169
  function getDefaultConfig(section2) {
5163
5170
  return structuredClone(CONFIG_DEFAULTS[section2] ?? {});
5164
5171
  }
@@ -5727,6 +5734,8 @@ function _buildConfig(raw, projectRaw = {}) {
5727
5734
  const mcp = getDefaultConfig("mcp");
5728
5735
  mcp.confine_reads_to_project_root = validatedBool(mcp_raw["confine_reads_to_project_root"], mcp.confine_reads_to_project_root);
5729
5736
  mcp.confine_reads_to_project_root = envBool("TOKEN_GOAT_MCP_CONFINE_READS", mcp.confine_reads_to_project_root);
5737
+ mcp.allowed_roots = validatedStrList(mcp_raw["allowed_roots"], mcp.allowed_roots);
5738
+ mcp.allowed_roots = envStrList("TOKEN_GOAT_MCP_ALLOWED_ROOTS", mcp.allowed_roots, path5.delimiter);
5730
5739
  const hs_raw = section(raw, "hint_stats");
5731
5740
  const hs = getDefaultConfig("hint_stats");
5732
5741
  hs.suppress_threshold_pct = validatedInt(hs_raw["suppress_threshold_pct"], hs.suppress_threshold_pct, ...boundsOf("hint_stats.suppress_threshold_pct"));
@@ -6115,7 +6124,8 @@ var init_config = __esm({
6115
6124
  enabled: true
6116
6125
  },
6117
6126
  mcp: {
6118
- confine_reads_to_project_root: true
6127
+ confine_reads_to_project_root: true,
6128
+ allowed_roots: []
6119
6129
  },
6120
6130
  hint_stats: {
6121
6131
  suppress_threshold_pct: 15,
@@ -6304,6 +6314,7 @@ var init_config = __esm({
6304
6314
  "context.model_window_tokens": ["TOKEN_GOAT_MODEL_WINDOW_TOKENS"],
6305
6315
  "injection.enabled": ["TOKEN_GOAT_INJECTION_ENABLED"],
6306
6316
  "mcp.confine_reads_to_project_root": ["TOKEN_GOAT_MCP_CONFINE_READS"],
6317
+ "mcp.allowed_roots": ["TOKEN_GOAT_MCP_ALLOWED_ROOTS"],
6307
6318
  "indexing.embeddings_enabled": ["TOKEN_GOAT_EMBEDDINGS_ENABLED"]
6308
6319
  };
6309
6320
  }
@@ -6312,7 +6323,7 @@ var init_config = __esm({
6312
6323
  // src/db.ts
6313
6324
  import * as fs5 from "node:fs";
6314
6325
  import { createRequire as createRequire2 } from "node:module";
6315
- import * as path5 from "node:path";
6326
+ import * as path6 from "node:path";
6316
6327
  import Database from "better-sqlite3";
6317
6328
  function alterTableIdempotent(conn, sql) {
6318
6329
  try {
@@ -6365,8 +6376,8 @@ function initConnection(conn) {
6365
6376
  }
6366
6377
  }
6367
6378
  function resolveDbPath(dbPath) {
6368
- if (path5.isAbsolute(dbPath)) return dbPath;
6369
- if (dbPath.includes("/") || dbPath.includes("\\")) return path5.resolve(dbPath);
6379
+ if (path6.isAbsolute(dbPath)) return dbPath;
6380
+ if (dbPath.includes("/") || dbPath.includes("\\")) return path6.resolve(dbPath);
6370
6381
  return safeJoin(dataDir(), dbPath);
6371
6382
  }
6372
6383
  function connectionKey(dbPath) {
@@ -6377,7 +6388,7 @@ function getDb(dbPath) {
6377
6388
  const { resolved, key } = connectionKey(dbPath);
6378
6389
  const existing = _connections.get(key);
6379
6390
  if (existing !== void 0) return existing;
6380
- const dir = path5.dirname(resolved);
6391
+ const dir = path6.dirname(resolved);
6381
6392
  try {
6382
6393
  fs5.mkdirSync(dir, { recursive: true });
6383
6394
  } catch (e) {
@@ -6667,20 +6678,20 @@ END;
6667
6678
  });
6668
6679
 
6669
6680
  // src/parser_types.ts
6670
- import * as path6 from "node:path";
6681
+ import * as path7 from "node:path";
6671
6682
  function detectLanguage(filePath) {
6672
- const base = path6.basename(filePath).toLowerCase();
6683
+ const base = path7.basename(filePath).toLowerCase();
6673
6684
  if (DOTENV_VARIANT_RE.test(base)) return "env_file";
6674
6685
  const byName = FILENAME_LANGUAGE.get(base);
6675
6686
  if (byName !== void 0) return byName;
6676
6687
  if (base.endsWith("-meta.xml")) {
6677
6688
  return "salesforce_metadata";
6678
6689
  }
6679
- const ext2 = path6.extname(base).toLowerCase();
6690
+ const ext2 = path7.extname(base).toLowerCase();
6680
6691
  return EXTENSION_LANGUAGE.get(ext2) ?? "unknown";
6681
6692
  }
6682
6693
  function unsupportedLanguageName(filePath) {
6683
- const ext2 = path6.extname(filePath).toLowerCase();
6694
+ const ext2 = path7.extname(filePath).toLowerCase();
6684
6695
  return UNSUPPORTED_LANGUAGE_EXTENSIONS.get(ext2);
6685
6696
  }
6686
6697
  var EXTENSION_LANGUAGE, FILENAME_LANGUAGE, DOTENV_VARIANT_RE, UNSUPPORTED_LANGUAGE_EXTENSIONS;
@@ -7006,8 +7017,8 @@ async function readOoxmlZip(filePath) {
7006
7017
  const data = fs6.readFileSync(filePath);
7007
7018
  return fflate.unzipSync(new Uint8Array(data));
7008
7019
  }
7009
- function decodeZipEntry(entries, path69) {
7010
- const bytes = entries[path69];
7020
+ function decodeZipEntry(entries, path70) {
7021
+ const bytes = entries[path70];
7011
7022
  if (bytes === void 0) return null;
7012
7023
  return new TextDecoder("utf-8").decode(bytes);
7013
7024
  }
@@ -7217,9 +7228,9 @@ async function notesPathFor(entries, slidePath) {
7217
7228
  }
7218
7229
  return null;
7219
7230
  }
7220
- async function parseSlide(entries, path69) {
7221
- const xml = decodeZipEntry(entries, path69);
7222
- if (xml === null) throw new Error(`missing part: ${path69}`);
7231
+ async function parseSlide(entries, path70) {
7232
+ const xml = decodeZipEntry(entries, path70);
7233
+ if (xml === null) throw new Error(`missing part: ${path70}`);
7223
7234
  return parseOoxmlPart(xml);
7224
7235
  }
7225
7236
  async function notesTextFor(entries, notesPath) {
@@ -7235,8 +7246,8 @@ async function pptxOutline(filePath) {
7235
7246
  const { entries, slidePaths } = await listSlideParts(filePath);
7236
7247
  const out2 = [];
7237
7248
  for (let i = 0; i < slidePaths.length; i++) {
7238
- const path69 = slidePaths[i];
7239
- const parsed = await parseSlide(entries, path69);
7249
+ const path70 = slidePaths[i];
7250
+ const parsed = await parseSlide(entries, path70);
7240
7251
  const shapes = slideShapes(parsed);
7241
7252
  const titleShape = shapes.find((s) => {
7242
7253
  const t = shapePlaceholderType(s);
@@ -7245,7 +7256,7 @@ async function pptxOutline(filePath) {
7245
7256
  const title = titleShape !== void 0 ? shapeText(titleShape) : "";
7246
7257
  const allText = collectTextRuns(parsed, "a:t").join(" ");
7247
7258
  const bodyChars = Math.max(0, allText.length - title.length);
7248
- const hasNotes = (await notesTextFor(entries, await notesPathFor(entries, path69))).length > 0;
7259
+ const hasNotes = (await notesTextFor(entries, await notesPathFor(entries, path70))).length > 0;
7249
7260
  out2.push({ slide: i + 1, title, bodyChars, hasNotes });
7250
7261
  }
7251
7262
  return out2;
@@ -7255,13 +7266,13 @@ async function pptxSlideText(filePath, slideNumber, includeNotes) {
7255
7266
  if (slideNumber < 1 || slideNumber > slidePaths.length) {
7256
7267
  throw new Error(`slide ${slideNumber} out of range (this deck has ${slidePaths.length} slides)`);
7257
7268
  }
7258
- const path69 = slidePaths[slideNumber - 1];
7259
- const parsed = await parseSlide(entries, path69);
7269
+ const path70 = slidePaths[slideNumber - 1];
7270
+ const parsed = await parseSlide(entries, path70);
7260
7271
  const shapes = slideShapes(parsed);
7261
7272
  const blocks = [...shapes.map(shapeText).filter((t) => t.length > 0), ...tableRowBlocks(parsed)];
7262
7273
  const lines2 = [`# Slide ${slideNumber}`, ...blocks];
7263
7274
  if (includeNotes) {
7264
- const notes = await notesTextFor(entries, await notesPathFor(entries, path69));
7275
+ const notes = await notesTextFor(entries, await notesPathFor(entries, path70));
7265
7276
  if (notes.length > 0) lines2.push("", "## Speaker notes", notes);
7266
7277
  }
7267
7278
  return lines2.join("\n\n");
@@ -7539,7 +7550,7 @@ var init_init_state = __esm({
7539
7550
  needMoreDataSize: Math.max(
7540
7551
  // Skip if the remaining buffer smaller than comment
7541
7552
  options.comment !== null ? options.comment.length : 0,
7542
- ...options.delimiter ? options.delimiter.map((delimiter2) => delimiter2.length) : [],
7553
+ ...options.delimiter ? options.delimiter.map((delimiter3) => delimiter3.length) : [],
7543
7554
  // Auto discovery of delimiter is limited to 1 character
7544
7555
  options.delimiter_auto ? 1 : 0,
7545
7556
  // Skip if the remaining buffer can be escape sequence
@@ -7807,11 +7818,11 @@ var init_normalize_options = __esm({
7807
7818
  }
7808
7819
  options.delimiter = [options.delimiter];
7809
7820
  }
7810
- options.delimiter = options.delimiter.map(function(delimiter2) {
7811
- if (typeof delimiter2 === "string") {
7812
- delimiter2 = Buffer.from(delimiter2, options.encoding);
7821
+ options.delimiter = options.delimiter.map(function(delimiter3) {
7822
+ if (typeof delimiter3 === "string") {
7823
+ delimiter3 = Buffer.from(delimiter3, options.encoding);
7813
7824
  }
7814
- if (!Buffer.isBuffer(delimiter2) || delimiter2.length === 0) {
7825
+ if (!Buffer.isBuffer(delimiter3) || delimiter3.length === 0) {
7815
7826
  throw new CsvError(
7816
7827
  "CSV_INVALID_OPTION_DELIMITER",
7817
7828
  [
@@ -7822,7 +7833,7 @@ var init_normalize_options = __esm({
7822
7833
  options
7823
7834
  );
7824
7835
  }
7825
- return delimiter2;
7836
+ return delimiter3;
7826
7837
  });
7827
7838
  if (options.escape === void 0 || options.escape === true) {
7828
7839
  options.escape = Buffer.from('"', options.encoding);
@@ -8907,14 +8918,14 @@ var init_api = __esm({
8907
8918
  return 0;
8908
8919
  },
8909
8920
  __isDelimiter: function(buf, pos, chr) {
8910
- const { delimiter: delimiter2, ignore_last_delimiters } = this.options;
8921
+ const { delimiter: delimiter3, ignore_last_delimiters } = this.options;
8911
8922
  if (ignore_last_delimiters === true && this.state.record.length === this.options.columns.length - 1) {
8912
8923
  return 0;
8913
8924
  } else if (ignore_last_delimiters !== false && typeof ignore_last_delimiters === "number" && this.state.record.length === ignore_last_delimiters - 1) {
8914
8925
  return 0;
8915
8926
  }
8916
- loop1: for (let i = 0; i < delimiter2.length; i++) {
8917
- const del = delimiter2[i];
8927
+ loop1: for (let i = 0; i < delimiter3.length; i++) {
8928
+ const del = delimiter3[i];
8918
8929
  if (del[0] === chr) {
8919
8930
  for (let j = 1; j < del.length; j++) {
8920
8931
  if (del[j] !== buf[pos + j]) continue loop1;
@@ -9080,18 +9091,18 @@ var init_sync = __esm({
9080
9091
 
9081
9092
  // src/csv_query.ts
9082
9093
  function parseRecords(content, opts) {
9083
- const delimiter2 = opts.delimiter ?? ",";
9094
+ const delimiter3 = opts.delimiter ?? ",";
9084
9095
  if (opts.noHeader === true) {
9085
- const rows = parse2(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true });
9096
+ const rows = parse2(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true });
9086
9097
  return rows.map((row) => Object.fromEntries(row.map((cell, i) => [`col${i + 1}`, cell])));
9087
9098
  }
9088
- return parse2(content, { columns: true, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true });
9099
+ return parse2(content, { columns: true, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true });
9089
9100
  }
9090
9101
  function csvHeader(content, opts) {
9091
9102
  if (opts.noHeader === true) return [];
9092
- const delimiter2 = opts.delimiter ?? ",";
9103
+ const delimiter3 = opts.delimiter ?? ",";
9093
9104
  try {
9094
- const rows = parse2(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true, to: 1 });
9105
+ const rows = parse2(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true, to: 1 });
9095
9106
  return rows[0] ?? [];
9096
9107
  } catch {
9097
9108
  return [];
@@ -9453,13 +9464,13 @@ var init_xlsx_extract = __esm({
9453
9464
 
9454
9465
  // src/doc_embed_extract.ts
9455
9466
  import * as fs7 from "node:fs";
9456
- import * as path7 from "node:path";
9467
+ import * as path8 from "node:path";
9457
9468
  function isEmbeddableDocument(filePath) {
9458
- return EMBEDDABLE_DOCUMENT_EXTENSIONS.has(path7.extname(filePath).toLowerCase());
9469
+ return EMBEDDABLE_DOCUMENT_EXTENSIONS.has(path8.extname(filePath).toLowerCase());
9459
9470
  }
9460
9471
  async function extractEmbeddableDocumentText(filePath) {
9461
9472
  try {
9462
- switch (path7.extname(filePath).toLowerCase()) {
9473
+ switch (path8.extname(filePath).toLowerCase()) {
9463
9474
  case ".pdf": {
9464
9475
  const data = await fs7.promises.readFile(filePath);
9465
9476
  const { text } = await extractPdfText(new Uint8Array(data));
@@ -12594,7 +12605,7 @@ var init_stats_renderer = __esm({
12594
12605
  });
12595
12606
 
12596
12607
  // src/stats.ts
12597
- import * as path8 from "node:path";
12608
+ import * as path9 from "node:path";
12598
12609
  function kindToSource(kind) {
12599
12610
  const src = KIND_TO_SOURCE[kind];
12600
12611
  if (src !== void 0) return src;
@@ -12630,7 +12641,7 @@ function incBucket(bucket, bytesSaved, tokensSaved) {
12630
12641
  }
12631
12642
  function getGlobalDb(homeDir) {
12632
12643
  const basePath = homeDir ? dataDirForHome(homeDir) : dataDir();
12633
- const dbPath = path8.join(basePath, "global.db");
12644
+ const dbPath = path9.join(basePath, "global.db");
12634
12645
  const db = getDb(dbPath);
12635
12646
  if (!_globalSchemaApplied.has(dbPath)) {
12636
12647
  db.exec(GLOBAL_SCHEMA_SQL);
@@ -13079,26 +13090,26 @@ CREATE INDEX IF NOT EXISTS idx_stats_kind ON stats(kind);
13079
13090
 
13080
13091
  // src/disk_cache.ts
13081
13092
  import * as fs8 from "node:fs";
13082
- import * as path9 from "node:path";
13093
+ import * as path10 from "node:path";
13083
13094
  import * as os3 from "node:os";
13084
13095
  function tokenGoatHome() {
13085
13096
  const override = process.env["TOKEN_GOAT_HOME"];
13086
13097
  if (override !== void 0 && override !== "") return override;
13087
- return path9.join(os3.homedir(), ".token-goat");
13098
+ return path10.join(os3.homedir(), ".token-goat");
13088
13099
  }
13089
13100
  function sanitizeId(id) {
13090
13101
  return sanitizeIdForFilename(id, 64);
13091
13102
  }
13092
13103
  function blobDir(subdir) {
13093
- return path9.join(tokenGoatHome(), subdir);
13104
+ return path10.join(tokenGoatHome(), subdir);
13094
13105
  }
13095
13106
  function blobPath(subdir, id) {
13096
13107
  const safe = sanitizeId(id);
13097
13108
  if (!safe) return null;
13098
13109
  const dir = blobDir(subdir);
13099
- const candidate = path9.join(dir, `${safe}.json`);
13110
+ const candidate = path10.join(dir, `${safe}.json`);
13100
13111
  try {
13101
- const rel = path9.relative(dir, candidate);
13112
+ const rel = path10.relative(dir, candidate);
13102
13113
  if (rel.startsWith("..")) return null;
13103
13114
  } catch {
13104
13115
  return null;
@@ -13145,7 +13156,7 @@ function storeBlob(subdir, id, value, opts = {}) {
13145
13156
  }
13146
13157
  if (Number.isFinite(maxBytesPerItem) && Buffer.byteLength(json2, "utf-8") > maxBytesPerItem) return false;
13147
13158
  try {
13148
- const dir = path9.dirname(p);
13159
+ const dir = path10.dirname(p);
13149
13160
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
13150
13161
  atomicWriteText(p, json2);
13151
13162
  } catch {
@@ -13180,7 +13191,7 @@ function listBlobs(subdir) {
13180
13191
  const id = file2.slice(0, -5);
13181
13192
  let mtime = 0;
13182
13193
  try {
13183
- mtime = fs8.statSync(path9.join(dir, file2)).mtimeMs;
13194
+ mtime = fs8.statSync(path10.join(dir, file2)).mtimeMs;
13184
13195
  } catch {
13185
13196
  }
13186
13197
  const value = loadBlob(subdir, id);
@@ -13201,7 +13212,7 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
13201
13212
  let protectedEntry;
13202
13213
  for (const file2 of fs8.readdirSync(dir)) {
13203
13214
  if (!file2.endsWith(".json")) continue;
13204
- const full = path9.join(dir, file2);
13215
+ const full = path10.join(dir, file2);
13205
13216
  let stat2;
13206
13217
  try {
13207
13218
  stat2 = fs8.statSync(full);
@@ -15357,7 +15368,7 @@ var init_html = __esm({
15357
15368
  });
15358
15369
 
15359
15370
  // src/languages/liquid.ts
15360
- import * as path10 from "node:path";
15371
+ import * as path11 from "node:path";
15361
15372
  function extractLiquid(content, filePath, relPath) {
15362
15373
  const symbols = [];
15363
15374
  const imports = [];
@@ -15391,7 +15402,7 @@ function extractLiquid(content, filePath, relPath) {
15391
15402
  const resolvedRel = relPath ?? filePath;
15392
15403
  const relPosix = resolvedRel.replace(/\\/g, "/");
15393
15404
  if (relPosix.startsWith("sections/") || relPosix.includes("/sections/")) {
15394
- const stem = path10.basename(resolvedRel, path10.extname(resolvedRel));
15405
+ const stem = path11.basename(resolvedRel, path11.extname(resolvedRel));
15395
15406
  symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "", parent: "" });
15396
15407
  }
15397
15408
  const totalLines = content.split("\n").length;
@@ -17620,7 +17631,7 @@ var init_apex = __esm({
17620
17631
  });
17621
17632
 
17622
17633
  // src/languages/salesforce_metadata.ts
17623
- import * as path11 from "node:path";
17634
+ import * as path12 from "node:path";
17624
17635
  function xmlText(content, tag) {
17625
17636
  const re = new RegExp(
17626
17637
  `<(?:[A-Za-z_][\\w.-]*:)?${tag}(?:\\s[^>]*)?>([\\s\\S]*?)</(?:[A-Za-z_][\\w.-]*:)?${tag}>`,
@@ -17656,7 +17667,7 @@ function normalizedPath(filePath) {
17656
17667
  return filePath.replace(/\\/g, "/");
17657
17668
  }
17658
17669
  function basenameWithout(filePath, suffix) {
17659
- const base = path11.basename(filePath);
17670
+ const base = path12.basename(filePath);
17660
17671
  return base.toLowerCase().endsWith(suffix.toLowerCase()) ? base.slice(0, base.length - suffix.length) : base;
17661
17672
  }
17662
17673
  function objectNameFromPath(filePath) {
@@ -17695,12 +17706,12 @@ function snakeCase(value) {
17695
17706
  return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
17696
17707
  }
17697
17708
  function companionName(filePath) {
17698
- const base = path11.basename(filePath);
17709
+ const base = path12.basename(filePath);
17699
17710
  const match2 = /^(.+)\.(?:cls|trigger|page|component|cmp|app|evt|intf|design|auradoc|tokens|js)-meta\.xml$/i.exec(base);
17700
17711
  return match2?.[1] === void 0 ? null : `${match2[1]}.metadata`;
17701
17712
  }
17702
17713
  function metadataArtifactName(filePath) {
17703
- const base = path11.basename(filePath);
17714
+ const base = path12.basename(filePath);
17704
17715
  const match2 = /^(.+)\.[^.]+-meta\.xml$/i.exec(base);
17705
17716
  return match2?.[1] ?? basenameWithout(filePath, "-meta.xml");
17706
17717
  }
@@ -17791,7 +17802,7 @@ function extractSalesforceMetadata(rawContent, filePath) {
17791
17802
  const seen = /* @__PURE__ */ new Set();
17792
17803
  const refs = [];
17793
17804
  const seenRefs = /* @__PURE__ */ new Set();
17794
- const base = path11.basename(filePath).toLowerCase();
17805
+ const base = path12.basename(filePath).toLowerCase();
17795
17806
  const whole = wholeFileSpan(content);
17796
17807
  const root = rootElement(content);
17797
17808
  if (root === null) return { symbols, refs };
@@ -17965,14 +17976,14 @@ var init_salesforce_metadata = __esm({
17965
17976
  });
17966
17977
 
17967
17978
  // src/languages/salesforce_frontend.ts
17968
- import * as path12 from "node:path";
17979
+ import * as path13 from "node:path";
17969
17980
  function lines(content) {
17970
17981
  return content.split("\n");
17971
17982
  }
17972
17983
  function bundleName(filePath) {
17973
17984
  const normalized = filePath.replaceAll("\\", "/");
17974
- const parent = path12.posix.basename(path12.posix.dirname(normalized));
17975
- const base = path12.posix.basename(normalized).replace(/\.[^.]+$/, "");
17985
+ const parent = path13.posix.basename(path13.posix.dirname(normalized));
17986
+ const base = path13.posix.basename(normalized).replace(/\.[^.]+$/, "");
17976
17987
  return parent === "lwc" || parent === "aura" ? base : parent;
17977
17988
  }
17978
17989
  function lwcTagAlias(name2) {
@@ -18064,7 +18075,7 @@ function extractLwcTemplate(content, filePath) {
18064
18075
  }
18065
18076
  function markupArtifactName(filePath, extension) {
18066
18077
  if (extension === ".page" || extension === ".component" || extension === ".email") {
18067
- return path12.posix.basename(filePath.replaceAll("\\", "/")).replace(new RegExp(`${extension.replace(".", "\\.")}$`, "i"), "");
18078
+ return path13.posix.basename(filePath.replaceAll("\\", "/")).replace(new RegExp(`${extension.replace(".", "\\.")}$`, "i"), "");
18068
18079
  }
18069
18080
  return bundleName(filePath);
18070
18081
  }
@@ -18084,7 +18095,7 @@ function attributeRefs(refs, content, filePath, attribute, split = false) {
18084
18095
  }
18085
18096
  function extractSalesforceMarkup(content, filePath) {
18086
18097
  const normalized = filePath.replaceAll("\\", "/");
18087
- const extension = path12.posix.extname(normalized).toLowerCase();
18098
+ const extension = path13.posix.extname(normalized).toLowerCase();
18088
18099
  const sourceLines = lines(content);
18089
18100
  const kind = MARKUP_KIND[extension] ?? "salesforce_markup";
18090
18101
  const symbols = [
@@ -18137,7 +18148,7 @@ var init_salesforce_frontend = __esm({
18137
18148
  });
18138
18149
 
18139
18150
  // src/languages/sfc_idx.ts
18140
- import * as path13 from "node:path";
18151
+ import * as path14 from "node:path";
18141
18152
  function dedupe2(values, key) {
18142
18153
  const seen = /* @__PURE__ */ new Set();
18143
18154
  return values.filter((value) => {
@@ -18155,7 +18166,7 @@ function finalize(symbols, refs) {
18155
18166
  }
18156
18167
  function componentName(filePath) {
18157
18168
  const normalized = filePath.replaceAll("\\", "/");
18158
- return path13.posix.basename(normalized).replace(/\.[^.]+$/, "");
18169
+ return path14.posix.basename(normalized).replace(/\.[^.]+$/, "");
18159
18170
  }
18160
18171
  function matchLine2(content, offset) {
18161
18172
  return content.slice(0, offset).split("\n").length;
@@ -18395,7 +18406,7 @@ var init_ipynb_idx = __esm({
18395
18406
  // src/parser.ts
18396
18407
  import * as fs9 from "node:fs";
18397
18408
  import { createRequire as createRequire4 } from "node:module";
18398
- import * as path14 from "node:path";
18409
+ import * as path15 from "node:path";
18399
18410
  function loadParserCtor() {
18400
18411
  if (_parserCtor !== void 0) return _parserCtor;
18401
18412
  try {
@@ -18477,8 +18488,8 @@ function countNewlines(s) {
18477
18488
  return n;
18478
18489
  }
18479
18490
  function loadGrammar(lang, filePath, content) {
18480
- const useTsx = lang === "typescript" && filePath !== void 0 && path14.extname(filePath).toLowerCase() === ".tsx";
18481
- const useCppHeader = lang === "c" && filePath !== void 0 && path14.extname(filePath).toLowerCase() === ".h" && content !== void 0 && CPP_HEADER_SNIFF_RE.test(content);
18491
+ const useTsx = lang === "typescript" && filePath !== void 0 && path15.extname(filePath).toLowerCase() === ".tsx";
18492
+ const useCppHeader = lang === "c" && filePath !== void 0 && path15.extname(filePath).toLowerCase() === ".h" && content !== void 0 && CPP_HEADER_SNIFF_RE.test(content);
18482
18493
  const cacheKey = useTsx ? "typescript:tsx" : useCppHeader ? "c:cpp-header" : lang;
18483
18494
  const cached2 = _grammarCache.get(cacheKey);
18484
18495
  if (cached2 !== void 0) return cached2;
@@ -19527,7 +19538,7 @@ function isUnderSkipDir(filePath, skipDirs) {
19527
19538
  }
19528
19539
  function isParseSkipEligible(filePath, cfg) {
19529
19540
  if (isUnderSkipDir(filePath, cfg.skip_dirs)) return true;
19530
- if (cfg.skip_files.includes(path14.basename(filePath))) return true;
19541
+ if (cfg.skip_files.includes(path15.basename(filePath))) return true;
19531
19542
  try {
19532
19543
  const stat2 = fs9.statSync(filePath);
19533
19544
  if (stat2.size > cfg.large_file_skip_kb * 1024) return true;
@@ -20493,7 +20504,7 @@ var init_hooks_common = __esm({
20493
20504
 
20494
20505
  // src/index_prune.ts
20495
20506
  import * as fs10 from "node:fs";
20496
- import * as path15 from "node:path";
20507
+ import * as path16 from "node:path";
20497
20508
  function removeFileFromIndex(db, filePath) {
20498
20509
  const tx = db.transaction(() => {
20499
20510
  deleteFileRows(db, filePath);
@@ -20572,7 +20583,7 @@ function pruneSystemTempFiles(dbPath = globalDbPath()) {
20572
20583
  return removeFilesBestEffort(db, findSystemTempFiles(dbPath));
20573
20584
  }
20574
20585
  function recordKnownRoot(filePath, dbPath = globalDbPath()) {
20575
- const project = findProject(path15.dirname(filePath));
20586
+ const project = findProject(path16.dirname(filePath));
20576
20587
  if (project === null || isTooShallowToPrune(project.root)) return;
20577
20588
  const db = getDb(dbPath);
20578
20589
  db.prepare(
@@ -20625,7 +20636,7 @@ function sweepKnownRoots(dbPath = globalDbPath(), opts) {
20625
20636
  return { prunedRows, prunedRoots, flaggedRoots };
20626
20637
  }
20627
20638
  function knownRootRecordMarkerPath(dir, filePath) {
20628
- return path15.join(dir, `known-root-record-${shortFingerprint(path15.dirname(filePath))}.marker`);
20639
+ return path16.join(dir, `known-root-record-${shortFingerprint(path16.dirname(filePath))}.marker`);
20629
20640
  }
20630
20641
  function recordKnownRootThrottled(filePath, dir = dataDir(), dbPath = globalDbPath()) {
20631
20642
  const markerPath = knownRootRecordMarkerPath(dir, filePath);
@@ -20662,14 +20673,14 @@ var init_index_prune = __esm({
20662
20673
 
20663
20674
  // src/snapshots.ts
20664
20675
  import * as fs11 from "node:fs";
20665
- import * as path16 from "node:path";
20676
+ import * as path17 from "node:path";
20666
20677
  function sessionDir(sessionId) {
20667
20678
  if (!sessionId) return null;
20668
20679
  const safe = sanitizeIdForFilename(sessionId, 64, "anon");
20669
- const base = path16.join(tokenGoatHome(), "session_snapshots");
20670
- const candidate = path16.join(base, safe);
20680
+ const base = path17.join(tokenGoatHome(), "session_snapshots");
20681
+ const candidate = path17.join(base, safe);
20671
20682
  try {
20672
- const rel = path16.relative(base, candidate);
20683
+ const rel = path17.relative(base, candidate);
20673
20684
  if (rel.startsWith("..")) return null;
20674
20685
  } catch {
20675
20686
  return null;
@@ -20682,7 +20693,7 @@ function pathKey(filePath) {
20682
20693
  function snapshot_path(sessionId, filePath) {
20683
20694
  const d = sessionDir(sessionId);
20684
20695
  if (!d) return null;
20685
- return path16.join(d, `${pathKey(filePath)}.bin`);
20696
+ return path17.join(d, `${pathKey(filePath)}.bin`);
20686
20697
  }
20687
20698
  function kindSidecarPath(snapshotPath) {
20688
20699
  return snapshotPath + ".kind";
@@ -20690,7 +20701,7 @@ function kindSidecarPath(snapshotPath) {
20690
20701
  function writeSnapshotKind(sidecarPath, kind) {
20691
20702
  try {
20692
20703
  const safeKind = VALID_KINDS.has(kind) ? kind : KIND_READ;
20693
- const dir = path16.dirname(sidecarPath);
20704
+ const dir = path17.dirname(sidecarPath);
20694
20705
  if (!fs11.existsSync(dir)) {
20695
20706
  fs11.mkdirSync(dir, { recursive: true });
20696
20707
  }
@@ -20705,7 +20716,7 @@ function evictOldest(d, maxCount) {
20705
20716
  const entries = [];
20706
20717
  const files = fs11.readdirSync(d);
20707
20718
  for (const file2 of files) {
20708
- const fullPath = path16.join(d, file2);
20719
+ const fullPath = path17.join(d, file2);
20709
20720
  if (!file2.endsWith(".bin")) continue;
20710
20721
  try {
20711
20722
  const stat2 = fs11.statSync(fullPath);
@@ -20766,7 +20777,7 @@ function store(sessionId, filePath, content, opts = {}) {
20766
20777
  } catch {
20767
20778
  }
20768
20779
  }
20769
- const dir = path16.dirname(p);
20780
+ const dir = path17.dirname(p);
20770
20781
  if (!fs11.existsSync(dir)) {
20771
20782
  fs11.mkdirSync(dir, { recursive: true });
20772
20783
  }
@@ -20817,14 +20828,14 @@ function removeEligibleSnapshotFile(fullPath, file2, cutoff) {
20817
20828
  return file2.endsWith(".bin");
20818
20829
  }
20819
20830
  function cleanup_stale(maxAgeHours = 24) {
20820
- const base = path16.join(tokenGoatHome(), "session_snapshots");
20831
+ const base = path17.join(tokenGoatHome(), "session_snapshots");
20821
20832
  if (!fs11.existsSync(base)) return 0;
20822
20833
  const cutoff = Date.now() - maxAgeHours * 3600 * 1e3;
20823
20834
  let removed = 0;
20824
20835
  try {
20825
20836
  const sessionDirs = fs11.readdirSync(base);
20826
20837
  for (const sessionDir2 of sessionDirs) {
20827
- const sessionPath2 = path16.join(base, sessionDir2);
20838
+ const sessionPath2 = path17.join(base, sessionDir2);
20828
20839
  try {
20829
20840
  const stat2 = fs11.statSync(sessionPath2);
20830
20841
  if (!stat2.isDirectory()) continue;
@@ -20834,7 +20845,7 @@ function cleanup_stale(maxAgeHours = 24) {
20834
20845
  try {
20835
20846
  const files = fs11.readdirSync(sessionPath2);
20836
20847
  for (const file2 of files) {
20837
- const fullPath = path16.join(sessionPath2, file2);
20848
+ const fullPath = path17.join(sessionPath2, file2);
20838
20849
  try {
20839
20850
  if (removeEligibleSnapshotFile(fullPath, file2, cutoff)) removed++;
20840
20851
  } catch {
@@ -20874,18 +20885,18 @@ var init_snapshots = __esm({
20874
20885
  // src/worker.ts
20875
20886
  import { spawn as spawn2 } from "node:child_process";
20876
20887
  import * as fs12 from "node:fs";
20877
- import * as path17 from "node:path";
20888
+ import * as path18 from "node:path";
20878
20889
  import { fileURLToPath } from "node:url";
20879
20890
  function listDrainingFiles(queuePath) {
20880
- const dir = path17.dirname(queuePath);
20881
- const base = `${path17.basename(queuePath)}.draining`;
20891
+ const dir = path18.dirname(queuePath);
20892
+ const base = `${path18.basename(queuePath)}.draining`;
20882
20893
  let entries;
20883
20894
  try {
20884
20895
  entries = fs12.readdirSync(dir);
20885
20896
  } catch {
20886
20897
  return [];
20887
20898
  }
20888
- return entries.filter((name2) => name2 === base || name2.startsWith(`${base}.alt-`) && !name2.includes(".corrupt-")).sort().map((name2) => path17.join(dir, name2));
20899
+ return entries.filter((name2) => name2 === base || name2.startsWith(`${base}.alt-`) && !name2.includes(".corrupt-")).sort().map((name2) => path18.join(dir, name2));
20889
20900
  }
20890
20901
  function bumpRetryCount(dbPath, absPath) {
20891
20902
  const db = getDb(dbPath);
@@ -20912,16 +20923,16 @@ function clearRetryCount(dbPath, absPath) {
20912
20923
  }
20913
20924
  }
20914
20925
  function dirtyQueuePathFor(dir) {
20915
- return path17.join(dir, "queue", "dirty.txt");
20926
+ return path18.join(dir, "queue", "dirty.txt");
20916
20927
  }
20917
20928
  function drainHeartbeatPathFor(dir) {
20918
- return path17.join(dir, "queue", "drain-heartbeat");
20929
+ return path18.join(dir, "queue", "drain-heartbeat");
20919
20930
  }
20920
20931
  function writeDrainHeartbeat(dir, force = false) {
20921
20932
  const now = Date.now();
20922
20933
  if (!force && now - (heartbeatWriteTimes.get(dir) ?? 0) < WORKER_HEARTBEAT_REFRESH_MS) return;
20923
20934
  try {
20924
- fs12.mkdirSync(path17.dirname(drainHeartbeatPathFor(dir)), { recursive: true });
20935
+ fs12.mkdirSync(path18.dirname(drainHeartbeatPathFor(dir)), { recursive: true });
20925
20936
  fs12.writeFileSync(drainHeartbeatPathFor(dir), `${process.pid}
20926
20937
  `);
20927
20938
  heartbeatWriteTimes.set(dir, now);
@@ -20959,7 +20970,7 @@ function parseDirtyQueueLines(raw) {
20959
20970
  return out2;
20960
20971
  }
20961
20972
  function workerPidPath(dir = dataDir()) {
20962
- return path17.join(dir, "worker.pid");
20973
+ return path18.join(dir, "worker.pid");
20963
20974
  }
20964
20975
  function getDirtyPathsFor(dir) {
20965
20976
  let raw;
@@ -20971,7 +20982,7 @@ function getDirtyPathsFor(dir) {
20971
20982
  return parseDirtyQueueLines(raw);
20972
20983
  }
20973
20984
  function workerErrorLogPath(dir) {
20974
- return path17.join(dir, "worker-errors.log");
20985
+ return path18.join(dir, "worker-errors.log");
20975
20986
  }
20976
20987
  function cleanupWorkerStateFiles(dir) {
20977
20988
  try {
@@ -20987,11 +20998,11 @@ function cleanupWorkerStateFiles(dir) {
20987
20998
  } catch {
20988
20999
  }
20989
21000
  try {
20990
- const queueDir = path17.dirname(dirtyQueuePathFor(dir));
21001
+ const queueDir = path18.dirname(dirtyQueuePathFor(dir));
20991
21002
  const cutoff = Date.now() - CORRUPT_QUARANTINE_MAX_AGE_MS;
20992
21003
  for (const file2 of fs12.readdirSync(queueDir)) {
20993
21004
  if (!file2.includes(".corrupt-")) continue;
20994
- const full = path17.join(queueDir, file2);
21005
+ const full = path18.join(queueDir, file2);
20995
21006
  try {
20996
21007
  if (fs12.statSync(full).mtimeMs < cutoff) fs12.unlinkSync(full);
20997
21008
  } catch {
@@ -21008,7 +21019,7 @@ function releaseEmbedSlot() {
21008
21019
  function embedFileSerialized(absPath, dbPath, sha) {
21009
21020
  const key = foldPath(absPath);
21010
21021
  const prior = inFlightEmbeddings.get(key);
21011
- const dir = path17.dirname(dbPath);
21022
+ const dir = path18.dirname(dbPath);
21012
21023
  const onEmbedError = (err2) => {
21013
21024
  const message = extractErrorMessage(err2);
21014
21025
  appendWorkerErrorLog(dir, `${(/* @__PURE__ */ new Date()).toISOString()} indexFileEmbeddings failed for ${absPath}: ${message}
@@ -21058,7 +21069,7 @@ function logTransientReadFailure(dir, absPath) {
21058
21069
  );
21059
21070
  }
21060
21071
  function bumpAndCheckRetry(dir, absPath) {
21061
- const dbPath = path17.join(dir, "global.db");
21072
+ const dbPath = path18.join(dir, "global.db");
21062
21073
  const attempts = bumpRetryCount(dbPath, absPath);
21063
21074
  if (attempts > MAX_TRANSIENT_RETRIES) {
21064
21075
  if (attempts === MAX_TRANSIENT_RETRIES + 1) {
@@ -21075,7 +21086,7 @@ function bumpAndCheckRetry(dir, absPath) {
21075
21086
  function appendToDirtyQueue(dir, absPath) {
21076
21087
  const queuePath = dirtyQueuePathFor(dir);
21077
21088
  try {
21078
- fs12.mkdirSync(path17.dirname(queuePath), { recursive: true });
21089
+ fs12.mkdirSync(path18.dirname(queuePath), { recursive: true });
21079
21090
  let leadingNewline = "";
21080
21091
  try {
21081
21092
  const existing = fs12.readFileSync(queuePath, "utf8");
@@ -21091,7 +21102,7 @@ function requeueDirtyPath(dir, absPath) {
21091
21102
  if (bumpAndCheckRetry(dir, absPath)) appendToDirtyQueue(dir, absPath);
21092
21103
  }
21093
21104
  function makeIndexer(dbPath) {
21094
- const dir = path17.dirname(dbPath);
21105
+ const dir = path18.dirname(dbPath);
21095
21106
  return (absPath, sha) => {
21096
21107
  try {
21097
21108
  const ixCfgForSkip = loadConfig().indexing;
@@ -21143,9 +21154,9 @@ function processDirtyBatch(paths, index = makeIndexer(globalDbPath()), remove =
21143
21154
  requeue(dir, p);
21144
21155
  continue;
21145
21156
  }
21146
- clearRetryCount(path17.join(dir, "global.db"), p);
21157
+ clearRetryCount(path18.join(dir, "global.db"), p);
21147
21158
  try {
21148
- const dirname31 = path17.dirname(p);
21159
+ const dirname31 = path18.dirname(p);
21149
21160
  let root;
21150
21161
  if (projectRootCache.has(dirname31)) {
21151
21162
  root = projectRootCache.get(dirname31) ?? null;
@@ -21171,7 +21182,7 @@ function sleepSyncMs(ms) {
21171
21182
  function drainOnce(dir, index, remove) {
21172
21183
  const queuePath = dirtyQueuePathFor(dir);
21173
21184
  const draining = `${queuePath}.draining`;
21174
- const dbPath = path17.join(dir, "global.db");
21185
+ const dbPath = path18.join(dir, "global.db");
21175
21186
  const indexFn = index ?? makeIndexer(dbPath);
21176
21187
  const removeFn = remove ?? makeRemover(dbPath);
21177
21188
  let processed = 0;
@@ -21285,7 +21296,7 @@ function isWorkerRunning(dir = dataDir()) {
21285
21296
  return pidAlive(pid) && hasFreshWorkerHeartbeat(dir, pid);
21286
21297
  }
21287
21298
  function workerHealthCheckMarkerPath(dir) {
21288
- return path17.join(dir, "worker-healthcheck.marker");
21299
+ return path18.join(dir, "worker-healthcheck.marker");
21289
21300
  }
21290
21301
  function ensureWorkerAlive(dir = dataDir()) {
21291
21302
  if (process.env["TOKEN_GOAT_NO_WORKER_SPAWN"] === "1") return;
@@ -21418,7 +21429,7 @@ async function runWorkerLoop(dir, pollIntervalMs, shouldStop = () => false) {
21418
21429
  }
21419
21430
  if (Date.now() - lastKnownRootsSweepMs >= KNOWN_ROOTS_SWEEP_INTERVAL_MS) {
21420
21431
  try {
21421
- const result = sweepKnownRoots(path17.join(dir, "global.db"));
21432
+ const result = sweepKnownRoots(path18.join(dir, "global.db"));
21422
21433
  if (result.flaggedRoots.length > 0) {
21423
21434
  appendWorkerErrorLog(
21424
21435
  dir,
@@ -21503,13 +21514,13 @@ var init_worker = __esm({
21503
21514
 
21504
21515
  // src/hooks_index.ts
21505
21516
  import * as fs13 from "node:fs";
21506
- import * as path18 from "node:path";
21517
+ import * as path19 from "node:path";
21507
21518
  function dirtyQueuePath() {
21508
- return path18.join(dataDir(), "queue", "dirty.txt");
21519
+ return path19.join(dataDir(), "queue", "dirty.txt");
21509
21520
  }
21510
21521
  function appendDirtyPath(normalizedPath2) {
21511
21522
  const queuePath = dirtyQueuePath();
21512
- const dir = path18.dirname(queuePath);
21523
+ const dir = path19.dirname(queuePath);
21513
21524
  try {
21514
21525
  fs13.mkdirSync(dir, { recursive: true });
21515
21526
  } catch (e) {
@@ -21543,9 +21554,9 @@ function getDirtyPaths() {
21543
21554
  function preCompactIndexHandler(_event) {
21544
21555
  const paths = getDirtyPaths();
21545
21556
  if (paths.length > 0) {
21546
- const sidecar = path18.join(dataDir(), "queue", "pending.txt");
21557
+ const sidecar = path19.join(dataDir(), "queue", "pending.txt");
21547
21558
  try {
21548
- fs13.mkdirSync(path18.dirname(sidecar), { recursive: true });
21559
+ fs13.mkdirSync(path19.dirname(sidecar), { recursive: true });
21549
21560
  atomicWriteBytes(sidecar, Buffer.from(`${paths.join("\n")}
21550
21561
  `, "utf8"));
21551
21562
  } catch {
@@ -22122,10 +22133,10 @@ var init_json_query = __esm({
22122
22133
  });
22123
22134
 
22124
22135
  // src/openapi_query.ts
22125
- import * as path19 from "node:path";
22136
+ import * as path20 from "node:path";
22126
22137
  function parseOpenApiSpec(text, filePath) {
22127
22138
  text = stripBom(text);
22128
- const ext2 = path19.extname(filePath).toLowerCase();
22139
+ const ext2 = path20.extname(filePath).toLowerCase();
22129
22140
  if (ext2 === ".yaml" || ext2 === ".yml") return load(text);
22130
22141
  if (ext2 === ".json") return JSON.parse(text);
22131
22142
  try {
@@ -23204,9 +23215,9 @@ var init_conflict_query = __esm({
23204
23215
  // src/image_ocr.ts
23205
23216
  import { spawn as spawn3 } from "node:child_process";
23206
23217
  import { createRequire as createRequire5 } from "node:module";
23207
- import * as path20 from "node:path";
23218
+ import * as path21 from "node:path";
23208
23219
  function ocrCacheDir() {
23209
- return path20.join(tokenGoatHome(), "ocr-cache");
23220
+ return path21.join(tokenGoatHome(), "ocr-cache");
23210
23221
  }
23211
23222
  function resolveTesseractEntry() {
23212
23223
  if (_tesseractEntryPath !== void 0) return _tesseractEntryPath;
@@ -23314,7 +23325,7 @@ var init_image_ocr = __esm({
23314
23325
  // src/image_shrink.ts
23315
23326
  import { createHash as createHash2 } from "node:crypto";
23316
23327
  import * as fs15 from "node:fs";
23317
- import * as path21 from "node:path";
23328
+ import * as path22 from "node:path";
23318
23329
  function formatShrinkSummary(result, subject) {
23319
23330
  const saved = result.originalBytes - result.shrunkBytes;
23320
23331
  const pct = Math.round(saved / result.originalBytes * 100);
@@ -23323,7 +23334,7 @@ function formatShrinkSummary(result, subject) {
23323
23334
  return { summary, dataUrl };
23324
23335
  }
23325
23336
  function isImagePath(p) {
23326
- return IMAGE_EXTENSIONS.has(path21.extname(p).toLowerCase());
23337
+ return IMAGE_EXTENSIONS.has(path22.extname(p).toLowerCase());
23327
23338
  }
23328
23339
  async function probeImageMeta(input) {
23329
23340
  const sharp = await loadSharp();
@@ -23381,7 +23392,7 @@ function statInfo(absPath) {
23381
23392
  }
23382
23393
  }
23383
23394
  function imageShrinkCacheDir() {
23384
- return path21.join(tokenGoatHome(), "image_shrink_cache");
23395
+ return path22.join(tokenGoatHome(), "image_shrink_cache");
23385
23396
  }
23386
23397
  function shrinkCacheKey(originalPath, size, mtimeMs) {
23387
23398
  return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}`).digest("hex").slice(0, 16);
@@ -23394,7 +23405,7 @@ function findCachedShrink(originalPath, size, mtimeMs) {
23394
23405
  { ext: ".jpg", format: "jpeg" }
23395
23406
  ];
23396
23407
  for (const { ext: ext2, format } of candidates) {
23397
- const candidate = path21.join(dir, `token-goat-shrink-${key}${ext2}`);
23408
+ const candidate = path22.join(dir, `token-goat-shrink-${key}${ext2}`);
23398
23409
  if (fs15.existsSync(candidate)) return { filePath: candidate, format };
23399
23410
  }
23400
23411
  return null;
@@ -23405,7 +23416,7 @@ function writeCachedShrink(originalPath, result, mtimeMs) {
23405
23416
  fs15.mkdirSync(dir, { recursive: true });
23406
23417
  const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs);
23407
23418
  const ext2 = result.format === "jpeg" ? ".jpg" : ".webp";
23408
- atomicWriteBytes(path21.join(dir, `token-goat-shrink-${key}${ext2}`), result.data);
23419
+ atomicWriteBytes(path22.join(dir, `token-goat-shrink-${key}${ext2}`), result.data);
23409
23420
  } catch {
23410
23421
  }
23411
23422
  }
@@ -23419,7 +23430,7 @@ function pruneShrinkCache() {
23419
23430
  const cutoff = now - DEFAULT_MAX_AGE_MS;
23420
23431
  for (const file2 of fs15.readdirSync(dir)) {
23421
23432
  if (!file2.startsWith("token-goat-shrink-")) continue;
23422
- const full = path21.join(dir, file2);
23433
+ const full = path22.join(dir, file2);
23423
23434
  try {
23424
23435
  const st = fs15.statSync(full);
23425
23436
  if (st.mtimeMs < cutoff) fs15.unlinkSync(full);
@@ -23430,7 +23441,7 @@ function pruneShrinkCache() {
23430
23441
  }
23431
23442
  }
23432
23443
  async function finalizeShrinkResult(result, filePath) {
23433
- const basename22 = path21.basename(filePath);
23444
+ const basename22 = path22.basename(filePath);
23434
23445
  if (loadConfig().image_shrink.ocr_enabled) {
23435
23446
  const ocr = await ocrImage(result.data);
23436
23447
  if (ocr !== null && isTextHeavy(ocr, loadConfig().image_shrink.ocr_min_confidence)) {
@@ -23557,7 +23568,7 @@ var init_image_shrink = __esm({
23557
23568
  // src/screenshot.ts
23558
23569
  import dns from "node:dns/promises";
23559
23570
  import fs16 from "node:fs";
23560
- import path22 from "node:path";
23571
+ import path23 from "node:path";
23561
23572
  function findPlaywrightChromium(msPlaywrightDir) {
23562
23573
  let entries;
23563
23574
  try {
@@ -23569,7 +23580,7 @@ function findPlaywrightChromium(msPlaywrightDir) {
23569
23580
  const candidates = [];
23570
23581
  for (const m of versioned) {
23571
23582
  for (const sub of PLAYWRIGHT_CHROME_SUBDIRS) {
23572
- candidates.push(path22.join(msPlaywrightDir, m[0], sub, "chrome.exe"));
23583
+ candidates.push(path23.join(msPlaywrightDir, m[0], sub, "chrome.exe"));
23573
23584
  }
23574
23585
  }
23575
23586
  return candidates;
@@ -23580,23 +23591,23 @@ function platformCandidatePaths() {
23580
23591
  const programFiles = process.env["PROGRAMFILES"];
23581
23592
  const programFilesX86 = process.env["PROGRAMFILES(X86)"];
23582
23593
  const localAppData = process.env["LOCALAPPDATA"];
23583
- if (programFiles) candidates2.push(path22.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"));
23584
- if (programFilesX86) candidates2.push(path22.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"));
23594
+ if (programFiles) candidates2.push(path23.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"));
23595
+ if (programFilesX86) candidates2.push(path23.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"));
23585
23596
  if (localAppData) {
23586
- candidates2.push(path22.join(localAppData, "Google", "Chrome", "Application", "chrome.exe"));
23587
- candidates2.push(...findPlaywrightChromium(path22.join(localAppData, "ms-playwright")));
23597
+ candidates2.push(path23.join(localAppData, "Google", "Chrome", "Application", "chrome.exe"));
23598
+ candidates2.push(...findPlaywrightChromium(path23.join(localAppData, "ms-playwright")));
23588
23599
  }
23589
23600
  return candidates2;
23590
23601
  }
23591
23602
  if (process.platform === "darwin") {
23592
23603
  const home2 = process.env["HOME"];
23593
23604
  const candidates2 = ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"];
23594
- if (home2) candidates2.push(...findPlaywrightChromium(path22.join(home2, "Library", "Caches", "ms-playwright")));
23605
+ if (home2) candidates2.push(...findPlaywrightChromium(path23.join(home2, "Library", "Caches", "ms-playwright")));
23595
23606
  return candidates2;
23596
23607
  }
23597
23608
  const home = process.env["HOME"];
23598
23609
  const candidates = ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/usr/bin/chromium-browser", "/usr/bin/chromium"];
23599
- if (home) candidates.push(...findPlaywrightChromium(path22.join(home, ".cache", "ms-playwright")));
23610
+ if (home) candidates.push(...findPlaywrightChromium(path23.join(home, ".cache", "ms-playwright")));
23600
23611
  return candidates;
23601
23612
  }
23602
23613
  function resolveBrowserExecutablePath(explicit) {
@@ -24011,7 +24022,7 @@ var init_notes = __esm({
24011
24022
 
24012
24023
  // src/ts_refs.ts
24013
24024
  import { createRequire as createRequire6 } from "node:module";
24014
- import * as path23 from "node:path";
24025
+ import * as path24 from "node:path";
24015
24026
  function loadTs() {
24016
24027
  if (_tsOverride !== void 0) return _tsOverride;
24017
24028
  if (!_tsLoadAttempted) {
@@ -24031,7 +24042,7 @@ function loadError() {
24031
24042
  return _tsError;
24032
24043
  }
24033
24044
  function isTsPath(filePath) {
24034
- return TS_EXTENSIONS.has(path23.extname(filePath).toLowerCase());
24045
+ return TS_EXTENSIONS.has(path24.extname(filePath).toLowerCase());
24035
24046
  }
24036
24047
  function resolveTypedRefs(input) {
24037
24048
  const ts = loadTs();
@@ -24061,7 +24072,7 @@ function resolveTypedRefs(input) {
24061
24072
  if (defSymbol === null) return null;
24062
24073
  const out2 = [];
24063
24074
  for (const ref2 of input.candidates) {
24064
- if (!TS_JS_EXTENSIONS.has(path23.extname(ref2.filePath).toLowerCase())) {
24075
+ if (!TS_JS_EXTENSIONS.has(path24.extname(ref2.filePath).toLowerCase())) {
24065
24076
  out2.push(ref2);
24066
24077
  continue;
24067
24078
  }
@@ -24087,12 +24098,12 @@ function buildScopedProgram(ts, rootNames, searchFrom) {
24087
24098
  resolveJsonModule: true,
24088
24099
  esModuleInterop: true
24089
24100
  };
24090
- const configPath2 = ts.findConfigFile(path23.dirname(searchFrom), ts.sys.fileExists, "tsconfig.json");
24101
+ const configPath2 = ts.findConfigFile(path24.dirname(searchFrom), ts.sys.fileExists, "tsconfig.json");
24091
24102
  if (configPath2 !== void 0) {
24092
24103
  try {
24093
24104
  const raw = ts.readConfigFile(configPath2, ts.sys.readFile);
24094
24105
  if (raw.error === void 0) {
24095
- const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path23.dirname(configPath2));
24106
+ const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path24.dirname(configPath2));
24096
24107
  Object.assign(options, parsed.options);
24097
24108
  }
24098
24109
  } catch {
@@ -24196,7 +24207,7 @@ var init_ts_refs = __esm({
24196
24207
 
24197
24208
  // src/read_commands.ts
24198
24209
  import * as fs18 from "node:fs";
24199
- import * as path24 from "node:path";
24210
+ import * as path25 from "node:path";
24200
24211
  function fileExists(p) {
24201
24212
  try {
24202
24213
  fs18.statSync(p);
@@ -24263,7 +24274,7 @@ function verifyPin(p, pinned) {
24263
24274
  verifyPinnedIdentity(p, pinned);
24264
24275
  }
24265
24276
  function indexFileSyncPinned(resolvedPath, dbPath) {
24266
- const pinned = activePins?.get(pinKey(path24.resolve(resolvedPath)));
24277
+ const pinned = activePins?.get(pinKey(path25.resolve(resolvedPath)));
24267
24278
  if (pinned === void 0) {
24268
24279
  indexFileSync(resolvedPath, dbPath);
24269
24280
  return;
@@ -24285,7 +24296,7 @@ function indexFileSyncPinned(resolvedPath, dbPath) {
24285
24296
  indexFileSync(resolvedPath, dbPath, bytes);
24286
24297
  }
24287
24298
  function readFileText(p) {
24288
- const pinned = activePins?.get(pinKey(path24.resolve(p)));
24299
+ const pinned = activePins?.get(pinKey(path25.resolve(p)));
24289
24300
  try {
24290
24301
  if (pinned === ABSENT_PIN) {
24291
24302
  verifyStillAbsent(p);
@@ -24299,7 +24310,7 @@ function readFileText(p) {
24299
24310
  }
24300
24311
  }
24301
24312
  function readFileBytes(p) {
24302
- const pinned = activePins?.get(pinKey(path24.resolve(p)));
24313
+ const pinned = activePins?.get(pinKey(path25.resolve(p)));
24303
24314
  try {
24304
24315
  if (pinned === ABSENT_PIN) {
24305
24316
  verifyStillAbsent(p);
@@ -25017,7 +25028,7 @@ ${sub.text}`);
25017
25028
  return { text, code: 1 };
25018
25029
  }
25019
25030
  function resolveAgainstProjectRoot(file2, projectRoot) {
25020
- return projectRoot !== void 0 && !path24.isAbsolute(file2) ? path24.resolve(projectRoot, file2) : file2;
25031
+ return projectRoot !== void 0 && !path25.isAbsolute(file2) ? path25.resolve(projectRoot, file2) : file2;
25021
25032
  }
25022
25033
  function runSection(opts) {
25023
25034
  const crossFilePairs = parseCrossFileMultiSpec(opts.spec);
@@ -25098,7 +25109,7 @@ function runSectionCrossFile(pairs, opts) {
25098
25109
  textBlocks.push(`${key}:
25099
25110
  ${sub.text}`);
25100
25111
  }
25101
- const resolvePath = (f) => opts.projectRoot !== void 0 && !path24.isAbsolute(f) ? path24.resolve(opts.projectRoot, f) : f;
25112
+ const resolvePath = (f) => opts.projectRoot !== void 0 && !path25.isAbsolute(f) ? path25.resolve(opts.projectRoot, f) : f;
25102
25113
  const text = opts.json === true ? JSON.stringify(jsonOut, null, 2) : textBlocks.join("\n\n");
25103
25114
  if (anyFound) {
25104
25115
  const fullSourceBytes = sumFileSizes(Array.from(distinctFiles, resolvePath));
@@ -26071,7 +26082,7 @@ function runConflicts(opts) {
26071
26082
  if (opts.path === void 0) {
26072
26083
  files = walkProject(process.cwd()).files;
26073
26084
  } else {
26074
- const abs = path24.resolve(opts.path);
26085
+ const abs = path25.resolve(opts.path);
26075
26086
  let stat2;
26076
26087
  try {
26077
26088
  stat2 = fs18.statSync(abs);
@@ -26465,6 +26476,10 @@ function buildChangedRefHint(cwd, ref2) {
26465
26476
  }
26466
26477
  function runChanged(opts = {}) {
26467
26478
  const ref2 = opts.ref ?? "HEAD~5";
26479
+ if (ref2.startsWith("-")) {
26480
+ emitErr(`Refusing a git ref that starts with '-': ${ref2}`);
26481
+ return 1;
26482
+ }
26468
26483
  const cwd = opts.projectRoot ?? process.cwd();
26469
26484
  const projectRoot = resolveProjectRoot({ project: cwd });
26470
26485
  let changedFiles;
@@ -26829,7 +26844,7 @@ function runGrep(opts) {
26829
26844
  try {
26830
26845
  for (const entry of fs18.readdirSync(dir)) {
26831
26846
  if (entry.startsWith(".")) continue;
26832
- const full = path24.join(dir, entry);
26847
+ const full = path25.join(dir, entry);
26833
26848
  let lst;
26834
26849
  try {
26835
26850
  lst = fs18.lstatSync(full);
@@ -26871,14 +26886,14 @@ function runGrep(opts) {
26871
26886
  }
26872
26887
  const stat2 = fs18.statSync(searchPath);
26873
26888
  if (stat2.isDirectory()) {
26874
- const pinned = activePins?.get(pinKey(path24.resolve(searchPath)));
26889
+ const pinned = activePins?.get(pinKey(path25.resolve(searchPath)));
26875
26890
  if (pinned !== void 0) verifyPin(searchPath, pinned);
26876
26891
  let boundaryReal;
26877
26892
  try {
26878
26893
  boundaryReal = fs18.realpathSync(searchPath);
26879
26894
  } catch (err2) {
26880
26895
  if (pinned === void 0) {
26881
- boundaryReal = path24.resolve(searchPath);
26896
+ boundaryReal = path25.resolve(searchPath);
26882
26897
  } else {
26883
26898
  throw new ConfinementIdentityError(
26884
26899
  `refused: "${searchPath}" could not be resolved after validation (${String(err2)}). The path may have been replaced or redirected after the confinement check, so the search was not performed.`
@@ -27009,7 +27024,7 @@ function runConfigGet(opts) {
27009
27024
  emit2(value);
27010
27025
  return 0;
27011
27026
  }
27012
- const ext2 = path24.extname(opts.file).toLowerCase();
27027
+ const ext2 = path25.extname(opts.file).toLowerCase();
27013
27028
  if (ext2 === ".json") {
27014
27029
  try {
27015
27030
  let obj = JSON.parse(text);
@@ -27127,7 +27142,7 @@ function runExports(opts) {
27127
27142
  names.push(s.name);
27128
27143
  }
27129
27144
  }
27130
- const ext2 = path24.extname(opts.file).toLowerCase();
27145
+ const ext2 = path25.extname(opts.file).toLowerCase();
27131
27146
  const text = readFileText(diskPath);
27132
27147
  if (text === null && symbols.length === 0) {
27133
27148
  emitErr(`Could not read: ${opts.file}`);
@@ -27465,9 +27480,9 @@ function extractImports(text, ext2) {
27465
27480
  return found;
27466
27481
  }
27467
27482
  function importsExtensionFor(filePath) {
27468
- const base = path24.basename(filePath).toLowerCase();
27483
+ const base = path25.basename(filePath).toLowerCase();
27469
27484
  if (base === "makefile" || base === "gnumakefile" || base === "bsdmakefile") return ".mk";
27470
- return path24.extname(filePath);
27485
+ return path25.extname(filePath);
27471
27486
  }
27472
27487
  function runImports(opts) {
27473
27488
  const multiFiles = parseMultiFileSpec(opts.file);
@@ -27558,7 +27573,7 @@ async function runSemantic(query, opts) {
27558
27573
  }
27559
27574
  const n = opts.limit !== void 0 && Number.isFinite(opts.limit) ? opts.limit : 20;
27560
27575
  if (opts.projectRoot !== void 0) {
27561
- if (!path24.isAbsolute(opts.projectRoot) || !fs18.existsSync(opts.projectRoot) || !fs18.statSync(opts.projectRoot).isDirectory()) {
27576
+ if (!path25.isAbsolute(opts.projectRoot) || !fs18.existsSync(opts.projectRoot) || !fs18.statSync(opts.projectRoot).isDirectory()) {
27562
27577
  const message = `token-goat: projectRoot must be an absolute, existing directory, got '${opts.projectRoot}'`;
27563
27578
  if (opts.json === true) {
27564
27579
  return { text: JSON.stringify({ error: message }, null, 2), code: 1 };
@@ -27810,14 +27825,14 @@ var init_read_commands = __esm({
27810
27825
  });
27811
27826
 
27812
27827
  // src/repomap.ts
27813
- import * as path25 from "path";
27828
+ import * as path26 from "path";
27814
27829
  function getTrackedFiles(cwd = process.cwd()) {
27815
27830
  try {
27816
27831
  const result = runGit(["ls-files"], { cwd });
27817
27832
  if (result.exitCode !== 0 || !result.stdout) {
27818
27833
  return [];
27819
27834
  }
27820
- return result.stdout.split("\n").filter((line) => line.trim().length > 0).map((rel) => path25.join(cwd, rel));
27835
+ return result.stdout.split("\n").filter((line) => line.trim().length > 0).map((rel) => path26.join(cwd, rel));
27821
27836
  } catch {
27822
27837
  return [];
27823
27838
  }
@@ -27833,7 +27848,7 @@ var init_repomap = __esm({
27833
27848
  // src/graph_commands.ts
27834
27849
  import * as fs19 from "node:fs";
27835
27850
  import * as os4 from "node:os";
27836
- import * as path26 from "node:path";
27851
+ import * as path27 from "node:path";
27837
27852
  import { execFileSync, spawnSync as spawnSync3 } from "node:child_process";
27838
27853
  import { randomUUID } from "node:crypto";
27839
27854
  function emit3(text) {
@@ -28126,7 +28141,19 @@ function runImpact(opts) {
28126
28141
  }
28127
28142
  }
28128
28143
  hops.delete(rootName);
28129
- const sorted = [...hops.entries()].sort(compareHopEntries).slice(0, top);
28144
+ const allSorted = [...hops.entries()].sort(compareHopEntries);
28145
+ const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
28146
+ const grepped = matchesGrep !== void 0 ? allSorted.filter(([symbol3]) => matchesGrep(symbol3)) : allSorted;
28147
+ const sorted = grepped.slice(0, top);
28148
+ if (matchesGrep !== void 0 && sorted.length === 0 && allSorted.length > 0) {
28149
+ if (opts.json === true) {
28150
+ emitErr2(grepFilteredToEmptyNotice(allSorted.length, opts.grep, "impacted symbol", "impacted symbols"));
28151
+ emit3(JSON.stringify([], null, 2));
28152
+ return 0;
28153
+ }
28154
+ emit3(grepFilteredToEmptyNotice(allSorted.length, opts.grep, "impacted symbol", "impacted symbols"));
28155
+ return 0;
28156
+ }
28130
28157
  if (sorted.length === 0) {
28131
28158
  if (opts.excludeTests === true && suppressedCount > 0) {
28132
28159
  if (opts.json === true) {
@@ -28262,17 +28289,17 @@ function runDeps(opts) {
28262
28289
  }
28263
28290
  const ext2 = importsExtensionFor(opts.file);
28264
28291
  const raw = extractImports(text, ext2);
28265
- const dir = path26.dirname(opts.file);
28292
+ const dir = path27.dirname(opts.file);
28266
28293
  const internal = [];
28267
28294
  const external = [];
28268
28295
  for (const imp of raw) {
28269
28296
  if (imp.startsWith("./") || imp.startsWith("../")) {
28270
- const base = path26.resolve(dir, imp);
28297
+ const base = path27.resolve(dir, imp);
28271
28298
  let resolved = imp;
28272
28299
  if (fs19.existsSync(base) && fs19.statSync(base).isFile()) {
28273
28300
  resolved = base;
28274
28301
  } else {
28275
- const baseExt = path26.extname(base);
28302
+ const baseExt = path27.extname(base);
28276
28303
  const bareBase = SOURCE_EXTENSIONS.includes(baseExt) ? base.slice(0, -baseExt.length) : base;
28277
28304
  for (const srcExt of SOURCE_EXTENSIONS) {
28278
28305
  const candidate = bareBase + srcExt;
@@ -28283,7 +28310,7 @@ function runDeps(opts) {
28283
28310
  }
28284
28311
  if (resolved === imp && fs19.existsSync(base) && fs19.statSync(base).isDirectory()) {
28285
28312
  for (const srcExt of SOURCE_EXTENSIONS) {
28286
- const candidate = path26.join(base, "index" + srcExt);
28313
+ const candidate = path27.join(base, "index" + srcExt);
28287
28314
  if (fs19.existsSync(candidate)) {
28288
28315
  resolved = candidate;
28289
28316
  break;
@@ -28299,7 +28326,7 @@ function runDeps(opts) {
28299
28326
  }
28300
28327
  }
28301
28328
  const rootDir = resolveProjectRoot({ project: process.cwd() });
28302
- const displayInternal = internal.map((i) => path26.isAbsolute(i) ? toDisplayPath(rootDir, normalizePath(i)) : i);
28329
+ const displayInternal = internal.map((i) => path27.isAbsolute(i) ? toDisplayPath(rootDir, normalizePath(i)) : i);
28303
28330
  const preFilterCount = displayInternal.length + external.length;
28304
28331
  const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
28305
28332
  const filteredInternal = matchesGrep !== void 0 ? displayInternal.filter((i) => matchesGrep(i)) : displayInternal;
@@ -28692,15 +28719,15 @@ function runArch(opts) {
28692
28719
  const importedBy = /* @__PURE__ */ new Map();
28693
28720
  const resolveRelImport = (fromFile, spec) => {
28694
28721
  if (!spec.startsWith(".")) return null;
28695
- const dir = path26.dirname(fromFile);
28722
+ const dir = path27.dirname(fromFile);
28696
28723
  const strippedSpec = spec.replace(/\.(m?js|cjs)$/, "");
28697
- const base = path26.resolve(dir, strippedSpec);
28724
+ const base = path27.resolve(dir, strippedSpec);
28698
28725
  for (const ext2 of ["", ".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs", ".cjs", ".cts", ".py"]) {
28699
28726
  const candidate = base + ext2;
28700
28727
  const match2 = filesByFoldedPath.get(foldPath(candidate));
28701
28728
  if (match2 !== void 0) return match2;
28702
28729
  }
28703
- const idx = path26.join(base, "index");
28730
+ const idx = path27.join(base, "index");
28704
28731
  for (const ext2 of [".ts", ".js", ".tsx", ".jsx", ".mts", ".cts"]) {
28705
28732
  const candidate = idx + ext2;
28706
28733
  const match2 = filesByFoldedPath.get(foldPath(candidate));
@@ -28825,7 +28852,7 @@ ANSWER:`;
28825
28852
  try {
28826
28853
  let askArgs;
28827
28854
  if (isCodex) {
28828
- codexOutPath = path26.join(os4.tmpdir(), `tg-ask-${process.pid}-${randomUUID()}.txt`);
28855
+ codexOutPath = path27.join(os4.tmpdir(), `tg-ask-${process.pid}-${randomUUID()}.txt`);
28829
28856
  askArgs = ["exec", "--ephemeral", "--output-last-message", codexOutPath];
28830
28857
  } else {
28831
28858
  askArgs = ["--print", "--bare", "--no-session-persistence"];
@@ -29021,12 +29048,12 @@ var init_graph_commands = __esm({
29021
29048
 
29022
29049
  // src/project_memory.ts
29023
29050
  import * as fs20 from "node:fs";
29024
- import * as path27 from "node:path";
29051
+ import * as path28 from "node:path";
29025
29052
  function ordinal(a, b) {
29026
29053
  return a < b ? -1 : a > b ? 1 : 0;
29027
29054
  }
29028
29055
  function memoryPath(projectHash2) {
29029
- return path27.join(dataDir(), "projects", `${projectHash2}_memory.toml`);
29056
+ return path28.join(dataDir(), "projects", `${projectHash2}_memory.toml`);
29030
29057
  }
29031
29058
  function validateKey(key) {
29032
29059
  if (!KEY_RE.test(key)) {
@@ -29085,7 +29112,7 @@ function save(filePath, entries) {
29085
29112
  lines2.push(`${k} = "${escaped}"`);
29086
29113
  }
29087
29114
  const content = lines2.length > 0 ? lines2.join("\n") + "\n" : "";
29088
- const dir = path27.dirname(filePath);
29115
+ const dir = path28.dirname(filePath);
29089
29116
  ensureDirSync(dir);
29090
29117
  atomicWriteText(filePath, content);
29091
29118
  }
@@ -29095,7 +29122,7 @@ function loadEntries(projectHash2) {
29095
29122
  function setEntry(projectHash2, key, value) {
29096
29123
  validateKey(key);
29097
29124
  const p = memoryPath(projectHash2);
29098
- const dir = path27.dirname(p);
29125
+ const dir = path28.dirname(p);
29099
29126
  ensureDirSync(dir);
29100
29127
  const doSet = () => {
29101
29128
  const entries = loadRaw(p);
@@ -29508,7 +29535,7 @@ var init_session = __esm({
29508
29535
 
29509
29536
  // src/text_commands.ts
29510
29537
  import * as fs22 from "fs";
29511
- import * as path28 from "path";
29538
+ import * as path29 from "path";
29512
29539
  function readInput(src) {
29513
29540
  if (src !== void 0) return fs22.readFileSync(src, "utf8");
29514
29541
  return fs22.readFileSync(0, "utf8");
@@ -29559,7 +29586,7 @@ function collectTodoFiles(patterns) {
29559
29586
  if (patterns.length > 0) {
29560
29587
  const results = [];
29561
29588
  for (const p of patterns) {
29562
- const abs = path28.resolve(p);
29589
+ const abs = path29.resolve(p);
29563
29590
  try {
29564
29591
  const stat2 = fs22.statSync(abs);
29565
29592
  if (stat2.isDirectory()) {
@@ -29817,7 +29844,7 @@ function isProjectFrame(framePath, cwd) {
29817
29844
  if (framePath.includes("/rustc/")) return false;
29818
29845
  if (framePath.includes(".cargo/registry") || framePath.includes(".cargo\\registry")) return false;
29819
29846
  if (/^<.+>$/.test(framePath)) return false;
29820
- if (!path28.isAbsolute(framePath) && !framePath.startsWith("..")) return true;
29847
+ if (!path29.isAbsolute(framePath) && !framePath.startsWith("..")) return true;
29821
29848
  return false;
29822
29849
  }
29823
29850
  function resolveFrameSymbol(frame, projectRoot) {
@@ -30003,17 +30030,17 @@ function findLockfile(startPath) {
30003
30030
  if (stat2 !== void 0 && stat2.isFile()) {
30004
30031
  return { file: startPath, others: [] };
30005
30032
  }
30006
- const dir = stat2 !== void 0 && stat2.isDirectory() ? startPath : path28.dirname(startPath);
30033
+ const dir = stat2 !== void 0 && stat2.isDirectory() ? startPath : path29.dirname(startPath);
30007
30034
  const found = [];
30008
30035
  for (const name2 of LOCK_PRIORITY) {
30009
- const candidate = path28.join(dir, name2);
30036
+ const candidate = path29.join(dir, name2);
30010
30037
  if (fs22.existsSync(candidate)) found.push(candidate);
30011
30038
  }
30012
30039
  try {
30013
30040
  const entries = fs22.readdirSync(dir);
30014
30041
  for (const e of entries) {
30015
30042
  if (/^requirements.*\.txt$/.test(e)) {
30016
- const p = path28.join(dir, e);
30043
+ const p = path29.join(dir, e);
30017
30044
  if (!found.includes(p)) found.push(p);
30018
30045
  }
30019
30046
  }
@@ -30210,7 +30237,7 @@ function parsePnpmLock(content) {
30210
30237
  return deps;
30211
30238
  }
30212
30239
  function parseLockFile(filePath) {
30213
- const base = path28.basename(filePath);
30240
+ const base = path29.basename(filePath);
30214
30241
  const content = fs22.readFileSync(filePath, "utf8");
30215
30242
  if (base === "package-lock.json") return { format: "npm", deps: parsePackageLockJson(content) };
30216
30243
  if (base === "yarn.lock") return { format: "yarn", deps: parseYarnLock(content) };
@@ -30326,7 +30353,7 @@ Depended on by direct/top-level deps (${dependedOnBy.length}):
30326
30353
  `);
30327
30354
  }
30328
30355
  function cmdLockdeps(filePath, opts) {
30329
- const target = filePath !== void 0 ? path28.resolve(filePath) : process.cwd();
30356
+ const target = filePath !== void 0 ? path29.resolve(filePath) : process.cwd();
30330
30357
  const found = findLockfile(target);
30331
30358
  if (found === null) {
30332
30359
  throw new Error("No lockfile found. Expected one of: " + LOCK_PRIORITY.join(", ") + ", requirements*.txt");
@@ -30414,7 +30441,7 @@ function cmdNote(action, key, value, opts) {
30414
30441
  throw new Error(`Unknown note action: ${action}. Use: set, get, unset, list, clear`);
30415
30442
  }
30416
30443
  function loadAllSessionReadCounts() {
30417
- const sessionsDir = path28.join(tokenGoatHome(), "sessions");
30444
+ const sessionsDir = path29.join(tokenGoatHome(), "sessions");
30418
30445
  const totals = /* @__PURE__ */ new Map();
30419
30446
  let entries;
30420
30447
  try {
@@ -30424,7 +30451,7 @@ function loadAllSessionReadCounts() {
30424
30451
  }
30425
30452
  for (const entry of entries) {
30426
30453
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
30427
- const filePath = path28.join(sessionsDir, entry.name);
30454
+ const filePath = path29.join(sessionsDir, entry.name);
30428
30455
  let raw;
30429
30456
  try {
30430
30457
  raw = JSON.parse(fs22.readFileSync(filePath, "utf8"));
@@ -30512,8 +30539,8 @@ function detectWalkMode(cwd) {
30512
30539
  if (project?.marker === ".git") return "git";
30513
30540
  let cur = cwd;
30514
30541
  while (true) {
30515
- if (fs22.existsSync(path28.join(cur, ".git"))) return "git";
30516
- const parent = path28.dirname(cur);
30542
+ if (fs22.existsSync(path29.join(cur, ".git"))) return "git";
30543
+ const parent = path29.dirname(cur);
30517
30544
  if (parent === cur) break;
30518
30545
  cur = parent;
30519
30546
  }
@@ -31194,8 +31221,9 @@ function buildGuidanceBody(fallbackToolClause) {
31194
31221
  "- pulling one value or subtree out of a JSON/YAML file (manifest, lockfile, spec, config) \u2192 `json-query file 'a.b.c'` / `yaml-query file 'a.b.c'`",
31195
31222
  "- opening an image to check its dimensions, format, or size \u2192 `image-meta file`",
31196
31223
  "- opening a screenshot, diagram, or scan to read the text in it \u2192 `image-text file`",
31224
+ "- opening a PDF or Office document \u2192 inspect its format first, then read a narrow slice: PDF `pdf-meta`/`pdf-outline` then `pdf-extract`; Word `docx-outline` then `docx-text`; PowerPoint `pptx-outline` then `pptx-slide`/`pptx-notes`; Excel `xlsx-sheets` then `xlsx-head`/`xlsx-range`/`xlsx-query`",
31197
31225
  "",
31198
- 'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`, `json-outline file`/`yaml-outline`, `bash-output`/`web-output`/`mcp-output`, `gdrive-sections <file-id>`, `image-meta file`/`image-text file`.',
31226
+ 'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`, `json-outline file`/`yaml-outline`, `bash-output`/`web-output`/`mcp-output`, `gdrive-sections <file-id>`, `image-meta file`/`image-text file`, `pdf-meta`/`pdf-outline`/`pdf-extract`, `docx-outline`/`docx-text`, `pptx-outline`/`pptx-slide`/`pptx-notes`/`pptx-text`, `xlsx-sheets`/`xlsx-head`/`xlsx-range`/`xlsx-query`.',
31199
31227
  "",
31200
31228
  "Sub-agent briefs must carry this gate verbatim: a sub-agent inherits none of this context and its reads spend the same token budget.",
31201
31229
  "",
@@ -31215,7 +31243,7 @@ var init_guidance_block = __esm({
31215
31243
  // src/install.ts
31216
31244
  import * as fs24 from "node:fs";
31217
31245
  import * as os5 from "node:os";
31218
- import * as path29 from "node:path";
31246
+ import * as path30 from "node:path";
31219
31247
  function anchoredMarkerPattern(marker) {
31220
31248
  const escaped = escapeRegExp(marker);
31221
31249
  return new RegExp(`(?<![a-zA-Z0-9_-])${escaped}(?![a-zA-Z0-9_-])`);
@@ -31224,7 +31252,7 @@ function isTokenGoatHookCommand(command) {
31224
31252
  return HOOK_MARKER_PATTERNS.some((pattern) => pattern.test(command));
31225
31253
  }
31226
31254
  function claudeHookScriptPath() {
31227
- return path29.join(os5.homedir(), ".claude", "hooks", "token-goat-shim.js");
31255
+ return path30.join(os5.homedir(), ".claude", "hooks", "token-goat-shim.js");
31228
31256
  }
31229
31257
  function anyScopeReferencesShim(scriptPath, currentScope, alreadyStripped) {
31230
31258
  const referencesIn = (map3) => {
@@ -31246,8 +31274,8 @@ function anyScopeReferencesShim(scriptPath, currentScope, alreadyStripped) {
31246
31274
  }
31247
31275
  function settingsPath(scope) {
31248
31276
  const root = scope === "user" ? os5.homedir() : normalizeDarwinSystemAlias(process.cwd());
31249
- const base = path29.join(root, ".claude");
31250
- return path29.join(base, "settings.json");
31277
+ const base = path30.join(root, ".claude");
31278
+ return path30.join(base, "settings.json");
31251
31279
  }
31252
31280
  function readSettings(p, opts = {}) {
31253
31281
  let raw;
@@ -31291,7 +31319,7 @@ function installHooks(scope = "user") {
31291
31319
  const settings = readSettings(p, { strict: true });
31292
31320
  const hooks = settings.hooks ?? {};
31293
31321
  const scriptPath = claudeHookScriptPath();
31294
- ensureDirSync(path29.dirname(scriptPath));
31322
+ ensureDirSync(path30.dirname(scriptPath));
31295
31323
  const scriptChanged = writeIfDifferent(scriptPath, CLAUDECODE_HOOK_SCRIPT);
31296
31324
  let settingsChanged = false;
31297
31325
  for (const [eventKey, eventArg] of HOOK_EVENT_MAP) {
@@ -31384,7 +31412,7 @@ function isInstalled(scope = "user") {
31384
31412
  return true;
31385
31413
  }
31386
31414
  function claudeMdPath() {
31387
- return path29.join(os5.homedir(), ".claude", "CLAUDE.md");
31415
+ return path30.join(os5.homedir(), ".claude", "CLAUDE.md");
31388
31416
  }
31389
31417
  function buildClaudeMdBlock() {
31390
31418
  return buildGuidanceBlock({
@@ -31408,8 +31436,8 @@ function uninstallClaudeMd() {
31408
31436
  return stripClaudeMdBlock(claudeMdPath());
31409
31437
  }
31410
31438
  function findStrayClaudeMdBlocks(searchRoot) {
31411
- const root = searchRoot ?? path29.join(os5.homedir(), ".claude");
31412
- const canonical = path29.resolve(claudeMdPath());
31439
+ const root = searchRoot ?? path30.join(os5.homedir(), ".claude");
31440
+ const canonical = path30.resolve(claudeMdPath());
31413
31441
  const found = [];
31414
31442
  if (!fs24.existsSync(root)) return found;
31415
31443
  const SKIP_DIRS2 = /* @__PURE__ */ new Set(["node_modules", ".git"]);
@@ -31432,13 +31460,13 @@ function findStrayClaudeMdBlocks(searchRoot) {
31432
31460
  return;
31433
31461
  }
31434
31462
  for (const entry of entries) {
31435
- const full = path29.join(dir, entry.name);
31463
+ const full = path30.join(dir, entry.name);
31436
31464
  if (entry.isDirectory()) {
31437
31465
  if (!SKIP_DIRS2.has(entry.name)) walk(full, depth + 1);
31438
31466
  continue;
31439
31467
  }
31440
31468
  if (!entry.isFile() || !entry.name.toLowerCase().endsWith(".md")) continue;
31441
- if (path29.resolve(full) === canonical) continue;
31469
+ if (path30.resolve(full) === canonical) continue;
31442
31470
  let text;
31443
31471
  try {
31444
31472
  text = fs24.readFileSync(full, "utf8");
@@ -31452,10 +31480,10 @@ function findStrayClaudeMdBlocks(searchRoot) {
31452
31480
  return found.sort();
31453
31481
  }
31454
31482
  function skillDir() {
31455
- return path29.join(os5.homedir(), ".claude", "skills", "token-goat");
31483
+ return path30.join(os5.homedir(), ".claude", "skills", "token-goat");
31456
31484
  }
31457
31485
  function skillPath() {
31458
- return path29.join(skillDir(), "SKILL.md");
31486
+ return path30.join(skillDir(), "SKILL.md");
31459
31487
  }
31460
31488
  function installSkill() {
31461
31489
  const p = skillPath();
@@ -31538,15 +31566,15 @@ var init_matcher_group = __esm({
31538
31566
  // src/bridges/codex_install.ts
31539
31567
  import * as fs25 from "node:fs";
31540
31568
  import * as os6 from "node:os";
31541
- import * as path30 from "node:path";
31569
+ import * as path31 from "node:path";
31542
31570
  function codexConfigPath() {
31543
- return path30.join(os6.homedir(), ".codex", "config.toml");
31571
+ return path31.join(os6.homedir(), ".codex", "config.toml");
31544
31572
  }
31545
31573
  function codexAgentsPath() {
31546
- return path30.join(os6.homedir(), ".codex", "AGENTS.md");
31574
+ return path31.join(os6.homedir(), ".codex", "AGENTS.md");
31547
31575
  }
31548
31576
  function codexHookScriptPath() {
31549
- return path30.join(os6.homedir(), ".codex", "hooks", "token-goat-shim.js");
31577
+ return path31.join(os6.homedir(), ".codex", "hooks", "token-goat-shim.js");
31550
31578
  }
31551
31579
  function readCodexConfig(p, opts = {}) {
31552
31580
  let raw;
@@ -31583,7 +31611,7 @@ function installCodex() {
31583
31611
  const configPath2 = codexConfigPath();
31584
31612
  const agentsPath = codexAgentsPath();
31585
31613
  const scriptPath = codexHookScriptPath();
31586
- ensureDirSync(path30.dirname(scriptPath));
31614
+ ensureDirSync(path31.dirname(scriptPath));
31587
31615
  atomicWriteText(scriptPath, CODEX_HOOK_SCRIPT);
31588
31616
  const config2 = readCodexConfig(configPath2, { strict: true });
31589
31617
  const hooks = config2.hooks ?? {};
@@ -31618,7 +31646,7 @@ function installCodex() {
31618
31646
  const agentsChanged = writeAgentsBlock(agentsPath);
31619
31647
  if (hooksChanged) {
31620
31648
  config2.hooks = hooks;
31621
- ensureDirSync(path30.dirname(configPath2));
31649
+ ensureDirSync(path31.dirname(configPath2));
31622
31650
  backupFile(configPath2);
31623
31651
  atomicWriteText(configPath2, stringify(config2));
31624
31652
  }
@@ -32052,29 +32080,29 @@ main()
32052
32080
  // src/bridges/copilot_cli_install.ts
32053
32081
  import * as fs26 from "node:fs";
32054
32082
  import * as os7 from "node:os";
32055
- import * as path31 from "node:path";
32083
+ import * as path32 from "node:path";
32056
32084
  function copilotCliUserRoot() {
32057
32085
  const override = process.env["COPILOT_HOME"];
32058
- if (override !== void 0 && override.trim() !== "") return path31.resolve(override);
32059
- return path31.join(os7.homedir(), ".copilot");
32086
+ if (override !== void 0 && override.trim() !== "") return path32.resolve(override);
32087
+ return path32.join(os7.homedir(), ".copilot");
32060
32088
  }
32061
32089
  function copilotCliUserHooksDir() {
32062
- return path31.join(copilotCliUserRoot(), "hooks");
32090
+ return path32.join(copilotCliUserRoot(), "hooks");
32063
32091
  }
32064
32092
  function copilotCliProjectHooksDir() {
32065
- return path31.join(process.cwd(), ".github", "hooks");
32093
+ return path32.join(process.cwd(), ".github", "hooks");
32066
32094
  }
32067
32095
  function copilotCliHooksDir(opts = {}) {
32068
32096
  return opts.local === true ? copilotCliProjectHooksDir() : copilotCliUserHooksDir();
32069
32097
  }
32070
32098
  function copilotCliConfigPath(opts = {}) {
32071
- return path31.join(copilotCliHooksDir(opts), "token-goat.json");
32099
+ return path32.join(copilotCliHooksDir(opts), "token-goat.json");
32072
32100
  }
32073
32101
  function copilotCliScriptPath(opts = {}) {
32074
- return path31.join(copilotCliHooksDir(opts), "token-goat-shim.js");
32102
+ return path32.join(copilotCliHooksDir(opts), "token-goat-shim.js");
32075
32103
  }
32076
32104
  function copilotCliInstructionsPath(opts = {}) {
32077
- return path31.join(path31.dirname(copilotCliHooksDir(opts)), "copilot-instructions.md");
32105
+ return path32.join(path32.dirname(copilotCliHooksDir(opts)), "copilot-instructions.md");
32078
32106
  }
32079
32107
  function buildCopilotInstructionsBlock() {
32080
32108
  return stripInlineCodeSpans(
@@ -32309,15 +32337,15 @@ main().catch((err) => {
32309
32337
  // src/bridges/grok_install.ts
32310
32338
  import * as fs27 from "node:fs";
32311
32339
  import * as os8 from "node:os";
32312
- import * as path32 from "node:path";
32340
+ import * as path33 from "node:path";
32313
32341
  function grokHooksDir() {
32314
- return path32.join(os8.homedir(), ".grok", "hooks");
32342
+ return path33.join(os8.homedir(), ".grok", "hooks");
32315
32343
  }
32316
32344
  function grokConfigPath() {
32317
- return path32.join(grokHooksDir(), "token-goat.json");
32345
+ return path33.join(grokHooksDir(), "token-goat.json");
32318
32346
  }
32319
32347
  function grokHookScriptPath() {
32320
- return path32.join(grokHooksDir(), "token-goat-shim.js");
32348
+ return path33.join(grokHooksDir(), "token-goat-shim.js");
32321
32349
  }
32322
32350
  function buildConfig2(scriptPath) {
32323
32351
  const hooks = {};
@@ -32374,14 +32402,14 @@ var init_grok_install = __esm({
32374
32402
  // src/bridges/vscode_install.ts
32375
32403
  import * as fs28 from "node:fs";
32376
32404
  import * as os9 from "node:os";
32377
- import * as path33 from "node:path";
32405
+ import * as path34 from "node:path";
32378
32406
  import { createRequire as createRequire7 } from "node:module";
32379
32407
  import { fileURLToPath as fileURLToPath2 } from "node:url";
32380
32408
  function bundledCliPath() {
32381
- const here = path33.dirname(fileURLToPath2(import.meta.url));
32382
- const bundled = path33.join(here, "token-goat.mjs");
32409
+ const here = path34.dirname(fileURLToPath2(import.meta.url));
32410
+ const bundled = path34.join(here, "token-goat.mjs");
32383
32411
  if (fs28.existsSync(bundled)) return bundled;
32384
- return path33.resolve(here, "..", "..", "dist", "token-goat.mjs");
32412
+ return path34.resolve(here, "..", "..", "dist", "token-goat.mjs");
32385
32413
  }
32386
32414
  function managedServer() {
32387
32415
  return {
@@ -32396,24 +32424,24 @@ function isManagedServer(value) {
32396
32424
  if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
32397
32425
  const entry = value;
32398
32426
  const args = entry["args"];
32399
- return entry["type"] === "stdio" && Array.isArray(args) && args.length === 2 && typeof args[0] === "string" && path33.basename(args[0]).toLowerCase() === "token-goat.mjs" && args[1] === "mcp-serve";
32427
+ return entry["type"] === "stdio" && Array.isArray(args) && args.length === 2 && typeof args[0] === "string" && path34.basename(args[0]).toLowerCase() === "token-goat.mjs" && args[1] === "mcp-serve";
32400
32428
  }
32401
32429
  function vscodeUserConfigDir() {
32402
32430
  if (process.platform === "win32") {
32403
32431
  const appData = process.env["APPDATA"];
32404
- const base = appData !== void 0 && appData.trim() !== "" ? appData : path33.join(os9.homedir(), "AppData", "Roaming");
32405
- return path33.join(base, "Code", "User");
32432
+ const base = appData !== void 0 && appData.trim() !== "" ? appData : path34.join(os9.homedir(), "AppData", "Roaming");
32433
+ return path34.join(base, "Code", "User");
32406
32434
  }
32407
32435
  if (process.platform === "darwin") {
32408
- return path33.join(os9.homedir(), "Library", "Application Support", "Code", "User");
32436
+ return path34.join(os9.homedir(), "Library", "Application Support", "Code", "User");
32409
32437
  }
32410
- return path33.join(os9.homedir(), ".config", "Code", "User");
32438
+ return path34.join(os9.homedir(), ".config", "Code", "User");
32411
32439
  }
32412
32440
  function vscodeUserMcpPath() {
32413
- return path33.join(vscodeUserConfigDir(), "mcp.json");
32441
+ return path34.join(vscodeUserConfigDir(), "mcp.json");
32414
32442
  }
32415
32443
  function vscodeProjectMcpPath(projectRoot = process.cwd()) {
32416
- return path33.join(path33.resolve(projectRoot), ".vscode", "mcp.json");
32444
+ return path34.join(path34.resolve(projectRoot), ".vscode", "mcp.json");
32417
32445
  }
32418
32446
  function vscodeMcpPath(opts = {}) {
32419
32447
  return opts.project === true ? vscodeProjectMcpPath(opts.projectRoot) : vscodeUserMcpPath();
@@ -32422,7 +32450,7 @@ function otherScopeMcpPath(opts) {
32422
32450
  return opts.project === true ? vscodeUserMcpPath() : vscodeProjectMcpPath(opts.projectRoot);
32423
32451
  }
32424
32452
  function vscodeInstructionsPath(projectRoot = process.cwd()) {
32425
- return path33.join(path33.resolve(projectRoot), ".github", "copilot-instructions.md");
32453
+ return path34.join(path34.resolve(projectRoot), ".github", "copilot-instructions.md");
32426
32454
  }
32427
32455
  function readConfig(filePath) {
32428
32456
  const text = fs28.existsSync(filePath) ? fs28.readFileSync(filePath, "utf8") : "{}\n";
@@ -32507,7 +32535,7 @@ function installVscode(opts = {}) {
32507
32535
  throw new Error(`VS Code MCP JSON at ${mcpPath} already has a non-token-goat-managed server named "token-goat"`);
32508
32536
  }
32509
32537
  const next = updateConfig(config2.text, managedServer());
32510
- fs28.mkdirSync(path33.dirname(mcpPath), { recursive: true });
32538
+ fs28.mkdirSync(path34.dirname(mcpPath), { recursive: true });
32511
32539
  if (config2.text !== next) atomicWriteText(mcpPath, next);
32512
32540
  const guidanceChanged = writeGuidance(instructionsPath);
32513
32541
  return { mcpPath, instructionsPath, alreadyInstalled: config2.text === next && !guidanceChanged, scope };
@@ -32562,15 +32590,15 @@ var init_bridges = __esm({
32562
32590
 
32563
32591
  // src/session_store.ts
32564
32592
  import * as fs29 from "node:fs";
32565
- import * as path34 from "node:path";
32593
+ import * as path35 from "node:path";
32566
32594
  function sessionPath(sessionId) {
32567
32595
  if (!sessionId) return null;
32568
32596
  const safe = sanitizeIdForFilename(sessionId, 64);
32569
32597
  if (!safe) return null;
32570
- const dir = path34.join(tokenGoatHome(), SESSIONS_SUBDIR);
32571
- const candidate = path34.join(dir, `${safe}.json`);
32598
+ const dir = path35.join(tokenGoatHome(), SESSIONS_SUBDIR);
32599
+ const candidate = path35.join(dir, `${safe}.json`);
32572
32600
  try {
32573
- const rel = path34.relative(dir, candidate);
32601
+ const rel = path35.relative(dir, candidate);
32574
32602
  if (rel.startsWith("..")) return null;
32575
32603
  } catch {
32576
32604
  return null;
@@ -32805,13 +32833,13 @@ function listSiblingSessionStates(sessionId) {
32805
32833
  const safeSessionId = sanitizeIdForFilename(sessionId);
32806
32834
  if (!safeSessionId) return [];
32807
32835
  const prefix = `${safeSessionId}${AGENT_SALT_MARKER}`;
32808
- const dir = path34.join(tokenGoatHome(), SESSIONS_SUBDIR);
32836
+ const dir = path35.join(tokenGoatHome(), SESSIONS_SUBDIR);
32809
32837
  const out2 = [];
32810
32838
  try {
32811
32839
  if (!fs29.existsSync(dir)) return out2;
32812
32840
  for (const file2 of fs29.readdirSync(dir)) {
32813
32841
  if (!file2.endsWith(".json") || !file2.startsWith(prefix)) continue;
32814
- const state = readDiskState(path34.join(dir, file2));
32842
+ const state = readDiskState(path35.join(dir, file2));
32815
32843
  if (state !== null) out2.push(state);
32816
32844
  }
32817
32845
  } catch {
@@ -32830,7 +32858,7 @@ function saveSessionState(sessionId) {
32830
32858
  const p = sessionPath(sessionId);
32831
32859
  if (!p) return;
32832
32860
  try {
32833
- const dir = path34.dirname(p);
32861
+ const dir = path35.dirname(p);
32834
32862
  if (!fs29.existsSync(dir)) fs29.mkdirSync(dir, { recursive: true });
32835
32863
  const mem = exportSessionState();
32836
32864
  const writeMerged = () => {
@@ -32860,7 +32888,7 @@ var init_session_store = __esm({
32860
32888
 
32861
32889
  // src/compact.ts
32862
32890
  import * as fs30 from "node:fs";
32863
- import * as path35 from "node:path";
32891
+ import * as path36 from "node:path";
32864
32892
  function tierForFraction(fill) {
32865
32893
  if (fill >= CONTEXT_TIER_CRITICAL) return "critical";
32866
32894
  if (fill >= CONTEXT_TIER_HOT) return "hot";
@@ -32927,7 +32955,7 @@ function inferSessionGoal(cache, maxTokens = 80) {
32927
32955
  const dirCounts = new Counter();
32928
32956
  for (const fpath of editedPaths) {
32929
32957
  try {
32930
- let parent = path35.dirname(fpath);
32958
+ let parent = path36.dirname(fpath);
32931
32959
  if (parent === ".") {
32932
32960
  parent = "root";
32933
32961
  } else if (parent.startsWith("./")) {
@@ -33003,7 +33031,7 @@ function isNoisePath(inputPath) {
33003
33031
  }
33004
33032
  function findLatestSessionId() {
33005
33033
  try {
33006
- const sessionsDir = path35.join(tokenGoatHome(), "sessions");
33034
+ const sessionsDir = path36.join(tokenGoatHome(), "sessions");
33007
33035
  if (!fs30.existsSync(sessionsDir)) {
33008
33036
  return null;
33009
33037
  }
@@ -33017,9 +33045,9 @@ function findLatestSessionId() {
33017
33045
  return null;
33018
33046
  }
33019
33047
  let latestFile = firstFile;
33020
- let latestMtime = fs30.statSync(path35.join(sessionsDir, firstFile)).mtimeMs;
33048
+ let latestMtime = fs30.statSync(path36.join(sessionsDir, firstFile)).mtimeMs;
33021
33049
  for (const file2 of jsonFiles) {
33022
- const mtime = fs30.statSync(path35.join(sessionsDir, file2)).mtimeMs;
33050
+ const mtime = fs30.statSync(path36.join(sessionsDir, file2)).mtimeMs;
33023
33051
  if (mtime > latestMtime) {
33024
33052
  latestFile = file2;
33025
33053
  latestMtime = mtime;
@@ -33041,15 +33069,15 @@ function eventCount(cache) {
33041
33069
  function writeSessionManifest(projectHash2, sessionId, manifestJson) {
33042
33070
  const safeSessionId = sanitizeIdForFilename(sessionId, 64);
33043
33071
  if (!safeSessionId) return;
33044
- const sessionsDir = path35.join(dataDir(), "projects", projectHash2, "sessions");
33072
+ const sessionsDir = path36.join(dataDir(), "projects", projectHash2, "sessions");
33045
33073
  if (!fs30.existsSync(sessionsDir)) {
33046
33074
  fs30.mkdirSync(sessionsDir, { recursive: true });
33047
33075
  }
33048
- const dest = path35.join(sessionsDir, `${safeSessionId}.json`);
33076
+ const dest = path36.join(sessionsDir, `${safeSessionId}.json`);
33049
33077
  atomicWriteText(dest, JSON.stringify(manifestJson));
33050
33078
  }
33051
33079
  function readAllSessionManifests(projectHash2, maxAgeSecs = 3600) {
33052
- const sessionsDir = path35.join(dataDir(), "projects", projectHash2, "sessions");
33080
+ const sessionsDir = path36.join(dataDir(), "projects", projectHash2, "sessions");
33053
33081
  if (!fs30.existsSync(sessionsDir)) {
33054
33082
  return [];
33055
33083
  }
@@ -33062,7 +33090,7 @@ function readAllSessionManifests(projectHash2, maxAgeSecs = 3600) {
33062
33090
  continue;
33063
33091
  }
33064
33092
  try {
33065
- const fullPath = path35.join(sessionsDir, file2);
33093
+ const fullPath = path36.join(sessionsDir, file2);
33066
33094
  const stat2 = fs30.statSync(fullPath);
33067
33095
  if (now - stat2.mtimeMs / 1e3 > maxAgeSecs) {
33068
33096
  try {
@@ -33400,11 +33428,11 @@ function buildPackageManifestHint(options) {
33400
33428
  return null;
33401
33429
  }
33402
33430
  }
33403
- function _sanitizeHintPath(path69) {
33404
- if (typeof path69 !== "string") {
33431
+ function _sanitizeHintPath(path70) {
33432
+ if (typeof path70 !== "string") {
33405
33433
  return "???";
33406
33434
  }
33407
- return path69.replace(/[\x00]/g, "").slice(0, 200);
33435
+ return path70.replace(/[\x00]/g, "").slice(0, 200);
33408
33436
  }
33409
33437
  var HINT_PRIORITY_MEDIUM;
33410
33438
  var init_hints = __esm({
@@ -33760,7 +33788,8 @@ function handlePdf(filePath, contentLength) {
33760
33788
  shouldBlock: true,
33761
33789
  message: [
33762
33790
  `PDF file (${formatBytes(contentLength)}) \u2014 Read cannot return PDF content; this is not retryable with different Read parameters.`,
33763
- `Extract text instead: token-goat pdf-extract "${filePath}"`
33791
+ `Inspect first: token-goat pdf-meta "${filePath}" and token-goat pdf-outline "${filePath}"`,
33792
+ `Then extract relevant pages: token-goat pdf-extract "${filePath}" --pages <range>`
33764
33793
  ].join("\n")
33765
33794
  };
33766
33795
  }
@@ -34576,7 +34605,7 @@ var init_skill_cache = __esm({
34576
34605
 
34577
34606
  // src/doc_compact.ts
34578
34607
  import * as fs32 from "fs";
34579
- import * as path36 from "path";
34608
+ import * as path37 from "path";
34580
34609
  function sourceHash(filePath) {
34581
34610
  try {
34582
34611
  return fingerprintContent(fs32.readFileSync(filePath));
@@ -34586,14 +34615,14 @@ function sourceHash(filePath) {
34586
34615
  }
34587
34616
  function _compactSlug(absPathStr) {
34588
34617
  const h = fingerprintContent(foldPath(absPathStr)).slice(0, 12);
34589
- const ext2 = path36.extname(absPathStr);
34590
- const stem = path36.basename(absPathStr, ext2);
34618
+ const ext2 = path37.extname(absPathStr);
34619
+ const stem = path37.basename(absPathStr, ext2);
34591
34620
  const safeStem = sanitizeIdForFilename(stem, 32);
34592
34621
  return `${h}_${safeStem}`;
34593
34622
  }
34594
34623
  function compactPathFor(sourcePath) {
34595
34624
  const abs = resolveIndexPath(sourcePath);
34596
- return path36.join(dataDir(), compactSubdir, `${_compactSlug(abs)}.md`);
34625
+ return path37.join(dataDir(), compactSubdir, `${_compactSlug(abs)}.md`);
34597
34626
  }
34598
34627
  function readCompactHeader(compactPath) {
34599
34628
  try {
@@ -34642,13 +34671,13 @@ function readCompactBody(compactPath) {
34642
34671
  }
34643
34672
  }
34644
34673
  function writeCompact(compactPath, sourcePath, compactBody, sourceRel) {
34645
- const srcPath = path36.resolve(sourcePath);
34674
+ const srcPath = path37.resolve(sourcePath);
34646
34675
  const sha = sourceHash(srcPath);
34647
- const displayRel = sourceRel || path36.basename(srcPath);
34676
+ const displayRel = sourceRel || path37.basename(srcPath);
34648
34677
  const header = `${headerPrefix}${sha} source:${displayRel} -->
34649
34678
  `;
34650
34679
  const fullText = header + compactBody.trimStart();
34651
- const dir = path36.dirname(compactPath);
34680
+ const dir = path37.dirname(compactPath);
34652
34681
  if (!fs32.existsSync(dir)) {
34653
34682
  fs32.mkdirSync(dir, { recursive: true });
34654
34683
  }
@@ -34799,7 +34828,7 @@ var init_doc_compact = __esm({
34799
34828
 
34800
34829
  // src/notebook_compact.ts
34801
34830
  import * as fs33 from "node:fs";
34802
- import * as path37 from "node:path";
34831
+ import * as path38 from "node:path";
34803
34832
  function stripNotebook(nbDict) {
34804
34833
  const cells = [];
34805
34834
  for (const cell of nbDict.cells ?? []) {
@@ -34816,14 +34845,14 @@ function stripNotebook(nbDict) {
34816
34845
  return { ...nbDict, cells };
34817
34846
  }
34818
34847
  function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs = SIDECAR_DEFAULT_MAX_AGE_MS) {
34819
- const nbStripDir = path37.join(cacheRoot, "nb_strip");
34848
+ const nbStripDir = path38.join(cacheRoot, "nb_strip");
34820
34849
  let removed = 0;
34821
34850
  try {
34822
34851
  if (!fs33.existsSync(nbStripDir)) return 0;
34823
34852
  const cutoff = Date.now() - maxAgeMs;
34824
34853
  const kept = [];
34825
34854
  for (const entry of fs33.readdirSync(nbStripDir)) {
34826
- const dir = path37.join(nbStripDir, entry);
34855
+ const dir = path38.join(nbStripDir, entry);
34827
34856
  let mtime;
34828
34857
  try {
34829
34858
  mtime = fs33.statSync(dir).mtimeMs;
@@ -34859,8 +34888,8 @@ function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs
34859
34888
  }
34860
34889
  function getOrCreateSidecar(rawBytes, cacheRoot, opts = {}) {
34861
34890
  const sha = fingerprintContent(rawBytes);
34862
- const sidecarDir = path37.join(cacheRoot, "nb_strip", sha);
34863
- const sidecarPath = path37.join(sidecarDir, "stripped.ipynb");
34891
+ const sidecarDir = path38.join(cacheRoot, "nb_strip", sha);
34892
+ const sidecarPath = path38.join(sidecarDir, "stripped.ipynb");
34864
34893
  if (fs33.existsSync(sidecarPath)) {
34865
34894
  return [sidecarPath, false];
34866
34895
  }
@@ -34902,7 +34931,7 @@ var init_notebook_compact = __esm({
34902
34931
 
34903
34932
  // src/hooks_read.ts
34904
34933
  import * as fs34 from "node:fs";
34905
- import * as path38 from "node:path";
34934
+ import * as path39 from "node:path";
34906
34935
  function isTsConfigFile(basename22) {
34907
34936
  const lower = basename22.toLowerCase();
34908
34937
  return /^tsconfig(\..+)?\.json$/i.test(lower) || lower === "jsconfig.json";
@@ -34917,8 +34946,8 @@ function isNodeModulesPath(p) {
34917
34946
  return check2.includes("/node_modules/") || check2.includes("\\node_modules\\");
34918
34947
  }
34919
34948
  function relPathWithinRoot(root, target) {
34920
- const rel = path38.relative(root, target).replace(/\\/g, "/");
34921
- if (rel.startsWith("..") || path38.isAbsolute(rel)) return null;
34949
+ const rel = path39.relative(root, target).replace(/\\/g, "/");
34950
+ if (rel.startsWith("..") || path39.isAbsolute(rel)) return null;
34922
34951
  return rel;
34923
34952
  }
34924
34953
  function _isDocFile(filePath) {
@@ -35010,7 +35039,7 @@ function isSourceExtension(basename22) {
35010
35039
  return language === "apex" || language === "salesforce_metadata" || language === "salesforce_markup";
35011
35040
  }
35012
35041
  function isDispatchedFileType(basename22) {
35013
- return DISPATCHED_FILE_TYPE_EXTS.has(path38.extname(basename22).slice(1).toLowerCase());
35042
+ return DISPATCHED_FILE_TYPE_EXTS.has(path39.extname(basename22).slice(1).toLowerCase());
35014
35043
  }
35015
35044
  function surgicalHint(filePath, basename22, lineCount) {
35016
35045
  if (lineCount < loadConfig().hints.min_file_lines_for_hint) return "";
@@ -35154,7 +35183,7 @@ function preReadHandlerInner(event) {
35154
35183
  "node_modules is typically noise; use npm ls, npm outdated, or npm audit instead for dependency info. To force access, use: token-goat read node_modules/package/file.js::symbol-name or token-goat section node_modules/package/file.js::heading"
35155
35184
  );
35156
35185
  }
35157
- const basename22 = path38.basename(normalized);
35186
+ const basename22 = path39.basename(normalized);
35158
35187
  if (isLockFile(basename22)) {
35159
35188
  return denyOutput(
35160
35189
  'Lock files are rarely useful to read in full. Use `token-goat section "' + normalized + '::<section>"` to extract a specific dependency, or read the relevant manifest instead.'
@@ -35475,7 +35504,7 @@ function preReadHandlerInner(event) {
35475
35504
  "Note: " + normalized + " is large (" + kb + "KB). " + hint + contextPressureAdvisorySuffix()
35476
35505
  );
35477
35506
  }
35478
- const fileTypeExt = path38.extname(normalized).slice(1).toLowerCase();
35507
+ const fileTypeExt = path39.extname(normalized).slice(1).toLowerCase();
35479
35508
  const fileStatSize = size ?? statSize(normalized) ?? 0;
35480
35509
  const isKnownFileType = DISPATCHED_FILE_TYPE_EXTS.has(fileTypeExt);
35481
35510
  if (event.toolName !== "Grep" && !isImagePath(normalized) && (isKnownFileType || fileStatSize >= FILE_TYPE_THRESHOLDS.generic)) {
@@ -35532,7 +35561,7 @@ function postReadHandlerInner(event) {
35532
35561
  if (respText.includes("[Truncated:") || respText.includes("Truncated: PARTIAL view")) {
35533
35562
  markFileTruncated(normalized);
35534
35563
  }
35535
- const postBasename = path38.basename(normalized);
35564
+ const postBasename = path39.basename(normalized);
35536
35565
  const diffSourcesEnabled = loadConfig().hints.serve_diff_on_reread;
35537
35566
  if (/\.(md|mdx|markdown|rst|txt)$/i.test(postBasename) || isSessionArtifactFile(normalized) || diffSourcesEnabled && DIFFABLE_SOURCE_RE.test(postBasename)) {
35538
35567
  try {
@@ -35697,7 +35726,7 @@ var init_confirm_apply = __esm({
35697
35726
 
35698
35727
  // src/memory_prune.ts
35699
35728
  import * as fs35 from "node:fs";
35700
- import * as path39 from "node:path";
35729
+ import * as path40 from "node:path";
35701
35730
  function parseIndex(text) {
35702
35731
  const passthrough2 = [];
35703
35732
  const entries = [];
@@ -35740,7 +35769,7 @@ function pruneIndex(memoryDir, opts) {
35740
35769
  changed: false,
35741
35770
  tokensSaved: 0
35742
35771
  };
35743
- const memoryMd = path39.join(memoryDir, "MEMORY.md");
35772
+ const memoryMd = path40.join(memoryDir, "MEMORY.md");
35744
35773
  let text;
35745
35774
  try {
35746
35775
  text = fs35.readFileSync(memoryMd, "utf-8");
@@ -35754,7 +35783,7 @@ function pruneIndex(memoryDir, opts) {
35754
35783
  const dups = [];
35755
35784
  for (const entry of entries) {
35756
35785
  const isUrl = URL_SCHEME_RE.test(entry.target);
35757
- const targetExists = isUrl ? true : path39.isAbsolute(entry.target) ? fs35.existsSync(entry.target) : fs35.existsSync(path39.join(memoryDir, entry.target));
35786
+ const targetExists = isUrl ? true : path40.isAbsolute(entry.target) ? fs35.existsSync(entry.target) : fs35.existsSync(path40.join(memoryDir, entry.target));
35758
35787
  const foldedTarget = foldPath(entry.target);
35759
35788
  if (!targetExists) {
35760
35789
  dead.push(entry);
@@ -35898,7 +35927,7 @@ async function tryEmbeddingClusters(siblings, snippets, threshold) {
35898
35927
  }
35899
35928
  async function findContentDuplicates(memoryDir, _opts) {
35900
35929
  const threshold = _opts?.threshold ?? 0.92;
35901
- const siblings = fs35.readdirSync(memoryDir).filter((name2) => name2.toLowerCase().endsWith(".md") && name2.toLowerCase() !== "memory.md").map((name2) => path39.join(memoryDir, name2)).sort();
35930
+ const siblings = fs35.readdirSync(memoryDir).filter((name2) => name2.toLowerCase().endsWith(".md") && name2.toLowerCase() !== "memory.md").map((name2) => path40.join(memoryDir, name2)).sort();
35902
35931
  if (siblings.length < 2) {
35903
35932
  return [];
35904
35933
  }
@@ -35982,7 +36011,7 @@ function auditClaudeMd(files) {
35982
36011
  const overlaps = [];
35983
36012
  for (const [stripped, filesSet] of lineToFiles) {
35984
36013
  if (filesSet.has(report.path) && filesSet.size > 1) {
35985
- const others = Array.from(filesSet).filter((p) => p !== report.path).map((p) => path39.basename(p));
36014
+ const others = Array.from(filesSet).filter((p) => p !== report.path).map((p) => path40.basename(p));
35986
36015
  if (others.length > 0) {
35987
36016
  if (stripped.length > 60) {
35988
36017
  overlaps.push(
@@ -36015,7 +36044,7 @@ var init_memory_prune = __esm({
36015
36044
  // src/cli_context_stats.ts
36016
36045
  import * as fs36 from "node:fs";
36017
36046
  import * as os10 from "node:os";
36018
- import * as path40 from "node:path";
36047
+ import * as path41 from "node:path";
36019
36048
  function tok(filePath) {
36020
36049
  try {
36021
36050
  const size = fs36.statSync(filePath).size;
@@ -36027,18 +36056,18 @@ function tok(filePath) {
36027
36056
  function findClaudeMdFiles(projectRoot, homeDir = os10.homedir()) {
36028
36057
  const found = [];
36029
36058
  const seen = /* @__PURE__ */ new Set();
36030
- let current = path40.resolve(projectRoot);
36059
+ let current = path41.resolve(projectRoot);
36031
36060
  while (true) {
36032
- const candidate = path40.join(current, "CLAUDE.md");
36061
+ const candidate = path41.join(current, "CLAUDE.md");
36033
36062
  if (!seen.has(candidate) && fs36.existsSync(candidate)) {
36034
36063
  found.push(candidate);
36035
36064
  seen.add(candidate);
36036
36065
  }
36037
- const parent = path40.dirname(current);
36066
+ const parent = path41.dirname(current);
36038
36067
  if (parent === current) break;
36039
36068
  current = parent;
36040
36069
  }
36041
- const globalMd = path40.join(homeDir, ".claude", "CLAUDE.md");
36070
+ const globalMd = path41.join(homeDir, ".claude", "CLAUDE.md");
36042
36071
  if (!seen.has(globalMd) && fs36.existsSync(globalMd)) {
36043
36072
  found.push(globalMd);
36044
36073
  }
@@ -36046,9 +36075,9 @@ function findClaudeMdFiles(projectRoot, homeDir = os10.homedir()) {
36046
36075
  }
36047
36076
  function findMemoryMd(projectRoot, homeDir = os10.homedir(), alternateRoots = []) {
36048
36077
  try {
36049
- const projectsDir = path40.join(homeDir, ".claude", "projects");
36078
+ const projectsDir = path41.join(homeDir, ".claude", "projects");
36050
36079
  if (!fs36.existsSync(projectsDir)) return null;
36051
- const rootStr = path40.resolve(projectRoot);
36080
+ const rootStr = path41.resolve(projectRoot);
36052
36081
  const candidateRoots2 = [rootStr];
36053
36082
  try {
36054
36083
  const realRoot = fs36.realpathSync.native(rootStr);
@@ -36056,12 +36085,12 @@ function findMemoryMd(projectRoot, homeDir = os10.homedir(), alternateRoots = []
36056
36085
  } catch {
36057
36086
  }
36058
36087
  for (const alternate of alternateRoots) {
36059
- const resolved = path40.resolve(alternate);
36088
+ const resolved = path41.resolve(alternate);
36060
36089
  if (!candidateRoots2.includes(resolved)) candidateRoots2.push(resolved);
36061
36090
  }
36062
36091
  for (const root of candidateRoots2) {
36063
36092
  const expectedSlug = root.replace(/[^A-Za-z0-9]/g, "-");
36064
- const candidate = path40.join(projectsDir, expectedSlug, "memory", "MEMORY.md");
36093
+ const candidate = path41.join(projectsDir, expectedSlug, "memory", "MEMORY.md");
36065
36094
  if (fs36.existsSync(candidate)) return candidate;
36066
36095
  }
36067
36096
  return null;
@@ -36076,10 +36105,10 @@ function buildStats(projectRoot, homeDir = os10.homedir(), alternateRoots = [])
36076
36105
  for (const p of claudeMds) {
36077
36106
  const t = tok(p);
36078
36107
  claudeMdTotal += t;
36079
- const parentDir = path40.basename(path40.dirname(p));
36108
+ const parentDir = path41.basename(path41.dirname(p));
36080
36109
  const label = parentDir === ".claude" ? "~/.claude/CLAUDE.md" : (() => {
36081
36110
  try {
36082
- return path40.relative(projectRoot, p);
36111
+ return path41.relative(projectRoot, p);
36083
36112
  } catch {
36084
36113
  return p;
36085
36114
  }
@@ -36143,7 +36172,7 @@ async function runContextStats(opts = {}) {
36143
36172
  process.stdout.write("[--fix] No MEMORY.md found; nothing to prune.\n");
36144
36173
  } else {
36145
36174
  const memPath = result.memory_md_path;
36146
- const pruneResult = pruneIndex(path40.dirname(memPath), { dryRun: true });
36175
+ const pruneResult = pruneIndex(path41.dirname(memPath), { dryRun: true });
36147
36176
  if (!pruneResult.changed || pruneResult.after === void 0) {
36148
36177
  process.stdout.write("[--fix] MEMORY.md already clean; nothing to prune.\n");
36149
36178
  } else {
@@ -36185,7 +36214,7 @@ var init_cli_context_stats = __esm({
36185
36214
 
36186
36215
  // src/baseline.ts
36187
36216
  import * as fs37 from "node:fs";
36188
- import * as path41 from "node:path";
36217
+ import * as path42 from "node:path";
36189
36218
  function walkProject(rootDir, opts = {}) {
36190
36219
  const files = [];
36191
36220
  const languages = {};
@@ -36204,7 +36233,7 @@ function walkProject(rootDir, opts = {}) {
36204
36233
  continue;
36205
36234
  }
36206
36235
  for (const entry of entries) {
36207
- const full = path41.join(dir, entry.name);
36236
+ const full = path42.join(dir, entry.name);
36208
36237
  if (entry.isDirectory()) {
36209
36238
  if (SKIP_DIRS.has(entry.name) || extraSkipDirs.includes(entry.name)) continue;
36210
36239
  if (entry.name.startsWith(".") && entry.name !== ".") {
@@ -36268,7 +36297,7 @@ function fetchTopSymbols(limit, dbPath, rootDir) {
36268
36297
  }
36269
36298
  }
36270
36299
  function buildProjectMap(rootDir = process.cwd(), opts = {}) {
36271
- const root = path41.resolve(rootDir);
36300
+ const root = path42.resolve(rootDir);
36272
36301
  const config2 = loadConfig();
36273
36302
  const { files, languages } = walkProject(root, { excludeTests: config2.repomap.exclude_tests });
36274
36303
  const compact = opts.compact === true || files.length > config2.repomap.compact_file_threshold;
@@ -36282,7 +36311,7 @@ function buildProjectMap(rootDir = process.cwd(), opts = {}) {
36282
36311
  mtime = 0;
36283
36312
  }
36284
36313
  return { f, mtime };
36285
- }).sort((a, b) => b.mtime - a.mtime).slice(0, compact ? 5 : 15).map((x) => path41.relative(root, x.f));
36314
+ }).sort((a, b) => b.mtime - a.mtime).slice(0, compact ? 5 : 15).map((x) => path42.relative(root, x.f));
36286
36315
  return {
36287
36316
  rootDir: root,
36288
36317
  fileCount: files.length,
@@ -36294,7 +36323,7 @@ function buildProjectMap(rootDir = process.cwd(), opts = {}) {
36294
36323
  }
36295
36324
  function formatProjectMap(map3, compact = false) {
36296
36325
  const lines2 = [];
36297
- const rel = path41.basename(map3.rootDir);
36326
+ const rel = path42.basename(map3.rootDir);
36298
36327
  lines2.push(`# Project map: ${rel}`);
36299
36328
  lines2.push(`Files: ${map3.fileCount}`);
36300
36329
  const langPairs = Object.entries(map3.languages).sort((a, b) => b[1] - a[1]);
@@ -36322,7 +36351,7 @@ function formatProjectMap(map3, compact = false) {
36322
36351
  }
36323
36352
  function mapLookupBytesSaved(map3, emittedText) {
36324
36353
  const referencedFiles = /* @__PURE__ */ new Set([
36325
- ...map3.recentFiles.map((f) => normalizePath(path41.resolve(map3.rootDir, f))),
36354
+ ...map3.recentFiles.map((f) => normalizePath(path42.resolve(map3.rootDir, f))),
36326
36355
  ...map3.topSymbols.map((s) => normalizePath(s.filePath))
36327
36356
  ]);
36328
36357
  let fullSourceBytes = 0;
@@ -36339,7 +36368,7 @@ function findMemSuggestionCandidates(projectRoot) {
36339
36368
  const claudeMdFiles = findClaudeMdFiles(projectRoot);
36340
36369
  const candidateFiles = new Set(claudeMdFiles);
36341
36370
  for (const claudeMd of claudeMdFiles) {
36342
- const agentsMd = path41.join(path41.dirname(claudeMd), "AGENTS.md");
36371
+ const agentsMd = path42.join(path42.dirname(claudeMd), "AGENTS.md");
36343
36372
  if (fs37.existsSync(agentsMd)) candidateFiles.add(agentsMd);
36344
36373
  }
36345
36374
  const suggestions = [];
@@ -36375,7 +36404,7 @@ function formatMemSuggestions(projectRoot) {
36375
36404
  if (suggestions.length === 0) return "";
36376
36405
  const lines2 = ["", "## mem suggestions"];
36377
36406
  for (const s of suggestions) {
36378
- const basename22 = path41.basename(s.path);
36407
+ const basename22 = path42.basename(s.path);
36379
36408
  lines2.push(
36380
36409
  "Consider: mem import --from-md " + s.path + " # migrates " + s.count + " preference-shaped lines from " + basename22 + " as pending facts for review"
36381
36410
  );
@@ -36429,7 +36458,7 @@ var init_baseline = __esm({
36429
36458
 
36430
36459
  // src/content_store.ts
36431
36460
  import { deflateRawSync } from "node:zlib";
36432
- import * as path66 from "node:path";
36461
+ import * as path67 from "node:path";
36433
36462
  function estimateTextTokens(bytes) {
36434
36463
  return Math.round(bytes / TEXT_BYTES_PER_TOKEN);
36435
36464
  }
@@ -36445,7 +36474,7 @@ function contentId(text) {
36445
36474
  return `tg_${shortFingerprint(text)}`;
36446
36475
  }
36447
36476
  function normalizeProjectRoot(projectRoot) {
36448
- const candidate = path66.resolve(projectRoot ?? process.cwd());
36477
+ const candidate = path67.resolve(projectRoot ?? process.cwd());
36449
36478
  return findProject(candidate)?.root ?? candidate;
36450
36479
  }
36451
36480
  function handoffId(name2, projectRoot) {
@@ -36809,10 +36838,10 @@ function mergeDefs(...defs) {
36809
36838
  function cloneDef(schema) {
36810
36839
  return mergeDefs(schema._zod.def);
36811
36840
  }
36812
- function getElementAtPath(obj, path69) {
36813
- if (!path69)
36841
+ function getElementAtPath(obj, path70) {
36842
+ if (!path70)
36814
36843
  return obj;
36815
- return path69.reduce((acc, key) => acc?.[key], obj);
36844
+ return path70.reduce((acc, key) => acc?.[key], obj);
36816
36845
  }
36817
36846
  function promiseAllObject(promisesObj) {
36818
36847
  const keys = Object.keys(promisesObj);
@@ -37140,11 +37169,11 @@ function explicitlyAborted(x, startIndex = 0) {
37140
37169
  }
37141
37170
  return false;
37142
37171
  }
37143
- function prefixIssues(path69, issues) {
37172
+ function prefixIssues(path70, issues) {
37144
37173
  return issues.map((iss) => {
37145
37174
  var _a6;
37146
37175
  (_a6 = iss).path ?? (_a6.path = []);
37147
- iss.path.unshift(path69);
37176
+ iss.path.unshift(path70);
37148
37177
  return iss;
37149
37178
  });
37150
37179
  }
@@ -37362,16 +37391,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
37362
37391
  }
37363
37392
  function formatError2(error52, mapper = (issue2) => issue2.message) {
37364
37393
  const fieldErrors = { _errors: [] };
37365
- const processError = (error53, path69 = []) => {
37394
+ const processError = (error53, path70 = []) => {
37366
37395
  for (const issue2 of error53.issues) {
37367
37396
  if (issue2.code === "invalid_union" && issue2.errors.length) {
37368
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
37397
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
37369
37398
  } else if (issue2.code === "invalid_key") {
37370
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
37399
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
37371
37400
  } else if (issue2.code === "invalid_element") {
37372
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
37401
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
37373
37402
  } else {
37374
- const fullpath = [...path69, ...issue2.path];
37403
+ const fullpath = [...path70, ...issue2.path];
37375
37404
  if (fullpath.length === 0) {
37376
37405
  fieldErrors._errors.push(mapper(issue2));
37377
37406
  } else {
@@ -37398,17 +37427,17 @@ function formatError2(error52, mapper = (issue2) => issue2.message) {
37398
37427
  }
37399
37428
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
37400
37429
  const result = { errors: [] };
37401
- const processError = (error53, path69 = []) => {
37430
+ const processError = (error53, path70 = []) => {
37402
37431
  var _a6, _b;
37403
37432
  for (const issue2 of error53.issues) {
37404
37433
  if (issue2.code === "invalid_union" && issue2.errors.length) {
37405
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
37434
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
37406
37435
  } else if (issue2.code === "invalid_key") {
37407
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
37436
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
37408
37437
  } else if (issue2.code === "invalid_element") {
37409
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
37438
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
37410
37439
  } else {
37411
- const fullpath = [...path69, ...issue2.path];
37440
+ const fullpath = [...path70, ...issue2.path];
37412
37441
  if (fullpath.length === 0) {
37413
37442
  result.errors.push(mapper(issue2));
37414
37443
  continue;
@@ -37440,8 +37469,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
37440
37469
  }
37441
37470
  function toDotPath(_path) {
37442
37471
  const segs = [];
37443
- const path69 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
37444
- for (const seg of path69) {
37472
+ const path70 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
37473
+ for (const seg of path70) {
37445
37474
  if (typeof seg === "number")
37446
37475
  segs.push(`[${seg}]`);
37447
37476
  else if (typeof seg === "symbol")
@@ -37711,8 +37740,8 @@ var init_regexes = __esm({
37711
37740
  _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
37712
37741
  ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
37713
37742
  ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
37714
- mac = (delimiter2) => {
37715
- const escapedDelim = escapeRegex(delimiter2 ?? ":");
37743
+ mac = (delimiter3) => {
37744
+ const escapedDelim = escapeRegex(delimiter3 ?? ":");
37716
37745
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
37717
37746
  };
37718
37747
  cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -50944,13 +50973,13 @@ function resolveRef(ref2, ctx) {
50944
50973
  if (!ref2.startsWith("#")) {
50945
50974
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
50946
50975
  }
50947
- const path69 = ref2.slice(1).split("/").filter(Boolean);
50948
- if (path69.length === 0) {
50976
+ const path70 = ref2.slice(1).split("/").filter(Boolean);
50977
+ if (path70.length === 0) {
50949
50978
  return ctx.rootSchema;
50950
50979
  }
50951
50980
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
50952
- if (path69[0] === defsKey) {
50953
- const key = path69[1];
50981
+ if (path70[0] === defsKey) {
50982
+ const key = path70[1];
50954
50983
  if (!key || !ctx.defs[key]) {
50955
50984
  throw new Error(`Reference not found: ${ref2}`);
50956
50985
  }
@@ -51727,7 +51756,7 @@ __export(mcp_server_exports, {
51727
51756
  createMcpServer: () => createMcpServer
51728
51757
  });
51729
51758
  import * as fs59 from "fs";
51730
- import * as path67 from "path";
51759
+ import * as path68 from "path";
51731
51760
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
51732
51761
  function mcpFriendlyText(text) {
51733
51762
  let out2 = text.replace(TOKEN_GOAT_RETRY_RE, (_match, cmd, arg) => {
@@ -51796,7 +51825,7 @@ function resolveToolRoot(projectRoot) {
51796
51825
  }
51797
51826
  function checkWithinProjectRoot(target, resolvedRoot) {
51798
51827
  const root = forCompare(normalizePath(realPathOrSelf(resolvedRoot)));
51799
- const abs = path67.resolve(resolvedRoot, normalizePath(target));
51828
+ const abs = path68.resolve(resolvedRoot, normalizePath(target));
51800
51829
  let identity;
51801
51830
  try {
51802
51831
  identity = fileIdentity(fs59.statSync(abs, { bigint: true }));
@@ -51815,6 +51844,16 @@ function specFilePart(spec) {
51815
51844
  }
51816
51845
  function confineTargets(targets, resolvedRoot, splitCommas = true) {
51817
51846
  if (!loadConfig(resolvedRoot).mcp.confine_reads_to_project_root) return { ok: true, targets, pins: NO_PINS };
51847
+ const allowedRoots = loadConfig().mcp.allowed_roots;
51848
+ if (allowedRoots.length > 0 && !allowedRoots.some((allowed) => checkWithinProjectRoot(resolvedRoot, allowed).inside)) {
51849
+ return {
51850
+ ok: false,
51851
+ refusal: toCallToolResult({
51852
+ text: `refused: "${resolvedRoot}" is not inside any root listed in mcp.allowed_roots. A caller-supplied projectRoot is untrusted input, so this deployment pins which roots may be named; add the root to mcp.allowed_roots (or TOKEN_GOAT_MCP_ALLOWED_ROOTS) to permit it.`,
51853
+ code: 1
51854
+ })
51855
+ };
51856
+ }
51818
51857
  const checked = [];
51819
51858
  const pins = /* @__PURE__ */ new Map();
51820
51859
  for (const raw of targets) {
@@ -52460,7 +52499,7 @@ init_baseline();
52460
52499
  init_stats();
52461
52500
  init_repomap();
52462
52501
  import * as fs60 from "fs";
52463
- import * as path68 from "path";
52502
+ import * as path69 from "path";
52464
52503
  import { homedir as homedir19 } from "os";
52465
52504
 
52466
52505
  // src/walk_index.ts
@@ -52469,27 +52508,27 @@ init_baseline();
52469
52508
  init_util2();
52470
52509
  import * as fs38 from "node:fs";
52471
52510
  import * as os11 from "node:os";
52472
- import * as path42 from "node:path";
52511
+ import * as path43 from "node:path";
52473
52512
  function isWalkExcluded(file2) {
52474
- const base = path42.basename(file2).toLowerCase();
52513
+ const base = path43.basename(file2).toLowerCase();
52475
52514
  if (base === ".env" || base.startsWith(".env.")) return true;
52476
52515
  if (base.endsWith(".d.ts")) return true;
52477
52516
  return false;
52478
52517
  }
52479
52518
  function assertWalkableRoot(root) {
52480
- let resolved = path42.resolve(root);
52519
+ let resolved = path43.resolve(root);
52481
52520
  try {
52482
52521
  resolved = fs38.realpathSync.native(resolved);
52483
52522
  } catch {
52484
52523
  }
52485
52524
  const norm = foldPath(normalizePath(resolved));
52486
- const fsRoot = foldPath(normalizePath(path42.parse(resolved).root));
52525
+ const fsRoot = foldPath(normalizePath(path43.parse(resolved).root));
52487
52526
  if (norm === fsRoot) {
52488
52527
  throw new Error(`refusing to walk-index a filesystem root: ${resolved}`);
52489
52528
  }
52490
52529
  const home = os11.homedir();
52491
52530
  if (home) {
52492
- const normHome = foldPath(normalizePath(path42.resolve(home)));
52531
+ const normHome = foldPath(normalizePath(path43.resolve(home)));
52493
52532
  if (norm === normHome) {
52494
52533
  throw new Error(`refusing to walk-index the home directory: ${resolved}`);
52495
52534
  }
@@ -52501,7 +52540,7 @@ function assertWalkableRoot(root) {
52501
52540
  }
52502
52541
  var MAX_FILES_SCANNED_FORCED = 5e5;
52503
52542
  function collectWalkIndexFiles(root, opts = {}) {
52504
- const resolved = path42.resolve(root);
52543
+ const resolved = path43.resolve(root);
52505
52544
  assertWalkableRoot(resolved);
52506
52545
  const force = opts.force === true;
52507
52546
  const ceiling = force ? MAX_FILES_SCANNED_FORCED : MAX_FILES_SCANNED;
@@ -52704,7 +52743,7 @@ init_define_import_meta_env();
52704
52743
  init_define_import_meta_env();
52705
52744
  init_bash_compress();
52706
52745
  import * as fs39 from "node:fs";
52707
- import * as path43 from "node:path";
52746
+ import * as path44 from "node:path";
52708
52747
  var DEFAULT_MAX_LINES = 1e3;
52709
52748
  var DEFAULT_MAX_BYTES = 64 * 1024;
52710
52749
  var MAX_INSPECT_BYTES = 2 * 1024 * 1024;
@@ -53125,13 +53164,13 @@ function loadPackageScripts(candidate, stat2) {
53125
53164
  function findNearestPackageScripts(startDir) {
53126
53165
  let dir = startDir;
53127
53166
  for (; ; ) {
53128
- const candidate = path43.join(dir, "package.json");
53167
+ const candidate = path44.join(dir, "package.json");
53129
53168
  try {
53130
53169
  const stat2 = fs39.statSync(candidate);
53131
53170
  if (stat2.isFile()) return loadPackageScripts(candidate, stat2);
53132
53171
  } catch {
53133
53172
  }
53134
- const parent = path43.dirname(dir);
53173
+ const parent = path44.dirname(dir);
53135
53174
  if (parent === dir) return null;
53136
53175
  dir = parent;
53137
53176
  }
@@ -66302,7 +66341,7 @@ function grepIntInput(toolInput, key) {
66302
66341
  function grepSignature(toolInput) {
66303
66342
  const pattern = toolInput["pattern"];
66304
66343
  if (typeof pattern !== "string" || pattern === "") return null;
66305
- const path69 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
66344
+ const path70 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
66306
66345
  const outputMode = typeof toolInput["output_mode"] === "string" ? toolInput["output_mode"] : "files_with_matches";
66307
66346
  const glob = typeof toolInput["glob"] === "string" ? toolInput["glob"] : "";
66308
66347
  const type = typeof toolInput["type"] === "string" ? toolInput["type"] : "";
@@ -66317,7 +66356,7 @@ function grepSignature(toolInput) {
66317
66356
  const offset = grepIntInput(toolInput, "offset");
66318
66357
  return JSON.stringify([
66319
66358
  pattern,
66320
- path69,
66359
+ path70,
66321
66360
  outputMode,
66322
66361
  glob,
66323
66362
  type,
@@ -66417,8 +66456,8 @@ init_session();
66417
66456
  function globSignature(toolInput) {
66418
66457
  const pattern = toolInput["pattern"];
66419
66458
  if (typeof pattern !== "string" || pattern === "") return null;
66420
- const path69 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
66421
- return JSON.stringify([pattern, path69]);
66459
+ const path70 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
66460
+ return JSON.stringify([pattern, path70]);
66422
66461
  }
66423
66462
  var { post: postGlobHandler, pre: preGlobDedupHandler } = makeDedupHintHandlers({
66424
66463
  toolName: "Glob",
@@ -66447,7 +66486,7 @@ init_stats();
66447
66486
  init_config();
66448
66487
  init_doc_compact();
66449
66488
  init_worker();
66450
- import * as path44 from "node:path";
66489
+ import * as path45 from "node:path";
66451
66490
  import { statSync as statSync20 } from "node:fs";
66452
66491
  function postEditHandlerInner(event) {
66453
66492
  const filePath = getFilePath(event);
@@ -66475,7 +66514,7 @@ function postEditHandlerInner(event) {
66475
66514
  if (loadConfig().hints.stable_doc_compacts) {
66476
66515
  markCompactStale(compactPathFor(normalized));
66477
66516
  }
66478
- const editedBasename = path44.basename(normalized);
66517
+ const editedBasename = path45.basename(normalized);
66479
66518
  if (/\.(md|mdx|markdown|rst)$/i.test(editedBasename)) {
66480
66519
  let editedSize = Infinity;
66481
66520
  try {
@@ -66797,11 +66836,11 @@ function gitStateFingerprintSync(cwd) {
66797
66836
  }
66798
66837
  }
66799
66838
  var DIR_FINGERPRINT_LISTING_CAP_ENTRIES = 1e4;
66800
- function dirStateFingerprintSync(path69) {
66839
+ function dirStateFingerprintSync(path70) {
66801
66840
  try {
66802
- const stat2 = statSync22(path69);
66841
+ const stat2 = statSync22(path70);
66803
66842
  if (!stat2.isDirectory()) return null;
66804
- const entries = readdirSync16(path69);
66843
+ const entries = readdirSync16(path70);
66805
66844
  if (entries.length <= DIR_FINGERPRINT_LISTING_CAP_ENTRIES) {
66806
66845
  return shortFingerprint(entries.slice().sort().join("\0"));
66807
66846
  }
@@ -66811,12 +66850,12 @@ function dirStateFingerprintSync(path69) {
66811
66850
  }
66812
66851
  }
66813
66852
  var FILE_FINGERPRINT_CONTENT_CAP_BYTES = 2 * 1024 * 1024;
66814
- function fileStateFingerprintSync(path69) {
66853
+ function fileStateFingerprintSync(path70) {
66815
66854
  try {
66816
- const stat2 = statSync22(path69);
66855
+ const stat2 = statSync22(path70);
66817
66856
  if (!stat2.isFile()) return null;
66818
66857
  if (stat2.size <= FILE_FINGERPRINT_CONTENT_CAP_BYTES) {
66819
- return shortFingerprint(readFileSync31(path69));
66858
+ return shortFingerprint(readFileSync31(path70));
66820
66859
  }
66821
66860
  return shortFingerprint(`${stat2.mtimeMs}\0${stat2.size}`);
66822
66861
  } catch {
@@ -67488,14 +67527,14 @@ init_install();
67488
67527
  init_ts_refs();
67489
67528
  init_parser();
67490
67529
  import * as fs40 from "fs";
67491
- import * as path45 from "path";
67530
+ import * as path46 from "path";
67492
67531
  import { execSync, spawnSync as spawnSync5 } from "child_process";
67493
67532
  function checkWorkerRunning(dataDir2) {
67494
67533
  return dataDir2 !== void 0 ? isWorkerRunning(dataDir2) : isWorkerRunning();
67495
67534
  }
67496
67535
  var DB_SIZE_WARN_BYTES = 1024 * 1024 * 1024;
67497
67536
  function checkDbExists(dataDir2) {
67498
- const dbPath = path45.join(dataDir2, "global.db");
67537
+ const dbPath = path46.join(dataDir2, "global.db");
67499
67538
  if (!fs40.existsSync(dbPath)) {
67500
67539
  return {
67501
67540
  name: "Database",
@@ -67807,8 +67846,8 @@ function runDoctor(dataDir2, configPath2, rootDir) {
67807
67846
  results.push(checkStrayClaudeMdBlocks());
67808
67847
  results.push(checkWorkerRunning(actualDataDir) ? { name: "Worker", status: "ok", message: "running" } : { name: "Worker", status: "warn", message: "not running" });
67809
67848
  results.push(checkDbExists(actualDataDir));
67810
- results.push(checkSymbolBodySize(path45.join(actualDataDir, "global.db")));
67811
- results.push(checkSymbolCount(path45.join(actualDataDir, "global.db"), rootDir));
67849
+ results.push(checkSymbolBodySize(path46.join(actualDataDir, "global.db")));
67850
+ results.push(checkSymbolCount(path46.join(actualDataDir, "global.db"), rootDir));
67812
67851
  results.push(checkDirtyQueueHealth(actualDataDir));
67813
67852
  const actualConfigPath = configPath2 || configPath();
67814
67853
  results.push(checkConfigValid(actualConfigPath));
@@ -67846,7 +67885,7 @@ async function runDoctorAndExit(opts) {
67846
67885
  console.log();
67847
67886
  try {
67848
67887
  const dir = skillOutputsDir();
67849
- const pregenPath = path45.join(dir, "pregen.json");
67888
+ const pregenPath = path46.join(dir, "pregen.json");
67850
67889
  if (fs40.existsSync(pregenPath)) {
67851
67890
  const content = JSON.parse(fs40.readFileSync(pregenPath, "utf-8"));
67852
67891
  const pregenNames = new Set(content.names || []);
@@ -67856,7 +67895,7 @@ async function runDoctorAndExit(opts) {
67856
67895
  for (const entry of entries) {
67857
67896
  if (!entry.isFile() || !entry.name.endsWith(".meta")) continue;
67858
67897
  try {
67859
- const meta3 = JSON.parse(fs40.readFileSync(path45.join(dir, entry.name), "utf-8"));
67898
+ const meta3 = JSON.parse(fs40.readFileSync(path46.join(dir, entry.name), "utf-8"));
67860
67899
  if (meta3.skillName && !pregenNames.has(meta3.skillName)) {
67861
67900
  skillsSeen.add(meta3.skillName);
67862
67901
  }
@@ -72351,8 +72390,8 @@ function trimCharacterEnd(str, char) {
72351
72390
  function unicodeEscape(str) {
72352
72391
  return str.replace(/[\s\S]/g, (c) => "\\u" + c.charCodeAt().toString(16).padStart(4, "0"));
72353
72392
  }
72354
- function get(obj, path69) {
72355
- for (const key of path69) {
72393
+ function get(obj, path70) {
72394
+ for (const key of path70) {
72356
72395
  if (!obj) {
72357
72396
  return void 0;
72358
72397
  }
@@ -73553,8 +73592,8 @@ function withBrackets(str, brackets) {
73553
73592
  const rbr = typeof brackets[1] === "string" ? brackets[1] : "]";
73554
73593
  return lbr + str + rbr;
73555
73594
  }
73556
- function pathRewrite(path69, rewriter, baseUrl, metadata, elem) {
73557
- const modifiedPath = typeof rewriter === "function" ? rewriter(path69, metadata, elem) : path69;
73595
+ function pathRewrite(path70, rewriter, baseUrl, metadata, elem) {
73596
+ const modifiedPath = typeof rewriter === "function" ? rewriter(path70, metadata, elem) : path70;
73558
73597
  return modifiedPath[0] === "/" && baseUrl ? trimCharacterEnd(baseUrl, "/") + modifiedPath : modifiedPath;
73559
73598
  }
73560
73599
  function formatImage(elem, walk, builder, formatOptions) {
@@ -73878,9 +73917,9 @@ function handleDeprecatedOptions(options) {
73878
73917
  options.selectors.push(...tagDefinitions);
73879
73918
  options.selectors = mergeDuplicatesPreferLast(options.selectors, (s) => s.selector);
73880
73919
  }
73881
- function set2(obj, path69, value) {
73882
- const valueKey = path69.pop();
73883
- for (const key of path69) {
73920
+ function set2(obj, path70, value) {
73921
+ const valueKey = path70.pop();
73922
+ for (const key of path70) {
73884
73923
  let nested = obj[key];
73885
73924
  if (!nested) {
73886
73925
  nested = {};
@@ -74162,7 +74201,7 @@ init_config();
74162
74201
  // src/shell.ts
74163
74202
  init_define_import_meta_env();
74164
74203
  import * as fs41 from "node:fs";
74165
- import * as path46 from "node:path";
74204
+ import * as path47 from "node:path";
74166
74205
  var WSL_LAUNCHER_SEGMENTS = /* @__PURE__ */ new Set(["system32", "syswow64", "windowsapps"]);
74167
74206
  function isExecutable(p) {
74168
74207
  try {
@@ -74175,15 +74214,15 @@ function isWslLauncherDir(dir) {
74175
74214
  return dir.toLowerCase().split(/[\\/]+/).some((seg) => WSL_LAUNCHER_SEGMENTS.has(seg));
74176
74215
  }
74177
74216
  function locateBashOnPath(pathValue, isExe = isExecutable) {
74178
- for (const dir of (pathValue ?? "").split(path46.delimiter)) {
74217
+ for (const dir of (pathValue ?? "").split(path47.delimiter)) {
74179
74218
  if (!dir || isWslLauncherDir(dir)) continue;
74180
- const cand = path46.join(dir, "bash.exe");
74219
+ const cand = path47.join(dir, "bash.exe");
74181
74220
  if (isExe(cand)) return cand;
74182
74221
  }
74183
74222
  return null;
74184
74223
  }
74185
74224
  function knownGitBashPaths() {
74186
- const localPrograms = process.env["LOCALAPPDATA"] ? path46.join(process.env["LOCALAPPDATA"], "Programs") : void 0;
74225
+ const localPrograms = process.env["LOCALAPPDATA"] ? path47.join(process.env["LOCALAPPDATA"], "Programs") : void 0;
74187
74226
  const bases = [
74188
74227
  process.env["ProgramFiles"],
74189
74228
  process.env["ProgramFiles(x86)"],
@@ -74193,8 +74232,8 @@ function knownGitBashPaths() {
74193
74232
  const out2 = [];
74194
74233
  for (const base of bases) {
74195
74234
  if (!base) continue;
74196
- out2.push(path46.join(base, "Git", "bin", "bash.exe"));
74197
- out2.push(path46.join(base, "Git", "usr", "bin", "bash.exe"));
74235
+ out2.push(path47.join(base, "Git", "bin", "bash.exe"));
74236
+ out2.push(path47.join(base, "Git", "usr", "bin", "bash.exe"));
74198
74237
  }
74199
74238
  return out2;
74200
74239
  }
@@ -74989,8 +75028,8 @@ function detectUnbalancedShellSyntax(cmd) {
74989
75028
  }
74990
75029
  j = delimEnd;
74991
75030
  }
74992
- const delimiter2 = cmd.slice(delimStart, j).replace(/["']/g, "");
74993
- if (delimiter2) {
75031
+ const delimiter3 = cmd.slice(delimStart, j).replace(/["']/g, "");
75032
+ if (delimiter3) {
74994
75033
  let scanPos = j;
74995
75034
  let terminatorEnd = -1;
74996
75035
  while (scanPos <= cmd.length) {
@@ -75000,7 +75039,7 @@ function detectUnbalancedShellSyntax(cmd) {
75000
75039
  if (line.endsWith("\r")) {
75001
75040
  line = line.slice(0, -1);
75002
75041
  }
75003
- const isMatch = hasIndentModifier ? line.trim() === delimiter2 : line === delimiter2;
75042
+ const isMatch = hasIndentModifier ? line.trim() === delimiter3 : line === delimiter3;
75004
75043
  if (isMatch) {
75005
75044
  terminatorEnd = nl3 === -1 ? cmd.length : nl3 + 1;
75006
75045
  break;
@@ -75009,7 +75048,7 @@ function detectUnbalancedShellSyntax(cmd) {
75009
75048
  scanPos = nl3 + 1;
75010
75049
  }
75011
75050
  if (terminatorEnd === -1) {
75012
- return `an unterminated heredoc (${delimiter2} never appears on its own line)`;
75051
+ return `an unterminated heredoc (${delimiter3} never appears on its own line)`;
75013
75052
  }
75014
75053
  i = terminatorEnd;
75015
75054
  continue;
@@ -76768,7 +76807,7 @@ init_codex_install();
76768
76807
  init_define_import_meta_env();
76769
76808
  import * as fs42 from "node:fs";
76770
76809
  import * as os12 from "node:os";
76771
- import * as path47 from "node:path";
76810
+ import * as path48 from "node:path";
76772
76811
  init_install();
76773
76812
  init_util2();
76774
76813
  init_matcher_group();
@@ -76784,7 +76823,7 @@ var GEMINI_POST_TOOLS = /* @__PURE__ */ new Set(["Bash", "Read", "Write", "Edit"
76784
76823
  var GeminiSettingsParseError = class extends Error {
76785
76824
  };
76786
76825
  function geminiSettingsPath() {
76787
- return path47.join(os12.homedir(), ".gemini", "settings.json");
76826
+ return path48.join(os12.homedir(), ".gemini", "settings.json");
76788
76827
  }
76789
76828
  function readGeminiSettings(p, opts = {}) {
76790
76829
  let raw;
@@ -76905,7 +76944,7 @@ init_install();
76905
76944
  init_util2();
76906
76945
  import * as fs43 from "node:fs";
76907
76946
  import * as os13 from "node:os";
76908
- import * as path48 from "node:path";
76947
+ import * as path49 from "node:path";
76909
76948
  var QWEN_HOOK_EVENTS = ["PreToolUse", "PostToolUse", "PreCompact", "UserPromptSubmit", "SubagentStop"];
76910
76949
  var QWEN_EVENT_ARG = {
76911
76950
  PreToolUse: "pre_tool_use",
@@ -76917,7 +76956,7 @@ var QWEN_EVENT_ARG = {
76917
76956
  var QwenSettingsParseError = class extends Error {
76918
76957
  };
76919
76958
  function qwenSettingsPath() {
76920
- return path48.join(os13.homedir(), ".qwen", "settings.json");
76959
+ return path49.join(os13.homedir(), ".qwen", "settings.json");
76921
76960
  }
76922
76961
  function readQwenSettings(p, opts = {}) {
76923
76962
  let raw;
@@ -77020,7 +77059,7 @@ function uninstallQwen() {
77020
77059
  init_define_import_meta_env();
77021
77060
  init_util2();
77022
77061
  import * as os14 from "node:os";
77023
- import * as path49 from "node:path";
77062
+ import * as path50 from "node:path";
77024
77063
 
77025
77064
  // src/bridges/pi.ts
77026
77065
  init_define_import_meta_env();
@@ -77334,16 +77373,16 @@ export default function (pi: ExtensionAPI) {
77334
77373
 
77335
77374
  // src/bridges/pi_install.ts
77336
77375
  function piGlobalExtensionPath() {
77337
- return path49.join(os14.homedir(), ".pi", "agent", "extensions", "token-goat.ts");
77376
+ return path50.join(os14.homedir(), ".pi", "agent", "extensions", "token-goat.ts");
77338
77377
  }
77339
77378
  function piLocalExtensionPath() {
77340
- return path49.join(process.cwd(), ".pi", "extensions", "token-goat.ts");
77379
+ return path50.join(process.cwd(), ".pi", "extensions", "token-goat.ts");
77341
77380
  }
77342
77381
  function piExtensionPath(opts = {}) {
77343
77382
  return opts.local === true ? piLocalExtensionPath() : piGlobalExtensionPath();
77344
77383
  }
77345
77384
  function piEntrySidecarPath(opts = {}) {
77346
- return path49.join(path49.dirname(piExtensionPath(opts)), "token-goat-entry.json");
77385
+ return path50.join(path50.dirname(piExtensionPath(opts)), "token-goat-entry.json");
77347
77386
  }
77348
77387
  function installPi(opts = {}) {
77349
77388
  const extensionPath = piExtensionPath(opts);
@@ -77366,7 +77405,7 @@ function uninstallPi(opts = {}) {
77366
77405
  init_define_import_meta_env();
77367
77406
  init_util2();
77368
77407
  import * as os15 from "node:os";
77369
- import * as path50 from "node:path";
77408
+ import * as path51 from "node:path";
77370
77409
 
77371
77410
  // src/bridges/opencode.ts
77372
77411
  init_define_import_meta_env();
@@ -77646,17 +77685,17 @@ function opencodeGlobalConfigDir() {
77646
77685
  if (process.platform === "win32") {
77647
77686
  const appData = process.env["APPDATA"];
77648
77687
  if (appData !== void 0 && appData.trim() !== "") return appData;
77649
- return path50.join(os15.homedir(), "AppData", "Roaming");
77688
+ return path51.join(os15.homedir(), "AppData", "Roaming");
77650
77689
  }
77651
77690
  const xdgConfigHome = process.env["XDG_CONFIG_HOME"];
77652
77691
  if (xdgConfigHome !== void 0 && xdgConfigHome.trim() !== "") return xdgConfigHome;
77653
- return path50.join(os15.homedir(), ".config");
77692
+ return path51.join(os15.homedir(), ".config");
77654
77693
  }
77655
77694
  function opencodePluginPath() {
77656
- return path50.join(opencodeGlobalConfigDir(), "opencode", "plugins", "token-goat.ts");
77695
+ return path51.join(opencodeGlobalConfigDir(), "opencode", "plugins", "token-goat.ts");
77657
77696
  }
77658
77697
  function opencodeEntrySidecarPath() {
77659
- return path50.join(path50.dirname(opencodePluginPath()), "token-goat-entry.json");
77698
+ return path51.join(path51.dirname(opencodePluginPath()), "token-goat-entry.json");
77660
77699
  }
77661
77700
  function installOpencode() {
77662
77701
  const pluginPath = opencodePluginPath();
@@ -77672,7 +77711,7 @@ init_define_import_meta_env();
77672
77711
  init_util2();
77673
77712
  import * as fs44 from "node:fs";
77674
77713
  import * as os16 from "node:os";
77675
- import * as path51 from "node:path";
77714
+ import * as path52 from "node:path";
77676
77715
 
77677
77716
  // src/bridges/openclaw.ts
77678
77717
  init_define_import_meta_env();
@@ -77808,16 +77847,16 @@ var OpenclawConfigParseError = class extends Error {
77808
77847
  };
77809
77848
  var OPENCLAW_PLUGIN_ID = "token-goat";
77810
77849
  function openclawHomeDir() {
77811
- return path51.join(os16.homedir(), ".openclaw");
77850
+ return path52.join(os16.homedir(), ".openclaw");
77812
77851
  }
77813
77852
  function openclawConfigPath() {
77814
- return path51.join(openclawHomeDir(), "openclaw.json");
77853
+ return path52.join(openclawHomeDir(), "openclaw.json");
77815
77854
  }
77816
77855
  function openclawPluginPath() {
77817
- return path51.join(openclawHomeDir(), "plugins", "token-goat.ts");
77856
+ return path52.join(openclawHomeDir(), "plugins", "token-goat.ts");
77818
77857
  }
77819
77858
  function openclawEntrySidecarPath() {
77820
- return path51.join(path51.dirname(openclawPluginPath()), "token-goat-entry.json");
77859
+ return path52.join(path52.dirname(openclawPluginPath()), "token-goat-entry.json");
77821
77860
  }
77822
77861
  function readOpenclawConfig(p, opts = {}) {
77823
77862
  let raw;
@@ -77870,7 +77909,7 @@ function installOpenclaw() {
77870
77909
  const settings = readOpenclawConfig(configPath2, { strict: true });
77871
77910
  const entryPath = process.argv[1];
77872
77911
  if (entryPath) {
77873
- ensureDirSync(path51.dirname(pluginPath));
77912
+ ensureDirSync(path52.dirname(pluginPath));
77874
77913
  atomicWriteText(openclawEntrySidecarPath(), JSON.stringify({ entryPath }));
77875
77914
  }
77876
77915
  const plugins = settings.plugins ?? {};
@@ -77889,7 +77928,7 @@ function installOpenclaw() {
77889
77928
  return { configPath: configPath2, pluginPath, alreadyInstalled: true };
77890
77929
  }
77891
77930
  if (pluginChanged) {
77892
- ensureDirSync(path51.dirname(pluginPath));
77931
+ ensureDirSync(path52.dirname(pluginPath));
77893
77932
  atomicWriteText(pluginPath, OPENCLAW_PLUGIN_SCRIPT);
77894
77933
  }
77895
77934
  if (configChanged) {
@@ -78267,7 +78306,7 @@ init_define_import_meta_env();
78267
78306
  init_util2();
78268
78307
  import * as fs45 from "node:fs";
78269
78308
  import * as os18 from "node:os";
78270
- import * as path52 from "node:path";
78309
+ import * as path53 from "node:path";
78271
78310
  var TENANT_HOST_RE = /^([a-z0-9-]+?)(-my)?\.sharepoint\.com$/i;
78272
78311
  function parseShareUrl(url2) {
78273
78312
  let u;
@@ -78317,7 +78356,7 @@ function candidateRoots(env, home) {
78317
78356
  try {
78318
78357
  for (const entry of fs45.readdirSync(home, { withFileTypes: true })) {
78319
78358
  if (entry.isDirectory() && /onedrive/i.test(entry.name)) {
78320
- const full = path52.join(home, entry.name);
78359
+ const full = path53.join(home, entry.name);
78321
78360
  if (!roots.includes(full)) roots.push(full);
78322
78361
  }
78323
78362
  }
@@ -78326,13 +78365,13 @@ function candidateRoots(env, home) {
78326
78365
  return roots;
78327
78366
  }
78328
78367
  function tryLibraryPaths(root, libSegments, triedPaths) {
78329
- const rawJoined = path52.join(root, ...libSegments);
78368
+ const rawJoined = path53.join(root, ...libSegments);
78330
78369
  triedPaths.push(rawJoined);
78331
78370
  if (fs45.existsSync(rawJoined)) return rawJoined;
78332
78371
  if (libSegments.length > 0) {
78333
78372
  const aliasedFirst = normalizeLibrarySegment(libSegments[0]);
78334
78373
  if (aliasedFirst !== libSegments[0]) {
78335
- const aliasedJoined = path52.join(root, aliasedFirst, ...libSegments.slice(1));
78374
+ const aliasedJoined = path53.join(root, aliasedFirst, ...libSegments.slice(1));
78336
78375
  triedPaths.push(aliasedJoined);
78337
78376
  if (fs45.existsSync(aliasedJoined)) return aliasedJoined;
78338
78377
  }
@@ -78344,9 +78383,9 @@ function resolveLocalPath(parsed, env = process.env, home = os18.homedir()) {
78344
78383
  const libSegments = parsed.libraryPath.split(/[/\\]+/).filter((s) => s.length > 0 && s !== "." && s !== "..");
78345
78384
  const triedPaths = [];
78346
78385
  function withinRoot(root, candidate) {
78347
- const resolvedRoot = path52.resolve(root) + path52.sep;
78348
- const resolvedCandidate = path52.resolve(candidate);
78349
- return (resolvedCandidate + path52.sep).startsWith(resolvedRoot);
78386
+ const resolvedRoot = path53.resolve(root) + path53.sep;
78387
+ const resolvedCandidate = path53.resolve(candidate);
78388
+ return (resolvedCandidate + path53.sep).startsWith(resolvedRoot);
78350
78389
  }
78351
78390
  function safeTryLibraryPaths(root, segments, tried) {
78352
78391
  const found = tryLibraryPaths(root, segments, tried);
@@ -78360,7 +78399,7 @@ function resolveLocalPath(parsed, env = process.env, home = os18.homedir()) {
78360
78399
  try {
78361
78400
  for (const entry of fs45.readdirSync(root, { withFileTypes: true })) {
78362
78401
  if (!entry.isDirectory() || !entry.name.toLowerCase().includes(parsed.siteName.toLowerCase())) continue;
78363
- const siteRoot = path52.join(root, entry.name);
78402
+ const siteRoot = path53.join(root, entry.name);
78364
78403
  const siteFound = safeTryLibraryPaths(siteRoot, libSegments, triedPaths);
78365
78404
  if (siteFound !== null) return { resolvedPath: siteFound, triedPaths };
78366
78405
  }
@@ -78550,7 +78589,7 @@ init_session();
78550
78589
  init_util2();
78551
78590
  init_ansi();
78552
78591
  import * as fs47 from "node:fs";
78553
- import * as path53 from "node:path";
78592
+ import * as path54 from "node:path";
78554
78593
  function writeRaw(text) {
78555
78594
  const payload = colorStdout() ? text : stripAnsi(text);
78556
78595
  process.stdout.write(ensureNewline(payload));
@@ -78562,7 +78601,7 @@ function formatTopFiles(ranked) {
78562
78601
  if (ranked.length === 0) return "";
78563
78602
  const lines2 = ["Top files this session:"];
78564
78603
  for (const { path: filePath, count } of ranked) {
78565
- const basename22 = path53.basename(filePath);
78604
+ const basename22 = path54.basename(filePath);
78566
78605
  lines2.push(` ${count.toString().padStart(3)}x ${basename22} (${filePath})`);
78567
78606
  }
78568
78607
  return lines2.join("\n");
@@ -78579,12 +78618,12 @@ function renderTopSessionFiles(topN = 5) {
78579
78618
  }
78580
78619
  function renderTopSessionFilesFromDisk(topN = 5, overrideSessionsDir) {
78581
78620
  try {
78582
- const sessionsDir = overrideSessionsDir ?? path53.join(dataDir(), "sessions");
78621
+ const sessionsDir = overrideSessionsDir ?? path54.join(dataDir(), "sessions");
78583
78622
  if (!fs47.existsSync(sessionsDir)) return "";
78584
- const files = fs47.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs47.statSync(path53.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
78623
+ const files = fs47.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs47.statSync(path54.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
78585
78624
  for (const { name: name2 } of files) {
78586
78625
  try {
78587
- const raw = fs47.readFileSync(path53.join(sessionsDir, name2), "utf-8");
78626
+ const raw = fs47.readFileSync(path54.join(sessionsDir, name2), "utf-8");
78588
78627
  const data = JSON.parse(raw);
78589
78628
  const filesList = data["files"];
78590
78629
  if (!Array.isArray(filesList)) continue;
@@ -79077,7 +79116,7 @@ async function getSectionContent(fileId, heading, opts = {}) {
79077
79116
  // src/pack.ts
79078
79117
  init_define_import_meta_env();
79079
79118
  import * as fs48 from "node:fs";
79080
- import * as path55 from "node:path";
79119
+ import * as path56 from "node:path";
79081
79120
 
79082
79121
  // node_modules/minimatch/dist/esm/index.js
79083
79122
  var esm_exports3 = {};
@@ -80160,11 +80199,11 @@ var qmarksTestNoExtDot = ([$0]) => {
80160
80199
  return (f) => f.length === len && f !== "." && f !== "..";
80161
80200
  };
80162
80201
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
80163
- var path54 = {
80202
+ var path55 = {
80164
80203
  win32: { sep: "\\" },
80165
80204
  posix: { sep: "/" }
80166
80205
  };
80167
- var sep2 = defaultPlatform === "win32" ? path54.win32.sep : path54.posix.sep;
80206
+ var sep2 = defaultPlatform === "win32" ? path55.win32.sep : path55.posix.sep;
80168
80207
  minimatch.sep = sep2;
80169
80208
  var GLOBSTAR = Symbol("globstar **");
80170
80209
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -80950,7 +80989,7 @@ var LANG_MAP = {
80950
80989
  ".exs": "elixir"
80951
80990
  };
80952
80991
  function getLang(filePath) {
80953
- const ext2 = path55.extname(filePath).toLowerCase();
80992
+ const ext2 = path56.extname(filePath).toLowerCase();
80954
80993
  return LANG_MAP[ext2] ?? "";
80955
80994
  }
80956
80995
  function matches(rel, patterns) {
@@ -80960,8 +80999,8 @@ function matches(rel, patterns) {
80960
80999
  return patterns.some((pat) => mm.minimatch(norm, pat) || mm.minimatch(base, pat));
80961
81000
  }
80962
81001
  function isPathWithinRoot(rootReal, resolvedPath) {
80963
- const rel = path55.relative(rootReal, resolvedPath);
80964
- return rel !== "" && rel !== ".." && !rel.startsWith(".." + path55.sep) && !path55.isAbsolute(rel);
81002
+ const rel = path56.relative(rootReal, resolvedPath);
81003
+ return rel !== "" && rel !== ".." && !rel.startsWith(".." + path56.sep) && !path56.isAbsolute(rel);
80965
81004
  }
80966
81005
  function openWithinRoot(rootReal, p) {
80967
81006
  let fd;
@@ -81001,11 +81040,11 @@ function openWithinRoot(rootReal, p) {
81001
81040
  }
81002
81041
  function* resolveOpenCandidates(projectRoot, patterns, rootReal, ignorePatterns, seen, skipped) {
81003
81042
  for (const pattern of patterns) {
81004
- const p = path55.isAbsolute(pattern) ? pattern : path55.join(projectRoot, pattern);
81043
+ const p = path56.isAbsolute(pattern) ? pattern : path56.join(projectRoot, pattern);
81005
81044
  if (seen.has(p)) continue;
81006
81045
  let rel;
81007
81046
  try {
81008
- rel = path55.relative(projectRoot, p).replace(/\\/g, "/");
81047
+ rel = path56.relative(projectRoot, p).replace(/\\/g, "/");
81009
81048
  } catch {
81010
81049
  skipped.push(`${p} (outside project root)`);
81011
81050
  continue;
@@ -81079,7 +81118,7 @@ function stripBlockComments(content, pattern, lineStates) {
81079
81118
  );
81080
81119
  }
81081
81120
  function stripComments4(content, filePath) {
81082
- const ext2 = path55.extname(filePath).toLowerCase();
81121
+ const ext2 = path56.extname(filePath).toLowerCase();
81083
81122
  const lineStates = computeLineStartQuoteStates(content);
81084
81123
  if (ext2 === ".py") {
81085
81124
  return stripLineComments(content, PY_LINE_COMMENT_RE, lineStates);
@@ -81117,7 +81156,7 @@ var SAFE_EXTS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp
81117
81156
  function scanSecrets(files) {
81118
81157
  const hits = [];
81119
81158
  for (const pf of files) {
81120
- if (SAFE_EXTS.has(path55.extname(pf.path).toLowerCase())) {
81159
+ if (SAFE_EXTS.has(path56.extname(pf.path).toLowerCase())) {
81121
81160
  continue;
81122
81161
  }
81123
81162
  for (const [lineno, line] of pf.content.split("\n").entries()) {
@@ -81140,7 +81179,7 @@ function scanSecrets(files) {
81140
81179
  function collectFiles(projectRoot, patterns, opts = {}) {
81141
81180
  const result = { files: [], skipped: [], total_lines: 0, total_tokens: 0 };
81142
81181
  const seen = /* @__PURE__ */ new Set();
81143
- const rootResolved = path55.resolve(projectRoot);
81182
+ const rootResolved = path56.resolve(projectRoot);
81144
81183
  let rootReal;
81145
81184
  try {
81146
81185
  rootReal = fs48.realpathSync(rootResolved);
@@ -81315,7 +81354,7 @@ function formatPack(result, style, opts = {}) {
81315
81354
  function estimateBudget(projectRoot, patterns, opts = {}) {
81316
81355
  const result = { entries: [], skipped: [], total_lines: 0, total_tokens: 0 };
81317
81356
  const seen = /* @__PURE__ */ new Set();
81318
- const rootResolved = path55.resolve(projectRoot);
81357
+ const rootResolved = path56.resolve(projectRoot);
81319
81358
  let rootReal;
81320
81359
  try {
81321
81360
  rootReal = fs48.realpathSync(rootResolved);
@@ -81769,7 +81808,7 @@ init_define_import_meta_env();
81769
81808
  init_constants();
81770
81809
  init_util2();
81771
81810
  import * as fs49 from "node:fs";
81772
- import * as path56 from "node:path";
81811
+ import * as path57 from "node:path";
81773
81812
  var KEY_RE2 = /^[A-Za-z0-9_-]{1,80}$/;
81774
81813
  var DEFAULT_FAILURES_STATE_KEY = "default";
81775
81814
  function validateKey2(key) {
@@ -81781,7 +81820,7 @@ function validateKey2(key) {
81781
81820
  }
81782
81821
  function failuresStatePath(projectHash2, key) {
81783
81822
  validateKey2(key);
81784
- return path56.join(dataDir(), "projects", `${projectHash2}_failures_${key}.json`);
81823
+ return path57.join(dataDir(), "projects", `${projectHash2}_failures_${key}.json`);
81785
81824
  }
81786
81825
  function loadFailureSnapshot(projectHash2, key) {
81787
81826
  const p = failuresStatePath(projectHash2, key);
@@ -81802,7 +81841,7 @@ function loadFailureSnapshot(projectHash2, key) {
81802
81841
  }
81803
81842
  function saveFailureSnapshot(projectHash2, key, snapshot) {
81804
81843
  const p = failuresStatePath(projectHash2, key);
81805
- const dir = path56.dirname(p);
81844
+ const dir = path57.dirname(p);
81806
81845
  ensureDirSync(dir);
81807
81846
  const content = JSON.stringify(snapshot);
81808
81847
  const doSave = () => {
@@ -81825,7 +81864,7 @@ init_stats();
81825
81864
  init_util2();
81826
81865
  import { createRequire as createRequire8 } from "node:module";
81827
81866
  import * as fs50 from "node:fs";
81828
- import * as path57 from "node:path";
81867
+ import * as path58 from "node:path";
81829
81868
  var _require6 = createRequire8(import.meta.url);
81830
81869
  var _ts2 = null;
81831
81870
  var _tsLoadAttempted2 = false;
@@ -81876,7 +81915,7 @@ function listInstalledPackageNames(nodeModulesDir) {
81876
81915
  if (entry.name.startsWith("@")) {
81877
81916
  let scoped;
81878
81917
  try {
81879
- scoped = fs50.readdirSync(path57.join(nodeModulesDir, entry.name), { withFileTypes: true });
81918
+ scoped = fs50.readdirSync(path58.join(nodeModulesDir, entry.name), { withFileTypes: true });
81880
81919
  } catch {
81881
81920
  continue;
81882
81921
  }
@@ -81893,7 +81932,7 @@ var README_NAME_RE = /^readme(\.(md|markdown|txt))?$/i;
81893
81932
  function findReadmeFile(pkgDir) {
81894
81933
  const direct = findReadmeIn(pkgDir);
81895
81934
  if (direct !== null) return direct;
81896
- return findReadmeIn(path57.join(pkgDir, "docs"));
81935
+ return findReadmeIn(path58.join(pkgDir, "docs"));
81897
81936
  }
81898
81937
  function findReadmeIn(dir) {
81899
81938
  let entries;
@@ -81910,7 +81949,7 @@ function findReadmeIn(dir) {
81910
81949
  return 1;
81911
81950
  };
81912
81951
  matches2.sort((a, b) => rank(a.name) - rank(b.name));
81913
- return path57.join(dir, matches2[0].name);
81952
+ return path58.join(dir, matches2[0].name);
81914
81953
  }
81915
81954
  function typesPackageDirName(pkgName) {
81916
81955
  if (pkgName.startsWith("@")) {
@@ -81937,30 +81976,30 @@ function resolveTypesLocation(pkgDir, pkgJson, nodeModulesDir, pkgName) {
81937
81976
  if (declared !== void 0) {
81938
81977
  const candidates = [declared, declared.endsWith(".d.ts") ? declared : `${declared}.d.ts`, declared.replace(/\.[cm]?[jt]s$/, ".d.ts")];
81939
81978
  for (const c of candidates) {
81940
- const p = path57.join(pkgDir, c);
81979
+ const p = path58.join(pkgDir, c);
81941
81980
  if (fileExists2(p)) return { path: p, source: "bundled" };
81942
81981
  }
81943
81982
  }
81944
81983
  const main = typeof pkgJson["main"] === "string" ? pkgJson["main"] : "index.js";
81945
- const mainDts = path57.join(pkgDir, main.replace(/\.[cm]?js$/, ".d.ts"));
81984
+ const mainDts = path58.join(pkgDir, main.replace(/\.[cm]?js$/, ".d.ts"));
81946
81985
  if (fileExists2(mainDts)) return { path: mainDts, source: "bundled" };
81947
- const indexDts = path57.join(pkgDir, "index.d.ts");
81986
+ const indexDts = path58.join(pkgDir, "index.d.ts");
81948
81987
  if (fileExists2(indexDts)) return { path: indexDts, source: "bundled" };
81949
81988
  const typesDirName = typesPackageDirName(pkgName);
81950
- const typesPkgDir = path57.join(nodeModulesDir, "@types", typesDirName);
81951
- const typesPkgJsonRaw = readFileTextOrNull(path57.join(typesPkgDir, "package.json"));
81989
+ const typesPkgDir = path58.join(nodeModulesDir, "@types", typesDirName);
81990
+ const typesPkgJsonRaw = readFileTextOrNull(path58.join(typesPkgDir, "package.json"));
81952
81991
  if (typesPkgJsonRaw !== null) {
81953
81992
  try {
81954
81993
  const typesPkgJson = JSON.parse(typesPkgJsonRaw);
81955
81994
  const entry = (typeof typesPkgJson["types"] === "string" ? typesPkgJson["types"] : void 0) ?? (typeof typesPkgJson["main"] === "string" ? typesPkgJson["main"] : void 0) ?? "index.d.ts";
81956
81995
  const entryCandidates = [entry, entry.endsWith(".d.ts") ? entry : `${entry}.d.ts`, entry.replace(/\.[cm]?[jt]s$/, ".d.ts")];
81957
81996
  for (const c of entryCandidates) {
81958
- const entryPath = path57.join(typesPkgDir, c);
81997
+ const entryPath = path58.join(typesPkgDir, c);
81959
81998
  if (fileExists2(entryPath)) return { path: entryPath, source: "@types" };
81960
81999
  }
81961
82000
  } catch {
81962
82001
  }
81963
- const fallback = path57.join(typesPkgDir, "index.d.ts");
82002
+ const fallback = path58.join(typesPkgDir, "index.d.ts");
81964
82003
  if (fileExists2(fallback)) return { path: fallback, source: "@types" };
81965
82004
  }
81966
82005
  return null;
@@ -82027,9 +82066,9 @@ function recordDepDocsStat(fullSourceBytes, emittedText, packageName) {
82027
82066
  }
82028
82067
  function runDepDocs(opts) {
82029
82068
  const root = resolveProjectRoot({ project: opts.projectRoot ?? process.cwd() });
82030
- const nodeModulesDir = path57.join(root, "node_modules");
82031
- const pkgDir = path57.join(nodeModulesDir, opts.packageName);
82032
- const pkgJsonPath = path57.join(pkgDir, "package.json");
82069
+ const nodeModulesDir = path58.join(root, "node_modules");
82070
+ const pkgDir = path58.join(nodeModulesDir, opts.packageName);
82071
+ const pkgJsonPath = path58.join(pkgDir, "package.json");
82033
82072
  if (!dirExists(pkgDir) || !fileExists2(pkgJsonPath)) {
82034
82073
  const known = listInstalledPackageNames(nodeModulesDir);
82035
82074
  const suggestions = suggestPackageNames(opts.packageName, known);
@@ -82557,7 +82596,7 @@ init_db();
82557
82596
  init_constants();
82558
82597
  init_worker();
82559
82598
  import * as fs51 from "node:fs";
82560
- import * as path58 from "node:path";
82599
+ import * as path59 from "node:path";
82561
82600
  var DERIVED_TABLES = ["chunk_vectors", "chunks", "refs", "symbols", "files"];
82562
82601
  function indexSizeBytes(dbPath) {
82563
82602
  let total = 0;
@@ -82625,7 +82664,7 @@ function mb(bytes) {
82625
82664
  }
82626
82665
  function cmdReclaimIndex(opts) {
82627
82666
  const dbPath = opts.dbPath ?? globalDbPath();
82628
- if (opts.force !== true && isWorkerRunning(path58.dirname(dbPath))) {
82667
+ if (opts.force !== true && isWorkerRunning(path59.dirname(dbPath))) {
82629
82668
  throw new Error(
82630
82669
  "reclaim-index: the worker daemon is running and writing to this index. Stop it first with 'token-goat worker stop', then re-run. Pass --force to proceed anyway (results may be inaccurate if the worker is really live)."
82631
82670
  );
@@ -82660,7 +82699,7 @@ function cmdReclaimIndex(opts) {
82660
82699
  }
82661
82700
  if (result.checkpointBusy) {
82662
82701
  process.stdout.write(
82663
- ` note: a concurrent reader blocked WAL truncation, so some space may still be held in ${path58.basename(dbPath)}-wal
82702
+ ` note: a concurrent reader blocked WAL truncation, so some space may still be held in ${path59.basename(dbPath)}-wal
82664
82703
  `
82665
82704
  );
82666
82705
  }
@@ -82677,7 +82716,7 @@ init_index_prune();
82677
82716
  init_disk_cache();
82678
82717
  import * as fs52 from "node:fs";
82679
82718
  import * as os19 from "node:os";
82680
- import * as path59 from "node:path";
82719
+ import * as path60 from "node:path";
82681
82720
  init_util2();
82682
82721
  init_paths();
82683
82722
  init_ansi();
@@ -82691,7 +82730,7 @@ function emitErr4(text) {
82691
82730
  process.stderr.write(ensureNewline(text));
82692
82731
  }
82693
82732
  function saveConfigSafe(cfg) {
82694
- ensureDirSync(path59.dirname(configPath()));
82733
+ ensureDirSync(path60.dirname(configPath()));
82695
82734
  saveConfig(cfg);
82696
82735
  }
82697
82736
  function levenshtein(a, b, cap = 3) {
@@ -82938,8 +82977,8 @@ function cmdConfig(opts) {
82938
82977
  saveConfigSafe(cfg);
82939
82978
  return coercedValue;
82940
82979
  };
82941
- ensureDirSync(path59.dirname(configPath()));
82942
- const lockPath = path59.join(path59.dirname(configPath()), ".config.lock");
82980
+ ensureDirSync(path60.dirname(configPath()));
82981
+ const lockPath = path60.join(path60.dirname(configPath()), ".config.lock");
82943
82982
  const lockResult = withFileLock(lockPath, applySet, { waitMs: LOCK_WAIT_MS_HARDENED });
82944
82983
  const coerced = lockResult === void 0 ? applySet() : lockResult;
82945
82984
  invalidateConfigCache();
@@ -83075,7 +83114,7 @@ function cmdProject(opts) {
83075
83114
  emitErr4("project exclude requires a path argument");
83076
83115
  throw new Error("missing path");
83077
83116
  }
83078
- const target = path59.resolve(opts.pathArg);
83117
+ const target = path60.resolve(opts.pathArg);
83079
83118
  const cfg = loadPersistedConfig();
83080
83119
  const targetFolded = foldPath(normalizePath(target));
83081
83120
  if (cfg.worker.blocked_roots.some((r) => foldPath(normalizePath(r)) === targetFolded)) {
@@ -83144,7 +83183,7 @@ function recordCompactDocStat(fullSourceBytes, emittedText, detail) {
83144
83183
  recordStat("compact_doc", bytesSaved, Math.round(bytesSaved / 4), void 0, detail);
83145
83184
  }
83146
83185
  function cmdCompactDoc(opts) {
83147
- const resolved = path59.resolve(opts.filePath);
83186
+ const resolved = path60.resolve(opts.filePath);
83148
83187
  if (opts.heading !== void 0) {
83149
83188
  const result = compactDoc(resolved, opts.heading);
83150
83189
  if (result === null) {
@@ -83251,7 +83290,7 @@ async function cmdFetchImage(opts) {
83251
83290
  throw new Error(`fetch failed: ${opts.url}`, { cause: e });
83252
83291
  }
83253
83292
  const buf = fetched.body;
83254
- const outPath = opts.out ?? path59.join(os19.tmpdir(), `tg-fetch-${Date.now()}${extensionForContentType(fetched.contentType)}`);
83293
+ const outPath = opts.out ?? path60.join(os19.tmpdir(), `tg-fetch-${Date.now()}${extensionForContentType(fetched.contentType)}`);
83255
83294
  const originalBytes = buf.length;
83256
83295
  let shrunkBytes;
83257
83296
  let outData;
@@ -83340,7 +83379,7 @@ init_cli_context_stats();
83340
83379
  init_project();
83341
83380
  import * as fs53 from "node:fs";
83342
83381
  import * as os20 from "node:os";
83343
- import * as path60 from "node:path";
83382
+ import * as path61 from "node:path";
83344
83383
  import * as readline2 from "node:readline";
83345
83384
  var FRONTMATTER_KEYS = /* @__PURE__ */ new Set(["description", "tools", "allowed-tools", "allowed_tools"]);
83346
83385
  function parseBudget(name2, value) {
@@ -83399,17 +83438,17 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
83399
83438
  logicalRoot = await fs53.promises.realpath(root);
83400
83439
  } catch (error52) {
83401
83440
  if (error52.code === "ENOENT") return entries;
83402
- diagnostics.push({ path: path60.resolve(root), reason: "unreadable root" });
83441
+ diagnostics.push({ path: path61.resolve(root), reason: "unreadable root" });
83403
83442
  return entries;
83404
83443
  }
83405
83444
  if (rootIsLink && !followLinks) {
83406
- diagnostics.push({ path: path60.resolve(root), reason: "external root link skipped (use --follow-links)" });
83445
+ diagnostics.push({ path: path61.resolve(root), reason: "external root link skipped (use --follow-links)" });
83407
83446
  return entries;
83408
83447
  }
83409
83448
  const canonicalKey = (candidate) => process.platform === "win32" ? candidate.toLocaleLowerCase() : candidate;
83410
83449
  const isContained = (candidate, allowedRoot) => {
83411
- const relative11 = path60.relative(canonicalKey(allowedRoot), canonicalKey(candidate));
83412
- return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path60.sep}`) && !path60.isAbsolute(relative11);
83450
+ const relative11 = path61.relative(canonicalKey(allowedRoot), canonicalKey(candidate));
83451
+ return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path61.sep}`) && !path61.isAbsolute(relative11);
83413
83452
  };
83414
83453
  async function visit(candidate, allowedRoot, topLevel = false) {
83415
83454
  let real;
@@ -83418,13 +83457,13 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
83418
83457
  candidateIsLink = (await fs53.promises.lstat(candidate)).isSymbolicLink();
83419
83458
  real = await fs53.promises.realpath(candidate);
83420
83459
  } catch {
83421
- diagnostics.push({ path: path60.resolve(candidate), reason: "broken or unreadable link" });
83460
+ diagnostics.push({ path: path61.resolve(candidate), reason: "broken or unreadable link" });
83422
83461
  return;
83423
83462
  }
83424
83463
  const withinAllowedRoot = allowedRoot === void 0 ? isContained(real, logicalRoot) : isContained(real, allowedRoot);
83425
83464
  const canFollowExternal = followLinks && topLevel;
83426
83465
  if (!withinAllowedRoot && !canFollowExternal) {
83427
- diagnostics.push({ path: path60.resolve(candidate), reason: candidateIsLink ? "external link skipped (use --follow-links)" : "canonical target outside scan root" });
83466
+ diagnostics.push({ path: path61.resolve(candidate), reason: candidateIsLink ? "external link skipped (use --follow-links)" : "canonical target outside scan root" });
83428
83467
  return;
83429
83468
  }
83430
83469
  const trustedRoot = !withinAllowedRoot && canFollowExternal ? real : allowedRoot ?? real;
@@ -83432,7 +83471,7 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
83432
83471
  try {
83433
83472
  stat2 = await fs53.promises.stat(real);
83434
83473
  } catch {
83435
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable" });
83474
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable" });
83436
83475
  return;
83437
83476
  }
83438
83477
  const canonical = process.platform === "win32" ? real.toLocaleLowerCase() : real;
@@ -83443,14 +83482,14 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
83443
83482
  try {
83444
83483
  children = await fs53.promises.readdir(real, { withFileTypes: true });
83445
83484
  } catch {
83446
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable directory" });
83485
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable directory" });
83447
83486
  return;
83448
83487
  }
83449
83488
  children.sort((a, b) => a.name.localeCompare(b.name));
83450
- for (const child of children) await visit(path60.join(real, child.name), trustedRoot);
83489
+ for (const child of children) await visit(path61.join(real, child.name), trustedRoot);
83451
83490
  return;
83452
83491
  }
83453
- if (!stat2.isFile() || path60.extname(real).toLowerCase() !== ".md") return;
83492
+ if (!stat2.isFile() || path61.extname(real).toLowerCase() !== ".md") return;
83454
83493
  if (seenFiles.has(canonical)) return;
83455
83494
  seenFiles.add(canonical);
83456
83495
  try {
@@ -83460,35 +83499,35 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
83460
83499
  const toolsBytes = Buffer.byteLength(metadata.tools, "utf8");
83461
83500
  entries.push({
83462
83501
  kind,
83463
- path: path60.resolve(real),
83502
+ path: path61.resolve(real),
83464
83503
  description_bytes: descriptionBytes,
83465
83504
  tools_bytes: toolsBytes,
83466
83505
  metadata_bytes: descriptionBytes + toolsBytes,
83467
83506
  estimated_tokens: Math.floor((descriptionBytes + toolsBytes) / 4)
83468
83507
  });
83469
83508
  } catch {
83470
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable file" });
83509
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable file" });
83471
83510
  }
83472
83511
  }
83473
83512
  try {
83474
83513
  const children = await fs53.promises.readdir(logicalRoot, { withFileTypes: true });
83475
83514
  children.sort((a, b) => a.name.localeCompare(b.name));
83476
- for (const child of children) await visit(path60.join(logicalRoot, child.name), void 0, true);
83515
+ for (const child of children) await visit(path61.join(logicalRoot, child.name), void 0, true);
83477
83516
  } catch {
83478
- diagnostics.push({ path: path60.resolve(root), reason: "unreadable root" });
83517
+ diagnostics.push({ path: path61.resolve(root), reason: "unreadable root" });
83479
83518
  }
83480
83519
  return entries;
83481
83520
  }
83482
83521
  async function buildBootstrapAudit(opts = {}) {
83483
83522
  const project = resolveProjectRoot(opts.project === void 0 ? {} : { project: opts.project });
83484
- const home = path60.resolve(opts.home ?? os20.homedir());
83523
+ const home = path61.resolve(opts.home ?? os20.homedir());
83485
83524
  const context = buildStats(project, home, opts.project === void 0 ? [] : [opts.project]);
83486
83525
  const diagnostics = [];
83487
83526
  const top = opts.top === void 0 ? 10 : parseBudget("--top", opts.top) ?? 10;
83488
83527
  const visitedDirs = /* @__PURE__ */ new Set();
83489
83528
  const seenFiles = /* @__PURE__ */ new Set();
83490
- const agents = await scanMetadataRoot(path60.join(home, ".claude", "agents"), "agent", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
83491
- const skills = await scanMetadataRoot(path60.join(home, ".claude", "skills"), "skill", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
83529
+ const agents = await scanMetadataRoot(path61.join(home, ".claude", "agents"), "agent", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
83530
+ const skills = await scanMetadataRoot(path61.join(home, ".claude", "skills"), "skill", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
83492
83531
  const largest = [...agents, ...skills].sort((a, b) => b.metadata_bytes - a.metadata_bytes || a.path.localeCompare(b.path)).slice(0, top);
83493
83532
  const metadataBytes = [...agents, ...skills].reduce((sum, entry) => sum + entry.metadata_bytes, 0);
83494
83533
  const totalTokens = context.total_tokens + Math.floor(metadataBytes / 4);
@@ -83554,7 +83593,7 @@ init_memory_prune();
83554
83593
  init_project();
83555
83594
  init_confirm_apply();
83556
83595
  import * as fs54 from "node:fs";
83557
- import * as path61 from "node:path";
83596
+ import * as path62 from "node:path";
83558
83597
  function removeExactDupLines(text, report) {
83559
83598
  if (report.exactDupLines.length === 0) return text;
83560
83599
  const toRemove = new Set(report.exactDupLines.map(([, dupIdx]) => dupIdx));
@@ -83612,7 +83651,7 @@ function printReport(reports, clusters) {
83612
83651
  } else {
83613
83652
  for (const cluster of clusters) {
83614
83653
  w(
83615
- ` [${cluster.method}, similarity ${cluster.similarity}, ~${cluster.tokens} tok] ${cluster.members.map((m) => path61.basename(m)).join(", ")}
83654
+ ` [${cluster.method}, similarity ${cluster.similarity}, ~${cluster.tokens} tok] ${cluster.members.map((m) => path62.basename(m)).join(", ")}
83616
83655
  `
83617
83656
  );
83618
83657
  }
@@ -83627,7 +83666,7 @@ async function runMemoryCommand(opts = {}) {
83627
83666
  const claudeMds = findClaudeMdFiles(projectRoot);
83628
83667
  const reports = auditClaudeMd(claudeMds);
83629
83668
  const memoryMdPath = findMemoryMd(projectRoot);
83630
- const clusters = memoryMdPath !== null ? await findContentDuplicates(path61.dirname(memoryMdPath)) : [];
83669
+ const clusters = memoryMdPath !== null ? await findContentDuplicates(path62.dirname(memoryMdPath)) : [];
83631
83670
  printReport(reports, clusters);
83632
83671
  if (opts.fix !== true) return;
83633
83672
  const changes = [];
@@ -83675,18 +83714,18 @@ async function runMemoryCommand(opts = {}) {
83675
83714
  init_define_import_meta_env();
83676
83715
  init_project();
83677
83716
  import * as fs56 from "node:fs";
83678
- import * as path63 from "node:path";
83717
+ import * as path64 from "node:path";
83679
83718
 
83680
83719
  // src/waste.ts
83681
83720
  init_define_import_meta_env();
83682
83721
  init_overflow_guard();
83683
83722
  import * as fs55 from "node:fs";
83684
83723
  import * as os21 from "node:os";
83685
- import * as path62 from "node:path";
83724
+ import * as path63 from "node:path";
83686
83725
  function projectTranscriptsDir(projectRoot) {
83687
- const rootStr = path62.resolve(projectRoot);
83726
+ const rootStr = path63.resolve(projectRoot);
83688
83727
  const slug = rootStr.replace(/[^A-Za-z0-9]/g, "-");
83689
- return path62.join(os21.homedir(), ".claude", "projects", slug);
83728
+ return path63.join(os21.homedir(), ".claude", "projects", slug);
83690
83729
  }
83691
83730
  function findLatestTranscript(projectRoot) {
83692
83731
  const dir = projectTranscriptsDir(projectRoot);
@@ -83698,7 +83737,7 @@ function findLatestTranscript(projectRoot) {
83698
83737
  }
83699
83738
  let best = null;
83700
83739
  for (const name2 of entries) {
83701
- const full = path62.join(dir, name2);
83740
+ const full = path63.join(dir, name2);
83702
83741
  let stat2;
83703
83742
  try {
83704
83743
  stat2 = fs55.statSync(full);
@@ -83980,7 +84019,7 @@ function printReport2(report) {
83980
84019
  }
83981
84020
  async function runWasteCommand(opts = {}) {
83982
84021
  const projectRoot = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
83983
- const transcriptPath = opts.transcript !== void 0 ? path63.resolve(opts.transcript) : findLatestTranscript(projectRoot);
84022
+ const transcriptPath = opts.transcript !== void 0 ? path64.resolve(opts.transcript) : findLatestTranscript(projectRoot);
83984
84023
  if (transcriptPath === null) {
83985
84024
  if (opts.json === true) {
83986
84025
  process.stdout.write(`${JSON.stringify({ error: "no session transcript found", project: projectRoot })}
@@ -84013,7 +84052,7 @@ async function runWasteCommand(opts = {}) {
84013
84052
  init_define_import_meta_env();
84014
84053
  init_compact();
84015
84054
  import * as fs57 from "node:fs";
84016
- import * as path64 from "node:path";
84055
+ import * as path65 from "node:path";
84017
84056
  import * as readline3 from "node:readline";
84018
84057
  init_project();
84019
84058
  function resolveSessionTranscript(arg, opts = {}) {
@@ -84022,7 +84061,7 @@ function resolveSessionTranscript(arg, opts = {}) {
84022
84061
  const projectRoot2 = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
84023
84062
  const dir = projectTranscriptsDir(projectRoot2);
84024
84063
  const byId = arg.endsWith(".jsonl") ? arg : `${arg}.jsonl`;
84025
- const candidate = path64.join(dir, byId);
84064
+ const candidate = path65.join(dir, byId);
84026
84065
  if (fs57.existsSync(candidate) && fs57.statSync(candidate).isFile()) return candidate;
84027
84066
  return null;
84028
84067
  }
@@ -84183,9 +84222,9 @@ init_define_import_meta_env();
84183
84222
  init_project();
84184
84223
  init_disk_cache();
84185
84224
  import * as fs58 from "node:fs";
84186
- import * as path65 from "node:path";
84225
+ import * as path66 from "node:path";
84187
84226
  function readMcpConfig(projectRoot) {
84188
- const configPath2 = path65.join(projectRoot, ".mcp.json");
84227
+ const configPath2 = path66.join(projectRoot, ".mcp.json");
84189
84228
  try {
84190
84229
  if (!fs58.existsSync(configPath2)) {
84191
84230
  return null;
@@ -84834,14 +84873,14 @@ async function cmdInstall(opts) {
84834
84873
  );
84835
84874
  }
84836
84875
  try {
84837
- const skillDir2 = path68.join(homedir19(), ".claude", "skills");
84876
+ const skillDir2 = path69.join(homedir19(), ".claude", "skills");
84838
84877
  if (fs60.existsSync(skillDir2)) {
84839
84878
  const entries = fs60.readdirSync(skillDir2, { withFileTypes: true });
84840
84879
  const skillNames = [];
84841
84880
  const sessionId = getSessionId();
84842
84881
  for (const entry of entries) {
84843
84882
  if (!entry.isDirectory()) continue;
84844
- const skillFile = path68.join(skillDir2, entry.name, "SKILL.md");
84883
+ const skillFile = path69.join(skillDir2, entry.name, "SKILL.md");
84845
84884
  if (fs60.existsSync(skillFile)) {
84846
84885
  const body = fs60.readFileSync(skillFile, "utf-8");
84847
84886
  const compact = extractCompactFromMarker(body);
@@ -84854,7 +84893,7 @@ async function cmdInstall(opts) {
84854
84893
  if (skillNames.length > 0) {
84855
84894
  const dir = skillOutputsDir();
84856
84895
  await fs60.promises.mkdir(dir, { recursive: true });
84857
- const pregenPath = path68.join(dir, "pregen.json");
84896
+ const pregenPath = path69.join(dir, "pregen.json");
84858
84897
  const pregenData = { ts: Date.now(), names: skillNames };
84859
84898
  await fs60.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
84860
84899
  out(`Pre-generated ${skillNames.length} skill compacts.`);
@@ -85592,8 +85631,8 @@ async function cmdSkillCompact(name2, opts) {
85592
85631
  }
85593
85632
  throw new CliError(`failed to read skill file '${opts.path}': ${extractErrorMessage(e)}`);
85594
85633
  }
85595
- cacheName = name2 ?? path68.basename(path68.dirname(path68.resolve(opts.path)));
85596
- sourcePath = path68.resolve(opts.path);
85634
+ cacheName = name2 ?? path69.basename(path69.dirname(path69.resolve(opts.path)));
85635
+ sourcePath = path69.resolve(opts.path);
85597
85636
  } else {
85598
85637
  if (name2 === void 0 || !name2.trim()) {
85599
85638
  throw new CliError("skill-compact requires a <name> or --path <file>");
@@ -85734,8 +85773,8 @@ async function cmdSkillDiff(name2) {
85734
85773
  }
85735
85774
  const newer = versions[0];
85736
85775
  const older = versions[1];
85737
- const newerBody = await fs60.promises.readFile(path68.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
85738
- const olderBody = await fs60.promises.readFile(path68.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
85776
+ const newerBody = await fs60.promises.readFile(path69.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
85777
+ const olderBody = await fs60.promises.readFile(path69.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
85739
85778
  if (newerBody === null || olderBody === null) {
85740
85779
  out(`a cached version of '${name2}' was evicted while diffing -- try again`);
85741
85780
  return;
@@ -85782,7 +85821,7 @@ function atomicWriteBuffer(dest, data) {
85782
85821
  if (e.code !== "ENOENT") throw e;
85783
85822
  }
85784
85823
  const rnd = Math.random().toString(36).slice(2, 8);
85785
- const tmp = path68.join(path68.dirname(path68.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
85824
+ const tmp = path69.join(path69.dirname(path69.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
85786
85825
  try {
85787
85826
  fs60.writeFileSync(tmp, data, { mode: 384 });
85788
85827
  try {
@@ -85820,9 +85859,9 @@ function mapFsError(e, src, dest, srcLabel = "source") {
85820
85859
  const fe = e;
85821
85860
  if (fe.code === "ENOENT") {
85822
85861
  const errPath = fe.path ?? "";
85823
- const isSource = src !== void 0 && path68.resolve(errPath) === path68.resolve(src);
85862
+ const isSource = src !== void 0 && path69.resolve(errPath) === path69.resolve(src);
85824
85863
  if (isSource) throw new CliError(`${srcLabel} file not found: ${src}`);
85825
- const destDir = dest ? path68.dirname(path68.resolve(dest)) : path68.dirname(path68.resolve(errPath || "."));
85864
+ const destDir = dest ? path69.dirname(path69.resolve(dest)) : path69.dirname(path69.resolve(errPath || "."));
85826
85865
  throw new CliError(`destination directory does not exist: ${destDir}`);
85827
85866
  }
85828
85867
  if (fe.code === "ENOTDIR") {
@@ -85833,7 +85872,7 @@ function mapFsError(e, src, dest, srcLabel = "source") {
85833
85872
  }
85834
85873
  if (fe.code === "EISDIR") {
85835
85874
  const errPath = fe.path ?? "";
85836
- const isSource = src !== void 0 && (errPath === "" || path68.resolve(errPath) === path68.resolve(src));
85875
+ const isSource = src !== void 0 && (errPath === "" || path69.resolve(errPath) === path69.resolve(src));
85837
85876
  if (isSource) throw new CliError(`source is a directory, not a file: ${src}`);
85838
85877
  throw new CliError(`destination is a directory, not a file: ${dest ?? (errPath || "(unknown)")}`);
85839
85878
  }
@@ -85902,7 +85941,7 @@ function validateWritablePath(dest, label) {
85902
85941
  throw new CliError(`${label} path contains a null byte`);
85903
85942
  }
85904
85943
  if (isWindows()) {
85905
- const base = path68.basename(dest);
85944
+ const base = path69.basename(dest);
85906
85945
  const stem = base.replace(/\.[^.]*$/, "").toUpperCase();
85907
85946
  if (WIN_RESERVED.has(stem)) {
85908
85947
  throw new CliError(`${label} '${base}' is a reserved Windows device name`);
@@ -86406,17 +86445,17 @@ function expandGlobs(root, patterns, globFnOverride) {
86406
86445
  if (globFn !== void 0 && (p.includes("*") || p.includes("?") || p.includes("{"))) {
86407
86446
  try {
86408
86447
  const hits = globFn(p, { cwd: root });
86409
- for (const h of hits) out2.push(path68.isAbsolute(h) ? h : path68.join(root, h));
86448
+ for (const h of hits) out2.push(path69.isAbsolute(h) ? h : path69.join(root, h));
86410
86449
  continue;
86411
86450
  } catch {
86412
86451
  }
86413
86452
  }
86414
- out2.push(path68.isAbsolute(p) ? p : path68.join(root, p));
86453
+ out2.push(path69.isAbsolute(p) ? p : path69.join(root, p));
86415
86454
  }
86416
86455
  return out2;
86417
86456
  }
86418
86457
  function readIgnoreFile(root) {
86419
- const ignorePath = path68.join(root, ".tokengoatignore");
86458
+ const ignorePath = path69.join(root, ".tokengoatignore");
86420
86459
  let raw;
86421
86460
  try {
86422
86461
  raw = fs60.readFileSync(ignorePath, "utf8");
@@ -86485,7 +86524,7 @@ function cmdTokens(patterns, opts) {
86485
86524
  if (opts.tree === true) {
86486
86525
  const dirs = /* @__PURE__ */ new Map();
86487
86526
  for (const e of entries) {
86488
- const dir = path68.dirname(e.rel_path);
86527
+ const dir = path69.dirname(e.rel_path);
86489
86528
  if (!dirs.has(dir)) dirs.set(dir, []);
86490
86529
  dirs.get(dir).push(e);
86491
86530
  }
@@ -86495,7 +86534,7 @@ function cmdTokens(patterns, opts) {
86495
86534
  const pct = result.total_tokens > 0 ? Math.round(dirTokens / result.total_tokens * 100) : 0;
86496
86535
  lines3.push(`${dir}/ (${dirTokens} tokens, ${pct}%)`);
86497
86536
  for (const e of dirEntries) {
86498
- lines3.push(` ${path68.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
86537
+ lines3.push(` ${path69.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
86499
86538
  }
86500
86539
  }
86501
86540
  out(lines3.join("\n"));
@@ -86778,13 +86817,14 @@ function buildProgram() {
86778
86817
  })
86779
86818
  )
86780
86819
  );
86781
- 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(
86820
+ 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)").option("--grep <pattern>", "only show impacted symbols whose name matches this regex (literal substring if it is not valid regex)").action(
86782
86821
  (symbol3, opts) => runExit(
86783
86822
  () => runImpact({
86784
86823
  symbol: symbol3,
86785
86824
  ...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
86786
86825
  ...opts.json === true ? { json: true } : {},
86787
- ...opts.excludeTests === true ? { excludeTests: true } : {}
86826
+ ...opts.excludeTests === true ? { excludeTests: true } : {},
86827
+ ...opts.grep !== void 0 ? { grep: opts.grep } : {}
86788
86828
  })
86789
86829
  )
86790
86830
  );