token-goat 2.6.10 → 2.6.12

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.
Files changed (2) hide show
  1. package/dist/token-goat.mjs +1146 -590
  2. package/package.json +1 -1
@@ -987,7 +987,7 @@ var require_command = __commonJS({
987
987
  var EventEmitter3 = __require("node:events").EventEmitter;
988
988
  var childProcess2 = __require("node:child_process");
989
989
  var path56 = __require("node:path");
990
- var fs49 = __require("node:fs");
990
+ var fs50 = __require("node:fs");
991
991
  var process6 = __require("node:process");
992
992
  var { Argument: Argument2, humanReadableArgName } = require_argument();
993
993
  var { CommanderError: CommanderError2 } = require_error();
@@ -1920,10 +1920,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1920
1920
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1921
1921
  function findFile(baseDir, baseName) {
1922
1922
  const localBin = path56.resolve(baseDir, baseName);
1923
- if (fs49.existsSync(localBin)) return localBin;
1923
+ if (fs50.existsSync(localBin)) return localBin;
1924
1924
  if (sourceExt.includes(path56.extname(baseName))) return void 0;
1925
1925
  const foundExt = sourceExt.find(
1926
- (ext2) => fs49.existsSync(`${localBin}${ext2}`)
1926
+ (ext2) => fs50.existsSync(`${localBin}${ext2}`)
1927
1927
  );
1928
1928
  if (foundExt) return `${localBin}${foundExt}`;
1929
1929
  return void 0;
@@ -1935,7 +1935,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1935
1935
  if (this._scriptPath) {
1936
1936
  let resolvedScriptPath;
1937
1937
  try {
1938
- resolvedScriptPath = fs49.realpathSync(this._scriptPath);
1938
+ resolvedScriptPath = fs50.realpathSync(this._scriptPath);
1939
1939
  } catch (err3) {
1940
1940
  resolvedScriptPath = this._scriptPath;
1941
1941
  }
@@ -3163,27 +3163,27 @@ var require_filesystem = __commonJS({
3163
3163
  "node_modules/detect-libc/lib/filesystem.js"(exports2, module) {
3164
3164
  "use strict";
3165
3165
  init_define_import_meta_env();
3166
- var fs49 = __require("fs");
3166
+ var fs50 = __require("fs");
3167
3167
  var LDD_PATH = "/usr/bin/ldd";
3168
3168
  var SELF_PATH = "/proc/self/exe";
3169
3169
  var MAX_LENGTH = 2048;
3170
3170
  var readFileSync39 = (path56) => {
3171
- const fd2 = fs49.openSync(path56, "r");
3171
+ const fd2 = fs50.openSync(path56, "r");
3172
3172
  const buffer = Buffer.alloc(MAX_LENGTH);
3173
- const bytesRead = fs49.readSync(fd2, buffer, 0, MAX_LENGTH, 0);
3174
- fs49.close(fd2, () => {
3173
+ const bytesRead = fs50.readSync(fd2, buffer, 0, MAX_LENGTH, 0);
3174
+ fs50.close(fd2, () => {
3175
3175
  });
3176
3176
  return buffer.subarray(0, bytesRead);
3177
3177
  };
3178
3178
  var readFile3 = (path56) => new Promise((resolve20, reject) => {
3179
- fs49.open(path56, "r", (err3, fd2) => {
3179
+ fs50.open(path56, "r", (err3, fd2) => {
3180
3180
  if (err3) {
3181
3181
  reject(err3);
3182
3182
  } else {
3183
3183
  const buffer = Buffer.alloc(MAX_LENGTH);
3184
- fs49.read(fd2, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3184
+ fs50.read(fd2, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3185
3185
  resolve20(buffer.subarray(0, bytesRead));
3186
- fs49.close(fd2, () => {
3186
+ fs50.close(fd2, () => {
3187
3187
  });
3188
3188
  });
3189
3189
  }
@@ -22124,12 +22124,12 @@ var require_dist = __commonJS({
22124
22124
  throw new Error(`Unknown format "${name2}"`);
22125
22125
  return f;
22126
22126
  };
22127
- function addFormats(ajv, list, fs49, exportName) {
22127
+ function addFormats(ajv, list, fs50, exportName) {
22128
22128
  var _a10;
22129
22129
  var _b3;
22130
22130
  (_a10 = (_b3 = ajv.opts.code).formats) !== null && _a10 !== void 0 ? _a10 : _b3.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
22131
22131
  for (const f of list)
22132
- ajv.addFormat(f, fs49[f]);
22132
+ ajv.addFormat(f, fs50[f]);
22133
22133
  }
22134
22134
  module.exports = exports2 = formatsPlugin;
22135
22135
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -22901,8 +22901,8 @@ function blend(fg2, bg, alpha) {
22901
22901
  return Math.round(alpha * fg2 + (1 - alpha) * bg);
22902
22902
  }
22903
22903
  async function node_utils_fetchData(url2) {
22904
- const fs49 = process.getBuiltinModule("fs/promises");
22905
- const data = await fs49.readFile(url2);
22904
+ const fs50 = process.getBuiltinModule("fs/promises");
22905
+ const data = await fs50.readFile(url2);
22906
22906
  return new Uint8Array(data);
22907
22907
  }
22908
22908
  function convertBlackAndWhiteToRGBA({
@@ -23541,11 +23541,11 @@ function network_getArrayBuffer(val) {
23541
23541
  return typeof val !== "string" ? val : stringToBytes(val).buffer;
23542
23542
  }
23543
23543
  function getReadableStream(url2, opts = null) {
23544
- const fs49 = process.getBuiltinModule("fs");
23544
+ const fs50 = process.getBuiltinModule("fs");
23545
23545
  const {
23546
23546
  Readable
23547
23547
  } = process.getBuiltinModule("stream");
23548
- const readStream = fs49.createReadStream(url2, opts);
23548
+ const readStream = fs50.createReadStream(url2, opts);
23549
23549
  return Readable.toWeb(readStream);
23550
23550
  }
23551
23551
  function getNetworkStream(url2) {
@@ -40342,8 +40342,8 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
40342
40342
  url: url2
40343
40343
  } = stream._source;
40344
40344
  this._isStreamingSupported = !disableStream;
40345
- const fs49 = process.getBuiltinModule("fs/promises");
40346
- fs49.lstat(url2).then((stat2) => {
40345
+ const fs50 = process.getBuiltinModule("fs/promises");
40346
+ fs50.lstat(url2).then((stat2) => {
40347
40347
  const readableStream = getReadableStream(url2);
40348
40348
  this._reader = readableStream.getReader();
40349
40349
  const {
@@ -122336,14 +122336,14 @@ var require_emscripten_module_WASM_RELEASE_SYNC = __commonJS({
122336
122336
  });
122337
122337
  var p = Object.assign({}, a), t = "./this.program", u = "object" == typeof window, v = "function" == typeof importScripts, w = "object" == typeof process && "object" == typeof process.versions && "string" == typeof process.versions.node, x = "", y, z2, A;
122338
122338
  if (w) {
122339
- var fs49 = __require("fs"), B = __require("path");
122339
+ var fs50 = __require("fs"), B = __require("path");
122340
122340
  x = v ? B.dirname(x) + "/" : __dirname + "/";
122341
122341
  y = (b, c) => {
122342
122342
  var d = C2(b);
122343
122343
  if (d)
122344
122344
  return c ? d : d.toString();
122345
122345
  b = b.startsWith("file://") ? new URL(b) : B.normalize(b);
122346
- return fs49.readFileSync(b, c ? void 0 : "utf8");
122346
+ return fs50.readFileSync(b, c ? void 0 : "utf8");
122347
122347
  };
122348
122348
  A = (b) => {
122349
122349
  b = y(b, true);
@@ -122354,7 +122354,7 @@ var require_emscripten_module_WASM_RELEASE_SYNC = __commonJS({
122354
122354
  var e = C2(b);
122355
122355
  e && c(e);
122356
122356
  b = b.startsWith("file://") ? new URL(b) : B.normalize(b);
122357
- fs49.readFile(b, function(f, g) {
122357
+ fs50.readFile(b, function(f, g) {
122358
122358
  f ? d(f) : c(g.buffer);
122359
122359
  });
122360
122360
  };
@@ -124016,7 +124016,7 @@ var init_chromium = __esm({
124016
124016
  });
124017
124017
 
124018
124018
  // node_modules/@puppeteer/browsers/lib/esm/browser-data/firefox.js
124019
- import fs30 from "fs";
124019
+ import fs31 from "fs";
124020
124020
  import path38 from "path";
124021
124021
  function getFormat(buildId) {
124022
124022
  const majorVersion = Number(buildId.split(".").shift());
@@ -124147,8 +124147,8 @@ async function resolveBuildId3(channel = FirefoxChannel.NIGHTLY) {
124147
124147
  return channel + "_" + version3;
124148
124148
  }
124149
124149
  async function createProfile(options) {
124150
- if (!fs30.existsSync(options.path)) {
124151
- await fs30.promises.mkdir(options.path, {
124150
+ if (!fs31.existsSync(options.path)) {
124151
+ await fs31.promises.mkdir(options.path, {
124152
124152
  recursive: true
124153
124153
  });
124154
124154
  }
@@ -124320,10 +124320,10 @@ function defaultProfilePreferences(extraPrefs) {
124320
124320
  return Object.assign(defaultPrefs, extraPrefs);
124321
124321
  }
124322
124322
  async function backupFile2(input) {
124323
- if (!fs30.existsSync(input)) {
124323
+ if (!fs31.existsSync(input)) {
124324
124324
  return;
124325
124325
  }
124326
- await fs30.promises.copyFile(input, input + ".puppeteer");
124326
+ await fs31.promises.copyFile(input, input + ".puppeteer");
124327
124327
  }
124328
124328
  async function syncPreferences(options) {
124329
124329
  const prefsPath = path38.join(options.path, "prefs.js");
@@ -124333,7 +124333,7 @@ async function syncPreferences(options) {
124333
124333
  });
124334
124334
  const result = await Promise.allSettled([
124335
124335
  backupFile2(userPath).then(async () => {
124336
- await fs30.promises.writeFile(userPath, lines.join("\n"));
124336
+ await fs31.promises.writeFile(userPath, lines.join("\n"));
124337
124337
  }),
124338
124338
  backupFile2(prefsPath)
124339
124339
  ]);
@@ -124578,7 +124578,7 @@ var init_detectPlatform = __esm({
124578
124578
  });
124579
124579
 
124580
124580
  // node_modules/@puppeteer/browsers/lib/esm/Cache.js
124581
- import fs31 from "fs";
124581
+ import fs32 from "fs";
124582
124582
  import os14 from "os";
124583
124583
  import path39 from "path";
124584
124584
  function parseFolderPath(folderPath) {
@@ -124654,10 +124654,10 @@ var init_Cache = __esm({
124654
124654
  }
124655
124655
  readMetadata(browser) {
124656
124656
  const metatadaPath = this.metadataFile(browser);
124657
- if (!fs31.existsSync(metatadaPath)) {
124657
+ if (!fs32.existsSync(metatadaPath)) {
124658
124658
  return { aliases: {} };
124659
124659
  }
124660
- const data = JSON.parse(fs31.readFileSync(metatadaPath, "utf8"));
124660
+ const data = JSON.parse(fs32.readFileSync(metatadaPath, "utf8"));
124661
124661
  if (typeof data !== "object") {
124662
124662
  throw new Error(".metadata is not an object");
124663
124663
  }
@@ -124665,8 +124665,8 @@ var init_Cache = __esm({
124665
124665
  }
124666
124666
  writeMetadata(browser, metadata) {
124667
124667
  const metatadaPath = this.metadataFile(browser);
124668
- fs31.mkdirSync(path39.dirname(metatadaPath), { recursive: true });
124669
- fs31.writeFileSync(metatadaPath, JSON.stringify(metadata, null, 2));
124668
+ fs32.mkdirSync(path39.dirname(metatadaPath), { recursive: true });
124669
+ fs32.writeFileSync(metatadaPath, JSON.stringify(metadata, null, 2));
124670
124670
  }
124671
124671
  resolveAlias(browser, alias) {
124672
124672
  const metadata = this.readMetadata(browser);
@@ -124679,7 +124679,7 @@ var init_Cache = __esm({
124679
124679
  return path39.join(this.browserRoot(browser), `${platform}-${buildId}`);
124680
124680
  }
124681
124681
  clear() {
124682
- fs31.rmSync(this.#rootDir, {
124682
+ fs32.rmSync(this.#rootDir, {
124683
124683
  force: true,
124684
124684
  recursive: true,
124685
124685
  maxRetries: 10,
@@ -124693,7 +124693,7 @@ var init_Cache = __esm({
124693
124693
  delete metadata.aliases[alias];
124694
124694
  }
124695
124695
  }
124696
- fs31.rmSync(this.installationDir(browser, platform, buildId), {
124696
+ fs32.rmSync(this.installationDir(browser, platform, buildId), {
124697
124697
  force: true,
124698
124698
  recursive: true,
124699
124699
  maxRetries: 10,
@@ -124701,15 +124701,15 @@ var init_Cache = __esm({
124701
124701
  });
124702
124702
  }
124703
124703
  getInstalledBrowsers() {
124704
- if (!fs31.existsSync(this.#rootDir)) {
124704
+ if (!fs32.existsSync(this.#rootDir)) {
124705
124705
  return [];
124706
124706
  }
124707
- const types2 = fs31.readdirSync(this.#rootDir);
124707
+ const types2 = fs32.readdirSync(this.#rootDir);
124708
124708
  const browsers = types2.filter((t) => {
124709
124709
  return Object.values(Browser3).includes(t);
124710
124710
  });
124711
124711
  return browsers.flatMap((browser) => {
124712
- const files = fs31.readdirSync(this.browserRoot(browser));
124712
+ const files = fs32.readdirSync(this.browserRoot(browser));
124713
124713
  return files.map((file2) => {
124714
124714
  const result = parseFolderPath(path39.join(this.browserRoot(browser), file2));
124715
124715
  if (!result) {
@@ -125230,9 +125230,9 @@ var require_pump = __commonJS({
125230
125230
  init_define_import_meta_env();
125231
125231
  var once = require_once();
125232
125232
  var eos = require_end_of_stream();
125233
- var fs49;
125233
+ var fs50;
125234
125234
  try {
125235
- fs49 = __require("fs");
125235
+ fs50 = __require("fs");
125236
125236
  } catch (e) {
125237
125237
  }
125238
125238
  var noop2 = function() {
@@ -125243,8 +125243,8 @@ var require_pump = __commonJS({
125243
125243
  };
125244
125244
  var isFS = function(stream) {
125245
125245
  if (!ancient) return false;
125246
- if (!fs49) return false;
125247
- return (stream instanceof (fs49.ReadStream || noop2) || stream instanceof (fs49.WriteStream || noop2)) && isFn(stream.close);
125246
+ if (!fs50) return false;
125247
+ return (stream instanceof (fs50.ReadStream || noop2) || stream instanceof (fs50.WriteStream || noop2)) && isFn(stream.close);
125248
125248
  };
125249
125249
  var isRequest = function(stream) {
125250
125250
  return stream.setHeader && isFn(stream.abort);
@@ -125460,7 +125460,7 @@ var require_pend = __commonJS({
125460
125460
  var require_fd_slicer = __commonJS({
125461
125461
  "node_modules/fd-slicer/index.js"(exports2) {
125462
125462
  init_define_import_meta_env();
125463
- var fs49 = __require("fs");
125463
+ var fs50 = __require("fs");
125464
125464
  var util2 = __require("util");
125465
125465
  var stream = __require("stream");
125466
125466
  var Readable = stream.Readable;
@@ -125485,7 +125485,7 @@ var require_fd_slicer = __commonJS({
125485
125485
  FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
125486
125486
  var self2 = this;
125487
125487
  self2.pend.go(function(cb) {
125488
- fs49.read(self2.fd, buffer, offset, length, position, function(err3, bytesRead, buffer2) {
125488
+ fs50.read(self2.fd, buffer, offset, length, position, function(err3, bytesRead, buffer2) {
125489
125489
  cb();
125490
125490
  callback(err3, bytesRead, buffer2);
125491
125491
  });
@@ -125494,7 +125494,7 @@ var require_fd_slicer = __commonJS({
125494
125494
  FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
125495
125495
  var self2 = this;
125496
125496
  self2.pend.go(function(cb) {
125497
- fs49.write(self2.fd, buffer, offset, length, position, function(err3, written, buffer2) {
125497
+ fs50.write(self2.fd, buffer, offset, length, position, function(err3, written, buffer2) {
125498
125498
  cb();
125499
125499
  callback(err3, written, buffer2);
125500
125500
  });
@@ -125515,7 +125515,7 @@ var require_fd_slicer = __commonJS({
125515
125515
  if (self2.refCount > 0) return;
125516
125516
  if (self2.refCount < 0) throw new Error("invalid unref");
125517
125517
  if (self2.autoClose) {
125518
- fs49.close(self2.fd, onCloseDone);
125518
+ fs50.close(self2.fd, onCloseDone);
125519
125519
  }
125520
125520
  function onCloseDone(err3) {
125521
125521
  if (err3) {
@@ -125552,7 +125552,7 @@ var require_fd_slicer = __commonJS({
125552
125552
  self2.context.pend.go(function(cb) {
125553
125553
  if (self2.destroyed) return cb();
125554
125554
  var buffer = new Buffer(toRead);
125555
- fs49.read(self2.context.fd, buffer, 0, toRead, self2.pos, function(err3, bytesRead) {
125555
+ fs50.read(self2.context.fd, buffer, 0, toRead, self2.pos, function(err3, bytesRead) {
125556
125556
  if (err3) {
125557
125557
  self2.destroy(err3);
125558
125558
  } else if (bytesRead === 0) {
@@ -125599,7 +125599,7 @@ var require_fd_slicer = __commonJS({
125599
125599
  }
125600
125600
  self2.context.pend.go(function(cb) {
125601
125601
  if (self2.destroyed) return cb();
125602
- fs49.write(self2.context.fd, buffer, 0, buffer.length, self2.pos, function(err4, bytes) {
125602
+ fs50.write(self2.context.fd, buffer, 0, buffer.length, self2.pos, function(err4, bytes) {
125603
125603
  if (err4) {
125604
125604
  self2.destroy();
125605
125605
  cb();
@@ -126028,7 +126028,7 @@ var require_buffer_crc32 = __commonJS({
126028
126028
  var require_yauzl = __commonJS({
126029
126029
  "node_modules/yauzl/index.js"(exports2) {
126030
126030
  init_define_import_meta_env();
126031
- var fs49 = __require("fs");
126031
+ var fs50 = __require("fs");
126032
126032
  var zlib2 = __require("zlib");
126033
126033
  var fd_slicer = require_fd_slicer();
126034
126034
  var crc32 = require_buffer_crc32();
@@ -126058,10 +126058,10 @@ var require_yauzl = __commonJS({
126058
126058
  if (options.validateEntrySizes == null) options.validateEntrySizes = true;
126059
126059
  if (options.strictFileNames == null) options.strictFileNames = false;
126060
126060
  if (callback == null) callback = defaultCallback;
126061
- fs49.open(path56, "r", function(err3, fd2) {
126061
+ fs50.open(path56, "r", function(err3, fd2) {
126062
126062
  if (err3) return callback(err3);
126063
126063
  fromFd(fd2, options, function(err4, zipfile) {
126064
- if (err4) fs49.close(fd2, defaultCallback);
126064
+ if (err4) fs50.close(fd2, defaultCallback);
126065
126065
  callback(err4, zipfile);
126066
126066
  });
126067
126067
  });
@@ -126078,7 +126078,7 @@ var require_yauzl = __commonJS({
126078
126078
  if (options.validateEntrySizes == null) options.validateEntrySizes = true;
126079
126079
  if (options.strictFileNames == null) options.strictFileNames = false;
126080
126080
  if (callback == null) callback = defaultCallback;
126081
- fs49.fstat(fd2, function(err3, stats) {
126081
+ fs50.fstat(fd2, function(err3, stats) {
126082
126082
  if (err3) return callback(err3);
126083
126083
  var reader = fd_slicer.createFromFd(fd2, { autoClose: true });
126084
126084
  fromRandomAccessReader(reader, stats.size, options, callback);
@@ -126659,7 +126659,7 @@ var require_extract_zip = __commonJS({
126659
126659
  "node_modules/extract-zip/index.js"(exports2, module) {
126660
126660
  init_define_import_meta_env();
126661
126661
  var debug5 = require_src()("extract-zip");
126662
- var { createWriteStream, promises: fs49 } = __require("fs");
126662
+ var { createWriteStream, promises: fs50 } = __require("fs");
126663
126663
  var getStream = require_get_stream();
126664
126664
  var path56 = __require("path");
126665
126665
  var { promisify: promisify2 } = __require("util");
@@ -126700,8 +126700,8 @@ var require_extract_zip = __commonJS({
126700
126700
  }
126701
126701
  const destDir = path56.dirname(path56.join(this.opts.dir, entry.fileName));
126702
126702
  try {
126703
- await fs49.mkdir(destDir, { recursive: true });
126704
- const canonicalDestDir = await fs49.realpath(destDir);
126703
+ await fs50.mkdir(destDir, { recursive: true });
126704
+ const canonicalDestDir = await fs50.realpath(destDir);
126705
126705
  const relativeDestDir = path56.relative(this.opts.dir, canonicalDestDir);
126706
126706
  if (relativeDestDir.split(path56.sep).includes("..")) {
126707
126707
  throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);
@@ -126745,14 +126745,14 @@ var require_extract_zip = __commonJS({
126745
126745
  mkdirOptions.mode = procMode;
126746
126746
  }
126747
126747
  debug5("mkdir", { dir: destDir, ...mkdirOptions });
126748
- await fs49.mkdir(destDir, mkdirOptions);
126748
+ await fs50.mkdir(destDir, mkdirOptions);
126749
126749
  if (isDir) return;
126750
126750
  debug5("opening read stream", dest);
126751
126751
  const readStream = await promisify2(this.zipfile.openReadStream.bind(this.zipfile))(entry);
126752
126752
  if (symlink) {
126753
126753
  const link = await getStream(readStream);
126754
126754
  debug5("creating symlink", link, dest);
126755
- await fs49.symlink(link, dest);
126755
+ await fs50.symlink(link, dest);
126756
126756
  } else {
126757
126757
  await pipeline(readStream, createWriteStream(dest, { mode: procMode }));
126758
126758
  }
@@ -126784,8 +126784,8 @@ var require_extract_zip = __commonJS({
126784
126784
  if (!path56.isAbsolute(opts.dir)) {
126785
126785
  throw new Error("Target directory is expected to be absolute");
126786
126786
  }
126787
- await fs49.mkdir(opts.dir, { recursive: true });
126788
- opts.dir = await fs49.realpath(opts.dir);
126787
+ await fs50.mkdir(opts.dir, { recursive: true });
126788
+ opts.dir = await fs50.realpath(opts.dir);
126789
126789
  return new Extractor(zipPath, opts).extract();
126790
126790
  };
126791
126791
  }
@@ -129233,13 +129233,13 @@ var require_tar_fs = __commonJS({
129233
129233
  init_define_import_meta_env();
129234
129234
  var tar2 = require_tar_stream();
129235
129235
  var pump = require_pump();
129236
- var fs49 = __require("fs");
129236
+ var fs50 = __require("fs");
129237
129237
  var path56 = __require("path");
129238
129238
  var win323 = (global.Bare ? global.Bare.platform : process.platform) === "win32";
129239
129239
  exports2.pack = function pack(cwd, opts) {
129240
129240
  if (!cwd) cwd = ".";
129241
129241
  if (!opts) opts = {};
129242
- const xfs = opts.fs || fs49;
129242
+ const xfs = opts.fs || fs50;
129243
129243
  const ignore = opts.ignore || opts.filter || noop2;
129244
129244
  const mapStream = opts.mapStream || echo;
129245
129245
  const statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort);
@@ -129327,7 +129327,7 @@ var require_tar_fs = __commonJS({
129327
129327
  if (!cwd) cwd = ".";
129328
129328
  if (!opts) opts = {};
129329
129329
  cwd = path56.resolve(cwd);
129330
- const xfs = opts.fs || fs49;
129330
+ const xfs = opts.fs || fs50;
129331
129331
  const ignore = opts.ignore || opts.filter || noop2;
129332
129332
  const mapStream = opts.mapStream || echo;
129333
129333
  const own = opts.chown !== false && !win323 && processGetuid() === 0;
@@ -129497,20 +129497,20 @@ var require_tar_fs = __commonJS({
129497
129497
  });
129498
129498
  }
129499
129499
  };
129500
- function validateNotSymlink(fs50, name2, root, cb) {
129500
+ function validateNotSymlink(fs51, name2, root, cb) {
129501
129501
  if (name2 === root) return cb(null, true);
129502
129502
  if (!name2.startsWith(root + path56.sep)) return cb(null, false);
129503
- fs50.lstat(name2, function(err3, st) {
129503
+ fs51.lstat(name2, function(err3, st) {
129504
129504
  if (err3 && err3.code !== "ENOENT" && err3.code !== "EPERM") return cb(err3);
129505
- if (err3 || !st.isSymbolicLink()) return validateNotSymlink(fs50, path56.join(name2, ".."), root, cb);
129505
+ if (err3 || !st.isSymbolicLink()) return validateNotSymlink(fs51, path56.join(name2, ".."), root, cb);
129506
129506
  cb(null, false);
129507
129507
  });
129508
129508
  }
129509
- function validate2(fs50, name2, root, cb) {
129509
+ function validate2(fs51, name2, root, cb) {
129510
129510
  if (name2 === root) return cb(null, true);
129511
- fs50.lstat(name2, function(err3, st) {
129511
+ fs51.lstat(name2, function(err3, st) {
129512
129512
  if (err3 && err3.code !== "ENOENT" && err3.code !== "EPERM") return cb(err3);
129513
- if (err3 || st.isDirectory()) return validate2(fs50, path56.join(name2, ".."), root, cb);
129513
+ if (err3 || st.isDirectory()) return validate2(fs51, path56.join(name2, ".."), root, cb);
129514
129514
  cb(null, false);
129515
129515
  });
129516
129516
  }
@@ -129525,7 +129525,7 @@ var require_tar_fs = __commonJS({
129525
129525
  function normalize3(name2) {
129526
129526
  return win323 ? name2.replace(/\\/g, "/").replace(/[:?<>|]/g, "_") : name2;
129527
129527
  }
129528
- function statAll(fs50, stat2, cwd, ignore, entries, sort) {
129528
+ function statAll(fs51, stat2, cwd, ignore, entries, sort) {
129529
129529
  if (!entries) entries = ["."];
129530
129530
  const queue = entries.slice(0);
129531
129531
  const root = path56.resolve(cwd);
@@ -129534,10 +129534,10 @@ var require_tar_fs = __commonJS({
129534
129534
  const next = queue.shift();
129535
129535
  const nextAbs = path56.join(cwd, next);
129536
129536
  if (!inside(root, path56.resolve(cwd, next))) return callback(new Error(next + " is not a valid path"));
129537
- stat2.call(fs50, nextAbs, function(err3, stat3) {
129537
+ stat2.call(fs51, nextAbs, function(err3, stat3) {
129538
129538
  if (err3) return callback(entries.indexOf(next) === -1 && err3.code === "ENOENT" ? null : err3);
129539
129539
  if (!stat3.isDirectory()) return callback(null, next, stat3);
129540
- fs50.readdir(nextAbs, function(err4, files) {
129540
+ fs51.readdir(nextAbs, function(err4, files) {
129541
129541
  if (err4) return callback(err4);
129542
129542
  if (sort) files.sort();
129543
129543
  for (let i = 0; i < files.length; i++) {
@@ -130752,7 +130752,7 @@ var init_cliui = __esm({
130752
130752
 
130753
130753
  // node_modules/escalade/sync/index.mjs
130754
130754
  import { dirname as dirname18, resolve as resolve11 } from "path";
130755
- import { readdirSync as readdirSync8, statSync as statSync19 } from "fs";
130755
+ import { readdirSync as readdirSync9, statSync as statSync19 } from "fs";
130756
130756
  function sync_default(start, callback) {
130757
130757
  let dir = resolve11(".", start);
130758
130758
  let tmp, stats = statSync19(dir);
@@ -130760,7 +130760,7 @@ function sync_default(start, callback) {
130760
130760
  dir = dirname18(dir);
130761
130761
  }
130762
130762
  while (true) {
130763
- tmp = callback(dir, readdirSync8(dir));
130763
+ tmp = callback(dir, readdirSync9(dir));
130764
130764
  if (tmp) return resolve11(dir, tmp);
130765
130765
  dir = dirname18(tmp = dir);
130766
130766
  if (tmp === dir) break;
@@ -135853,9 +135853,9 @@ For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides
135853
135853
  });
135854
135854
 
135855
135855
  // node_modules/puppeteer-core/lib/esm/puppeteer/node/util/fs.js
135856
- import fs32 from "fs";
135856
+ import fs33 from "fs";
135857
135857
  async function rm(path56) {
135858
- await fs32.promises.rm(path56, rmOptions);
135858
+ await fs33.promises.rm(path56, rmOptions);
135859
135859
  }
135860
135860
  var rmOptions;
135861
135861
  var init_fs = __esm({
@@ -136096,7 +136096,7 @@ var init_ChromeLauncher = __esm({
136096
136096
  });
136097
136097
 
136098
136098
  // node_modules/puppeteer-core/lib/esm/puppeteer/node/FirefoxLauncher.js
136099
- import fs33 from "fs";
136099
+ import fs34 from "fs";
136100
136100
  import { rename, unlink, mkdtemp as mkdtemp2 } from "fs/promises";
136101
136101
  import os18 from "os";
136102
136102
  import path41 from "path";
@@ -136212,7 +136212,7 @@ var init_FirefoxLauncher = __esm({
136212
136212
  const backupFiles = ["prefs.js", "user.js"];
136213
136213
  const results = await Promise.allSettled(backupFiles.map(async (file2) => {
136214
136214
  const prefsBackupPath = path41.join(userDataDir, file2 + backupSuffix);
136215
- if (fs33.existsSync(prefsBackupPath)) {
136215
+ if (fs34.existsSync(prefsBackupPath)) {
136216
136216
  const prefsPath = path41.join(userDataDir, file2);
136217
136217
  await unlink(prefsPath);
136218
136218
  await rename(prefsBackupPath, prefsPath);
@@ -136954,7 +136954,7 @@ __export(puppeteer_core_exports, {
136954
136954
  valueFromRemoteObject: () => valueFromRemoteObject,
136955
136955
  withSourcePuppeteerURLIfNone: () => withSourcePuppeteerURLIfNone
136956
136956
  });
136957
- import fs34 from "fs";
136957
+ import fs35 from "fs";
136958
136958
  import path42 from "path";
136959
136959
  var puppeteer, connect, defaultArgs, executablePath, launch2, puppeteer_core_default;
136960
136960
  var init_puppeteer_core = __esm({
@@ -136964,7 +136964,7 @@ var init_puppeteer_core = __esm({
136964
136964
  init_environment();
136965
136965
  init_puppeteer();
136966
136966
  environment.value = {
136967
- fs: fs34,
136967
+ fs: fs35,
136968
136968
  path: path42,
136969
136969
  ScreenRecorder
136970
136970
  };
@@ -142132,9 +142132,9 @@ var require_xlsx = __commonJS({
142132
142132
  }
142133
142133
  return o;
142134
142134
  }
142135
- var fs49;
142135
+ var fs50;
142136
142136
  function get_fs() {
142137
- return fs49 || (fs49 = __require("fs"));
142137
+ return fs50 || (fs50 = __require("fs"));
142138
142138
  }
142139
142139
  function parse6(file2, options) {
142140
142140
  if (file2[0] == 80 && file2[1] == 75) return parse_zip2(file2, options);
@@ -142410,7 +142410,7 @@ var require_xlsx = __commonJS({
142410
142410
  }
142411
142411
  function read_file(filename2, options) {
142412
142412
  get_fs();
142413
- return parse6(fs49.readFileSync(filename2), options);
142413
+ return parse6(fs50.readFileSync(filename2), options);
142414
142414
  }
142415
142415
  function read(blob, options) {
142416
142416
  var type = options && options.type;
@@ -142736,7 +142736,7 @@ var require_xlsx = __commonJS({
142736
142736
  function write_file(cfb, filename2, options) {
142737
142737
  get_fs();
142738
142738
  var o = _write(cfb, options);
142739
- fs49.writeFileSync(filename2, o);
142739
+ fs50.writeFileSync(filename2, o);
142740
142740
  }
142741
142741
  function a2s2(o) {
142742
142742
  var out2 = new Array(o.length);
@@ -142748,7 +142748,7 @@ var require_xlsx = __commonJS({
142748
142748
  switch (options && options.type || "buffer") {
142749
142749
  case "file":
142750
142750
  get_fs();
142751
- fs49.writeFileSync(options.filename, o);
142751
+ fs50.writeFileSync(options.filename, o);
142752
142752
  return o;
142753
142753
  case "binary":
142754
142754
  return typeof o == "string" ? o : a2s2(o);
@@ -169738,7 +169738,7 @@ var require_xlsx = __commonJS({
169738
169738
  return out2;
169739
169739
  }
169740
169740
  var qreg = /"/g;
169741
- function make_csv_row(sheet, r, R, cols, fs49, rs, FS, o) {
169741
+ function make_csv_row(sheet, r, R, cols, fs50, rs, FS, o) {
169742
169742
  var isempty = true;
169743
169743
  var row = [], txt = "", rr = encode_row(R);
169744
169744
  for (var C2 = r.s.c; C2 <= r.e.c; ++C2) {
@@ -169748,7 +169748,7 @@ var require_xlsx = __commonJS({
169748
169748
  else if (val.v != null) {
169749
169749
  isempty = false;
169750
169750
  txt = "" + (o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
169751
- for (var i = 0, cc = 0; i !== txt.length; ++i) if ((cc = txt.charCodeAt(i)) === fs49 || cc === rs || cc === 34 || o.forceQuotes) {
169751
+ for (var i = 0, cc = 0; i !== txt.length; ++i) if ((cc = txt.charCodeAt(i)) === fs50 || cc === rs || cc === 34 || o.forceQuotes) {
169752
169752
  txt = '"' + txt.replace(qreg, '""') + '"';
169753
169753
  break;
169754
169754
  }
@@ -169768,7 +169768,7 @@ var require_xlsx = __commonJS({
169768
169768
  var o = opts == null ? {} : opts;
169769
169769
  if (sheet == null || sheet["!ref"] == null) return "";
169770
169770
  var r = safe_decode_range(sheet["!ref"]);
169771
- var FS = o.FS !== void 0 ? o.FS : ",", fs49 = FS.charCodeAt(0);
169771
+ var FS = o.FS !== void 0 ? o.FS : ",", fs50 = FS.charCodeAt(0);
169772
169772
  var RS = o.RS !== void 0 ? o.RS : "\n", rs = RS.charCodeAt(0);
169773
169773
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
169774
169774
  var row = "", cols = [];
@@ -169779,7 +169779,7 @@ var require_xlsx = __commonJS({
169779
169779
  var w = 0;
169780
169780
  for (var R = r.s.r; R <= r.e.r; ++R) {
169781
169781
  if ((rowinfo[R] || {}).hidden) continue;
169782
- row = make_csv_row(sheet, r, R, cols, fs49, rs, FS, o);
169782
+ row = make_csv_row(sheet, r, R, cols, fs50, rs, FS, o);
169783
169783
  if (row == null) {
169784
169784
  continue;
169785
169785
  }
@@ -170051,7 +170051,7 @@ var require_xlsx = __commonJS({
170051
170051
  return stream;
170052
170052
  }
170053
170053
  var r = safe_decode_range(sheet["!ref"]);
170054
- var FS = o.FS !== void 0 ? o.FS : ",", fs49 = FS.charCodeAt(0);
170054
+ var FS = o.FS !== void 0 ? o.FS : ",", fs50 = FS.charCodeAt(0);
170055
170055
  var RS = o.RS !== void 0 ? o.RS : "\n", rs = RS.charCodeAt(0);
170056
170056
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
170057
170057
  var row = "", cols = [];
@@ -170069,7 +170069,7 @@ var require_xlsx = __commonJS({
170069
170069
  while (R <= r.e.r) {
170070
170070
  ++R;
170071
170071
  if ((rowinfo[R - 1] || {}).hidden) continue;
170072
- row = make_csv_row(sheet, r, R - 1, cols, fs49, rs, FS, o);
170072
+ row = make_csv_row(sheet, r, R - 1, cols, fs50, rs, FS, o);
170073
170073
  if (row != null) {
170074
170074
  if (o.strip) row = row.replace(endregex, "");
170075
170075
  if (row || o.blankrows !== false) return stream.push((w++ ? RS : "") + row);
@@ -178679,13 +178679,13 @@ var {
178679
178679
  } = import_index.default;
178680
178680
 
178681
178681
  // src/cli.ts
178682
- import * as fs48 from "fs";
178682
+ import * as fs49 from "fs";
178683
178683
  import * as path55 from "path";
178684
178684
  import { homedir as homedir15 } from "os";
178685
178685
 
178686
178686
  // src/baseline.ts
178687
178687
  init_define_import_meta_env();
178688
- import * as fs3 from "node:fs";
178688
+ import * as fs4 from "node:fs";
178689
178689
  import * as path6 from "node:path";
178690
178690
 
178691
178691
  // src/constants.ts
@@ -178698,7 +178698,7 @@ init_define_import_meta_env();
178698
178698
  import { createRequire } from "node:module";
178699
178699
  function resolveVersion() {
178700
178700
  if (true) {
178701
- return "2.6.10";
178701
+ return "2.6.12";
178702
178702
  }
178703
178703
  const require3 = createRequire(import.meta.url);
178704
178704
  const pkg = require3("../package.json");
@@ -178778,7 +178778,7 @@ var ENV_KEYS = {
178778
178778
 
178779
178779
  // src/config.ts
178780
178780
  init_define_import_meta_env();
178781
- import * as fs from "node:fs";
178781
+ import * as fs2 from "node:fs";
178782
178782
 
178783
178783
  // node_modules/smol-toml/dist/index.js
178784
178784
  init_define_import_meta_env();
@@ -179659,9 +179659,28 @@ import * as path3 from "node:path";
179659
179659
 
179660
179660
  // src/paths.ts
179661
179661
  init_define_import_meta_env();
179662
+ import * as fs from "node:fs";
179662
179663
  import * as path2 from "node:path";
179663
179664
  var WSL_PATH_RE = /^\/mnt\/([a-zA-Z])\/(.*)$/s;
179664
179665
  var UNC_HOST_SHARE_RE = /^\/\/([^/]+)\/([^/]+)/;
179666
+ var SHORT_NAME_RE = /~\d/;
179667
+ function expandShortPath(p) {
179668
+ if (process.platform !== "win32") return p;
179669
+ const segments = p.split("/");
179670
+ let lastShortIdx = -1;
179671
+ for (let i = 0; i < segments.length; i++) {
179672
+ if (SHORT_NAME_RE.test(segments[i])) lastShortIdx = i;
179673
+ }
179674
+ if (lastShortIdx === -1) return p;
179675
+ const prefix = segments.slice(0, lastShortIdx + 1).join("/");
179676
+ const suffix = segments.slice(lastShortIdx + 1).join("/");
179677
+ try {
179678
+ const expandedPrefix = fs.realpathSync.native(prefix).replace(/\\/g, "/");
179679
+ return suffix ? `${expandedPrefix}/${suffix}` : expandedPrefix;
179680
+ } catch {
179681
+ return p;
179682
+ }
179683
+ }
179665
179684
  function lowercaseDriveLetter(s) {
179666
179685
  if (s.length >= 2 && s[1] === ":") {
179667
179686
  const c = s[0];
@@ -179694,6 +179713,7 @@ function normalizePath(p) {
179694
179713
  const g = /^\/([a-zA-Z])(\/.*)?$/.exec(s);
179695
179714
  if (g) s = `${g[1].toLowerCase()}:${g[2] ?? "/"}`;
179696
179715
  }
179716
+ s = expandShortPath(s);
179697
179717
  s = lowercaseDriveLetter(s);
179698
179718
  return s;
179699
179719
  }
@@ -180197,7 +180217,7 @@ function loadConfig() {
180197
180217
  const p = configPath();
180198
180218
  let currentMtime = 0;
180199
180219
  try {
180200
- currentMtime = fs.statSync(p).mtimeMs;
180220
+ currentMtime = fs2.statSync(p).mtimeMs;
180201
180221
  } catch {
180202
180222
  }
180203
180223
  const envFp = configEnvFingerprint();
@@ -180207,7 +180227,7 @@ function loadConfig() {
180207
180227
  let raw = {};
180208
180228
  if (currentMtime !== 0) {
180209
180229
  try {
180210
- const text = fs.readFileSync(p, "utf8");
180230
+ const text = fs2.readFileSync(p, "utf8");
180211
180231
  raw = parse(text);
180212
180232
  } catch {
180213
180233
  }
@@ -180242,7 +180262,7 @@ function loadPersistedConfig() {
180242
180262
  const p = configPath();
180243
180263
  let raw = {};
180244
180264
  try {
180245
- const text = fs.readFileSync(p, "utf8");
180265
+ const text = fs2.readFileSync(p, "utf8");
180246
180266
  raw = parse(text);
180247
180267
  } catch {
180248
180268
  }
@@ -180668,7 +180688,7 @@ function saveConfig(config3) {
180668
180688
 
180669
180689
  // src/db.ts
180670
180690
  init_define_import_meta_env();
180671
- import * as fs2 from "node:fs";
180691
+ import * as fs3 from "node:fs";
180672
180692
  import { createRequire as createRequire2 } from "node:module";
180673
180693
  import * as path4 from "node:path";
180674
180694
  import Database from "better-sqlite3";
@@ -180689,8 +180709,21 @@ CREATE TABLE IF NOT EXISTS files (
180689
180709
  sha TEXT,
180690
180710
  mtime REAL,
180691
180711
  language TEXT,
180692
- indexed_at REAL
180712
+ indexed_at REAL,
180713
+ embed_sha TEXT,
180714
+ retry_count INTEGER NOT NULL DEFAULT 0
180693
180715
  );
180716
+ -- Expression index on TG_LOWER(path) -- see pathEqClause (sql_path.ts) and TG_LOWER's
180717
+ -- registration above. TG_LOWER is registered { deterministic: true }, which is required for
180718
+ -- SQLite to index an expression at all; without it CREATE INDEX on a function call throws
180719
+ -- "non-deterministic functions prohibited in index expressions". Because pathEqClause emits
180720
+ -- this exact 'TG_LOWER(path) = ?' text for every case-insensitive-filesystem query, the planner
180721
+ -- matches it against this index and uses SEARCH instead of a full table SCAN, without requiring
180722
+ -- any writer to populate a separate folded column (verified via EXPLAIN QUERY PLAN in
180723
+ -- db.test.ts / sql_path.test.ts). CREATE INDEX IF NOT EXISTS is purely additive and safe to run
180724
+ -- against an already-populated table on every connection open, unlike an ALTER TABLE column add
180725
+ -- -- no MIGRATIONS entry or SCHEMA_VERSION bump is needed for this index.
180726
+ CREATE INDEX IF NOT EXISTS idx_files_path_folded ON files(TG_LOWER(path));
180694
180727
 
180695
180728
  CREATE TABLE IF NOT EXISTS symbols (
180696
180729
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -180705,6 +180738,7 @@ CREATE TABLE IF NOT EXISTS symbols (
180705
180738
  CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
180706
180739
  CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_path);
180707
180740
  CREATE INDEX IF NOT EXISTS idx_symbols_name_kind ON symbols(name, kind);
180741
+ CREATE INDEX IF NOT EXISTS idx_symbols_file_folded ON symbols(TG_LOWER(file_path));
180708
180742
 
180709
180743
  CREATE TABLE IF NOT EXISTS refs (
180710
180744
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -180716,6 +180750,7 @@ CREATE TABLE IF NOT EXISTS refs (
180716
180750
  );
180717
180751
  CREATE INDEX IF NOT EXISTS idx_refs_name ON refs(name);
180718
180752
  CREATE INDEX IF NOT EXISTS idx_refs_file ON refs(file_path);
180753
+ CREATE INDEX IF NOT EXISTS idx_refs_file_folded ON refs(TG_LOWER(file_path));
180719
180754
 
180720
180755
  CREATE TABLE IF NOT EXISTS chunks (
180721
180756
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -180726,6 +180761,7 @@ CREATE TABLE IF NOT EXISTS chunks (
180726
180761
  kind TEXT
180727
180762
  );
180728
180763
  CREATE INDEX IF NOT EXISTS idx_chunks_file ON chunks(file_path);
180764
+ CREATE INDEX IF NOT EXISTS idx_chunks_file_folded ON chunks(TG_LOWER(file_path));
180729
180765
  `;
180730
180766
  var FTS_SQL = `
180731
180767
  CREATE VIRTUAL TABLE IF NOT EXISTS symbols_fts USING fts5(
@@ -180750,8 +180786,39 @@ CREATE TRIGGER IF NOT EXISTS symbols_au AFTER UPDATE ON symbols BEGIN
180750
180786
  VALUES (new.id, new.name, new.body, new.docstring);
180751
180787
  END;
180752
180788
  `;
180753
- var SCHEMA_VERSION = 1;
180754
- var MIGRATIONS = {};
180789
+ var SCHEMA_VERSION = 3;
180790
+ var MIGRATIONS = {
180791
+ // v1 -> v2: adds files.embed_sha, tracked separately from files.sha so embedding freshness
180792
+ // can be gated independently of parse freshness (see makeIndexer in worker.ts). A pre-existing
180793
+ // v1 database's `files` table predates the column, so it needs an explicit ALTER TABLE here;
180794
+ // a brand-new database already has the column from SCHEMA_SQL's CREATE TABLE above, so the
180795
+ // ALTER TABLE would fail with "duplicate column name" there -- swallow exactly that error and
180796
+ // rethrow anything else, so a genuine ALTER TABLE failure is never silently lost.
180797
+ 1: (conn) => {
180798
+ try {
180799
+ conn.exec("ALTER TABLE files ADD COLUMN embed_sha TEXT");
180800
+ } catch (err3) {
180801
+ if (!(err3 instanceof Error) || !/duplicate column/i.test(err3.message)) throw err3;
180802
+ }
180803
+ },
180804
+ // v2 -> v3: adds files.retry_count, a durable per-path counter for consecutive
180805
+ // transient-read-failure requeues (see MAX_TRANSIENT_RETRIES / requeueDirtyPath /
180806
+ // resetTransientRetryCount in worker.ts). Previously this counter lived only in an
180807
+ // in-memory Map inside worker.ts, which meant resetTransientRetryCount -- called from
180808
+ // appendDirtyPath (hooks_index.ts) in the short-lived hook CLI process -- could never
180809
+ // actually reach the long-lived detached daemon process's own copy of that Map: they are
180810
+ // different Node processes with no shared memory, so the reset was a silent no-op in the
180811
+ // real deployed topology. Persisting the counter in `files` makes it visible to both
180812
+ // processes via the one thing they do share: the index DB. Same swallow-duplicate-column
180813
+ // pattern as v1 -> v2 above.
180814
+ 2: (conn) => {
180815
+ try {
180816
+ conn.exec("ALTER TABLE files ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0");
180817
+ } catch (err3) {
180818
+ if (!(err3 instanceof Error) || !/duplicate column/i.test(err3.message)) throw err3;
180819
+ }
180820
+ }
180821
+ };
180755
180822
  function runMigrations(conn, fromVersion, toVersion) {
180756
180823
  for (let v = fromVersion; v < toVersion; v++) {
180757
180824
  MIGRATIONS[v]?.(conn);
@@ -180806,9 +180873,9 @@ function getDb(dbPath) {
180806
180873
  if (existing !== void 0) return existing;
180807
180874
  const dir = path4.dirname(resolved);
180808
180875
  try {
180809
- fs2.mkdirSync(dir, { recursive: true });
180876
+ fs3.mkdirSync(dir, { recursive: true });
180810
180877
  } catch (e) {
180811
- if (e.code !== "EEXIST" || !fs2.existsSync(dir)) throw e;
180878
+ if (e.code !== "EEXIST" || !fs3.existsSync(dir)) throw e;
180812
180879
  }
180813
180880
  const conn = new Database(resolved);
180814
180881
  try {
@@ -180977,7 +181044,7 @@ function walkProject(rootDir, opts = {}) {
180977
181044
  if (dir === void 0) break;
180978
181045
  let entries;
180979
181046
  try {
180980
- entries = fs3.readdirSync(dir, { withFileTypes: true });
181047
+ entries = fs4.readdirSync(dir, { withFileTypes: true });
180981
181048
  } catch {
180982
181049
  continue;
180983
181050
  }
@@ -181033,7 +181100,7 @@ function buildProjectMap(rootDir = process.cwd(), opts = {}) {
181033
181100
  const recentFiles = files.map((f) => {
181034
181101
  let mtime;
181035
181102
  try {
181036
- mtime = fs3.statSync(f).mtimeMs;
181103
+ mtime = fs4.statSync(f).mtimeMs;
181037
181104
  } catch {
181038
181105
  mtime = 0;
181039
181106
  }
@@ -181742,7 +181809,17 @@ function _renderHeader(stats) {
181742
181809
  }
181743
181810
  return [line];
181744
181811
  }
181745
- function renderStats(stats) {
181812
+ function _renderShortHint() {
181813
+ return [
181814
+ "",
181815
+ `${_M}${fg(...C.TEXT_MUTED)}Run 'token-goat stats --full' for the full breakdown (by source, by command, by day).${RESET}`
181816
+ ];
181817
+ }
181818
+ function renderStats(stats, opts) {
181819
+ if (opts?.short) {
181820
+ const sections2 = [_renderHeader(stats), _renderKpiSection(stats), _renderShortHint(), [""]];
181821
+ return sections2.flatMap((s) => s).join("\n");
181822
+ }
181746
181823
  const sections = [
181747
181824
  _renderHeader(stats),
181748
181825
  _renderKpiSection(stats),
@@ -182023,27 +182100,7 @@ function _plainTextStats(summary) {
182023
182100
  }
182024
182101
  console.log(lines.join("\n"));
182025
182102
  }
182026
- function renderShortStats(opts) {
182027
- const windowDays = opts?.windowDays ?? 30;
182028
- const summary = summarize(windowDays, void 0, opts?.homeDir);
182029
- if (summary.total_events === 0) {
182030
- console.log("No stats recorded yet.");
182031
- return;
182032
- }
182033
- _renderShortTotals(summary);
182034
- }
182035
- function renderStats2(opts) {
182036
- const windowDays = opts?.windowDays ?? 30;
182037
- const summary = summarize(windowDays, void 0, opts?.homeDir);
182038
- if (summary.total_events === 0) {
182039
- console.log("No stats recorded yet.");
182040
- return;
182041
- }
182042
- const useTty = process.stdout.isTTY === true && !process.env["NO_COLOR"];
182043
- if (!useTty) {
182044
- _plainTextStats(summary);
182045
- return;
182046
- }
182103
+ function _buildStatsData(summary, windowDays) {
182047
182104
  const now = /* @__PURE__ */ new Date();
182048
182105
  const periodStart = windowDays > 0 ? new Date(now.getTime() - windowDays * 24 * 60 * 60 * 1e3) : /* @__PURE__ */ new Date(0);
182049
182106
  const sparkDays = [...summary.by_day].reverse().slice(-30);
@@ -182052,7 +182109,7 @@ function renderStats2(opts) {
182052
182109
  bytes: sparkDays.map((d) => d.bytes_saved),
182053
182110
  tokens: sparkDays.map((d) => d.tokens_saved)
182054
182111
  } : null;
182055
- const statsData = {
182112
+ return {
182056
182113
  period_start: periodStart,
182057
182114
  period_end: now,
182058
182115
  version: VERSION,
@@ -182090,6 +182147,35 @@ function renderStats2(opts) {
182090
182147
  events: c.events
182091
182148
  }))
182092
182149
  };
182150
+ }
182151
+ function renderShortStats(opts) {
182152
+ const windowDays = opts?.windowDays ?? 30;
182153
+ const summary = summarize(windowDays, void 0, opts?.homeDir);
182154
+ if (summary.total_events === 0) {
182155
+ console.log("No stats recorded yet.");
182156
+ return;
182157
+ }
182158
+ const useTty = process.stdout.isTTY === true && !process.env["NO_COLOR"];
182159
+ if (!useTty) {
182160
+ _renderShortTotals(summary);
182161
+ return;
182162
+ }
182163
+ const statsData = _buildStatsData(summary, windowDays);
182164
+ process.stdout.write(renderStats(statsData, { short: true }) + "\n");
182165
+ }
182166
+ function renderStats2(opts) {
182167
+ const windowDays = opts?.windowDays ?? 30;
182168
+ const summary = summarize(windowDays, void 0, opts?.homeDir);
182169
+ if (summary.total_events === 0) {
182170
+ console.log("No stats recorded yet.");
182171
+ return;
182172
+ }
182173
+ const useTty = process.stdout.isTTY === true && !process.env["NO_COLOR"];
182174
+ if (!useTty) {
182175
+ _plainTextStats(summary);
182176
+ return;
182177
+ }
182178
+ const statsData = _buildStatsData(summary, windowDays);
182093
182179
  process.stdout.write(renderStats(statsData) + "\n");
182094
182180
  }
182095
182181
 
@@ -182176,14 +182262,17 @@ function queryRefCounts(names, dbPath = globalDbPath()) {
182176
182262
  }
182177
182263
  function getFileEntry(filePath, dbPath = globalDbPath()) {
182178
182264
  const db = getDb(dbPath);
182179
- const row = db.prepare(`SELECT path, sha, mtime, language, indexed_at FROM files WHERE ${pathEqClause("path")}`).get(foldPath(filePath));
182265
+ const row = db.prepare(
182266
+ `SELECT path, sha, mtime, language, indexed_at, embed_sha FROM files WHERE ${pathEqClause("path")}`
182267
+ ).get(foldPath(filePath));
182180
182268
  if (row === void 0) return null;
182181
182269
  return {
182182
182270
  filePath: row.path,
182183
182271
  sha: row.sha ?? "",
182184
182272
  mtime: row.mtime ?? 0,
182185
182273
  language: row.language ?? "unknown",
182186
- indexedAt: row.indexed_at ?? 0
182274
+ indexedAt: row.indexed_at ?? 0,
182275
+ embedSha: row.embed_sha ?? ""
182187
182276
  };
182188
182277
  }
182189
182278
  function sanitizeFtsQuery(query) {
@@ -182204,7 +182293,7 @@ function searchSymbolsFts(query, limit = 50, dbPath = globalDbPath()) {
182204
182293
 
182205
182294
  // src/compact.ts
182206
182295
  init_define_import_meta_env();
182207
- import * as fs10 from "node:fs";
182296
+ import * as fs11 from "node:fs";
182208
182297
  import * as path13 from "node:path";
182209
182298
 
182210
182299
  // src/bridges/index.ts
@@ -182233,7 +182322,7 @@ function detectHarness() {
182233
182322
  if (env2["HERMES_SESSION_ID"] || env2["HERMES_HOME"]) {
182234
182323
  return "hermes";
182235
182324
  }
182236
- if (env2["TERM_PROGRAM"] === "claude-code" || env2["CLAUDE_CODE_VERSION"] !== void 0 || env2["CLAUDE_CODE_SESSION_ID"] || env2["ANTHROPIC_API_KEY"]) {
182325
+ if (env2["TERM_PROGRAM"] === "claude-code" || env2["CLAUDE_CODE_VERSION"] !== void 0 || env2["CLAUDE_CODE_SESSION_ID"]) {
182237
182326
  return "claudecode";
182238
182327
  }
182239
182328
  if (env2["CODEX_SESSION_ID"] !== void 0 || env2["CODEX_SESSION"]) {
@@ -182248,6 +182337,9 @@ function detectHarness() {
182248
182337
  if (env2["OPENCLAW_SESSION_ID"] !== void 0) {
182249
182338
  return "openclaw";
182250
182339
  }
182340
+ if (env2["ANTHROPIC_API_KEY"]) {
182341
+ return "claudecode";
182342
+ }
182251
182343
  if (env2["OPENAI_API_KEY"] && !env2["ANTHROPIC_API_KEY"]) {
182252
182344
  return "codex";
182253
182345
  }
@@ -182368,13 +182460,13 @@ main()
182368
182460
 
182369
182461
  // src/bridges/codex_install.ts
182370
182462
  init_define_import_meta_env();
182371
- import * as fs5 from "node:fs";
182463
+ import * as fs6 from "node:fs";
182372
182464
  import * as os3 from "node:os";
182373
182465
  import * as path9 from "node:path";
182374
182466
 
182375
182467
  // src/install.ts
182376
182468
  init_define_import_meta_env();
182377
- import * as fs4 from "node:fs";
182469
+ import * as fs5 from "node:fs";
182378
182470
  import * as os2 from "node:os";
182379
182471
  import * as path8 from "node:path";
182380
182472
  var HOOK_EVENT_MAP = [
@@ -182410,7 +182502,7 @@ var SettingsParseError = class extends Error {
182410
182502
  function readSettings(p, opts = {}) {
182411
182503
  let raw;
182412
182504
  try {
182413
- raw = fs4.readFileSync(p, "utf8");
182505
+ raw = fs5.readFileSync(p, "utf8");
182414
182506
  } catch {
182415
182507
  return {};
182416
182508
  }
@@ -182540,6 +182632,12 @@ function buildClaudeMdBlock() {
182540
182632
  '- `token-goat section "file::Heading"` -- one doc or config section',
182541
182633
  '- `token-goat semantic "description"` -- find code by meaning',
182542
182634
  "- `token-goat outline file` / `token-goat skeleton file` -- signatures without bodies",
182635
+ "- `token-goat map --compact` -- project overview (low-token summary)",
182636
+ "- `token-goat refs file::symbol --callers` -- find callers of a symbol",
182637
+ "- `token-goat changed --symbol` -- symbols changed since a git ref",
182638
+ "- `token-goat config-get file KEY` -- read one config value",
182639
+ "- `token-goat bash-output` / `token-goat web-output` -- re-inspect cached output by ID",
182640
+ "- `token-goat gdrive-sections <file-id>` -- outline a Google Doc by ID",
182543
182641
  "",
182544
182642
  "Use this before a full-file `Read` or wide `Grep`, and before opening a large image",
182545
182643
  "(token-goat hooks shrink oversized images automatically). token-goat commands return",
@@ -182551,7 +182649,7 @@ function writeClaudeMdBlock(p) {
182551
182649
  const block = buildClaudeMdBlock();
182552
182650
  let existing;
182553
182651
  try {
182554
- existing = fs4.readFileSync(p, "utf8");
182652
+ existing = fs5.readFileSync(p, "utf8");
182555
182653
  } catch {
182556
182654
  existing = "";
182557
182655
  }
@@ -182579,7 +182677,7 @@ ${block}
182579
182677
  function stripClaudeMdBlock(p) {
182580
182678
  let existing;
182581
182679
  try {
182582
- existing = fs4.readFileSync(p, "utf8");
182680
+ existing = fs5.readFileSync(p, "utf8");
182583
182681
  } catch {
182584
182682
  return false;
182585
182683
  }
@@ -182612,7 +182710,7 @@ function uninstallClaudeMd() {
182612
182710
  }
182613
182711
  var SKILL_MD_CONTENT = `---
182614
182712
  name: token-goat
182615
- description: Use before reading whole files or grepping wide. token-goat commands (symbol, read, section, semantic, outline, skeleton) return narrow slices of code and docs at a fraction of the token cost.
182713
+ description: Use before reading whole files or grepping wide. token-goat commands (symbol, read, section, semantic, outline, skeleton, map, refs, changed, config-get, bash-output, web-output, gdrive-sections) return narrow slices of code and docs at a fraction of the token cost.
182616
182714
  ---
182617
182715
 
182618
182716
  # token-goat
@@ -182623,6 +182721,12 @@ Prefer token-goat commands over reading whole files:
182623
182721
  - \`token-goat section "file::Heading"\` -- one doc or config section
182624
182722
  - \`token-goat semantic "description"\` -- find code by meaning
182625
182723
  - \`token-goat outline file\` / \`token-goat skeleton file\` -- signatures without bodies
182724
+ - \`token-goat map --compact\` -- project overview (low-token summary)
182725
+ - \`token-goat refs file::symbol --callers\` -- find callers of a symbol
182726
+ - \`token-goat changed --symbol\` -- symbols changed since a git ref
182727
+ - \`token-goat config-get file KEY\` -- read one config value
182728
+ - \`token-goat bash-output\` / \`token-goat web-output\` -- re-inspect cached output by ID
182729
+ - \`token-goat gdrive-sections <file-id>\` -- outline a Google Doc by ID
182626
182730
 
182627
182731
  Read is the right call when the file is under about 200 lines, was never indexed (new or
182628
182732
  untracked), or is an image (token-goat's hooks shrink oversized images automatically).
@@ -182640,7 +182744,7 @@ function installSkill() {
182640
182744
  const p = skillPath();
182641
182745
  let existing = null;
182642
182746
  try {
182643
- existing = fs4.readFileSync(p, "utf8");
182747
+ existing = fs5.readFileSync(p, "utf8");
182644
182748
  } catch {
182645
182749
  }
182646
182750
  if (existing === SKILL_MD_CONTENT) return { path: p, alreadyInstalled: true };
@@ -182650,8 +182754,8 @@ function installSkill() {
182650
182754
  }
182651
182755
  function uninstallSkill() {
182652
182756
  const dir = skillDir();
182653
- if (!fs4.existsSync(dir)) return false;
182654
- fs4.rmSync(dir, { recursive: true, force: true });
182757
+ if (!fs5.existsSync(dir)) return false;
182758
+ fs5.rmSync(dir, { recursive: true, force: true });
182655
182759
  return true;
182656
182760
  }
182657
182761
 
@@ -182677,7 +182781,7 @@ function codexHookScriptPath() {
182677
182781
  function readCodexConfig(p, opts = {}) {
182678
182782
  let raw;
182679
182783
  try {
182680
- raw = fs5.readFileSync(p, "utf8");
182784
+ raw = fs6.readFileSync(p, "utf8");
182681
182785
  } catch {
182682
182786
  return {};
182683
182787
  }
@@ -182791,7 +182895,7 @@ function uninstallCodex() {
182791
182895
  removedAny = true;
182792
182896
  }
182793
182897
  try {
182794
- fs5.unlinkSync(scriptPath);
182898
+ fs6.unlinkSync(scriptPath);
182795
182899
  removedAny = true;
182796
182900
  } catch {
182797
182901
  }
@@ -182822,7 +182926,7 @@ function writeAgentsBlock(p) {
182822
182926
  const block = buildAgentsBlock();
182823
182927
  let existing;
182824
182928
  try {
182825
- existing = fs5.readFileSync(p, "utf8");
182929
+ existing = fs6.readFileSync(p, "utf8");
182826
182930
  } catch {
182827
182931
  existing = "";
182828
182932
  }
@@ -182850,7 +182954,7 @@ ${block}
182850
182954
  function stripAgentsBlock(p) {
182851
182955
  let existing;
182852
182956
  try {
182853
- existing = fs5.readFileSync(p, "utf8");
182957
+ existing = fs6.readFileSync(p, "utf8");
182854
182958
  } catch {
182855
182959
  return false;
182856
182960
  }
@@ -182954,6 +183058,21 @@ const FILE_PATH_ARG_KEY = {
182954
183058
  create: 'path',
182955
183059
  }
182956
183060
 
183061
+ // Copilot spawns a brand-new process for every single hook invocation (no long-lived plugin
183062
+ // process the way OpenClaw's is -- OPENCLAW_HOOK_SCRIPT's own \`copilot-\${process.pid}-\${Date.now()}\`
183063
+ // fallback is safe there specifically because that process lives for the whole session, so the
183064
+ // pid stays constant across calls). If Copilot ever omits \`sessionId\` from a payload, falling
183065
+ // back to \`process.pid\` here would mint a DIFFERENT id on every single call for what's really
183066
+ // the same session, since process.pid varies per invocation -- breaking token-goat's
183067
+ // session-based dedup/state ledger, which never accumulates across calls as a result. Derive a
183068
+ // stable id instead from the one thing that's actually constant across calls for the same
183069
+ // session: the working directory Copilot reports in \`payload.cwd\`.
183070
+ function stableFallbackSessionId(cwd) {
183071
+ const key = typeof cwd === 'string' && cwd ? cwd : process.cwd()
183072
+ const hash = require('node:crypto').createHash('sha256').update(key).digest('hex').slice(0, 16)
183073
+ return 'copilot-' + hash
183074
+ }
183075
+
182957
183076
  function remapToolInput(copilotToolName, input) {
182958
183077
  const pathKey = FILE_PATH_ARG_KEY[copilotToolName]
182959
183078
  if (pathKey === undefined || !input || typeof input !== 'object' || !(pathKey in input)) {
@@ -182996,7 +183115,7 @@ function main() {
182996
183115
 
182997
183116
  const toolName = payload && payload.toolName
182998
183117
  const canonical = {
182999
- session_id: (payload && payload.sessionId) || 'copilot-' + process.pid,
183118
+ session_id: (payload && payload.sessionId) || stableFallbackSessionId(payload && payload.cwd),
183000
183119
  cwd: payload && payload.cwd,
183001
183120
  }
183002
183121
  if (toolName) {
@@ -183143,7 +183262,7 @@ process.exitCode = 0
183143
183262
 
183144
183263
  // src/bridges/copilot_cli_install.ts
183145
183264
  init_define_import_meta_env();
183146
- import * as fs6 from "node:fs";
183265
+ import * as fs7 from "node:fs";
183147
183266
  import * as os4 from "node:os";
183148
183267
  import * as path10 from "node:path";
183149
183268
  var COPILOT_CLI_HOOK_EVENTS = [
@@ -183174,18 +183293,29 @@ function hookCommandFor2(scriptPath, event) {
183174
183293
  const entryArg = entryPath ? ` "${entryPath}"` : "";
183175
183294
  return `"${process.execPath}" "${scriptPath}" ${event}${entryArg}`;
183176
183295
  }
183296
+ function hookPowershellCommandFor(scriptPath, event) {
183297
+ return `& ${hookCommandFor2(scriptPath, event)}`;
183298
+ }
183177
183299
  var HOOK_TIMEOUT_SEC = 60;
183178
183300
  function buildConfig(scriptPath) {
183179
183301
  const hooks = {};
183180
183302
  for (const event of COPILOT_CLI_HOOK_EVENTS) {
183181
- hooks[event] = [{ type: "command", command: hookCommandFor2(scriptPath, event), timeoutSec: HOOK_TIMEOUT_SEC }];
183303
+ hooks[event] = [
183304
+ {
183305
+ type: "command",
183306
+ command: hookCommandFor2(scriptPath, event),
183307
+ bash: hookCommandFor2(scriptPath, event),
183308
+ powershell: hookPowershellCommandFor(scriptPath, event),
183309
+ timeoutSec: HOOK_TIMEOUT_SEC
183310
+ }
183311
+ ];
183182
183312
  }
183183
183313
  return { version: 1, hooks };
183184
183314
  }
183185
183315
  function writeIfDifferent(p, content, backup = false) {
183186
183316
  let existing;
183187
183317
  try {
183188
- existing = fs6.readFileSync(p, "utf8");
183318
+ existing = fs7.readFileSync(p, "utf8");
183189
183319
  } catch {
183190
183320
  existing = void 0;
183191
183321
  }
@@ -183208,12 +183338,12 @@ function uninstallCopilotCli(opts = {}) {
183208
183338
  const scriptPath = copilotCliScriptPath(opts);
183209
183339
  let removedAny = false;
183210
183340
  try {
183211
- fs6.unlinkSync(configPath2);
183341
+ fs7.unlinkSync(configPath2);
183212
183342
  removedAny = true;
183213
183343
  } catch {
183214
183344
  }
183215
183345
  try {
183216
- fs6.unlinkSync(scriptPath);
183346
+ fs7.unlinkSync(scriptPath);
183217
183347
  removedAny = true;
183218
183348
  } catch {
183219
183349
  }
@@ -183222,7 +183352,7 @@ function uninstallCopilotCli(opts = {}) {
183222
183352
 
183223
183353
  // src/disk_cache.ts
183224
183354
  init_define_import_meta_env();
183225
- import * as fs7 from "node:fs";
183355
+ import * as fs8 from "node:fs";
183226
183356
  import * as path11 from "node:path";
183227
183357
  import * as os5 from "node:os";
183228
183358
  var DEFAULT_MAX_COUNT = 200;
@@ -183275,7 +183405,7 @@ function storeBlob(subdir, id, value, opts = {}) {
183275
183405
  if (Number.isFinite(maxBytesPerItem) && Buffer.byteLength(json2, "utf-8") > maxBytesPerItem) return false;
183276
183406
  try {
183277
183407
  const dir = path11.dirname(p);
183278
- if (!fs7.existsSync(dir)) fs7.mkdirSync(dir, { recursive: true });
183408
+ if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
183279
183409
  atomicWriteText(p, json2);
183280
183410
  } catch {
183281
183411
  return false;
@@ -183293,8 +183423,8 @@ function loadBlob(subdir, id) {
183293
183423
  const p = blobPath(subdir, id);
183294
183424
  if (!p) return null;
183295
183425
  try {
183296
- if (!fs7.existsSync(p)) return null;
183297
- return JSON.parse(fs7.readFileSync(p, "utf8"));
183426
+ if (!fs8.existsSync(p)) return null;
183427
+ return JSON.parse(fs8.readFileSync(p, "utf8"));
183298
183428
  } catch {
183299
183429
  return null;
183300
183430
  }
@@ -183303,13 +183433,13 @@ function listBlobs(subdir) {
183303
183433
  const dir = blobDir(subdir);
183304
183434
  const out2 = [];
183305
183435
  try {
183306
- if (!fs7.existsSync(dir)) return out2;
183307
- for (const file2 of fs7.readdirSync(dir)) {
183436
+ if (!fs8.existsSync(dir)) return out2;
183437
+ for (const file2 of fs8.readdirSync(dir)) {
183308
183438
  if (!file2.endsWith(".json")) continue;
183309
183439
  const id = file2.slice(0, -5);
183310
183440
  let mtime = 0;
183311
183441
  try {
183312
- mtime = fs7.statSync(path11.join(dir, file2)).mtimeMs;
183442
+ mtime = fs8.statSync(path11.join(dir, file2)).mtimeMs;
183313
183443
  } catch {
183314
183444
  }
183315
183445
  const value = loadBlob(subdir, id);
@@ -183324,16 +183454,16 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
183324
183454
  const dir = blobDir(subdir);
183325
183455
  let removed = 0;
183326
183456
  try {
183327
- if (!fs7.existsSync(dir)) return 0;
183457
+ if (!fs8.existsSync(dir)) return 0;
183328
183458
  const cutoff = Date.now() - maxAgeMs;
183329
183459
  let kept = [];
183330
183460
  let protectedEntry;
183331
- for (const file2 of fs7.readdirSync(dir)) {
183461
+ for (const file2 of fs8.readdirSync(dir)) {
183332
183462
  if (!file2.endsWith(".json")) continue;
183333
183463
  const full = path11.join(dir, file2);
183334
183464
  let stat2;
183335
183465
  try {
183336
- stat2 = fs7.statSync(full);
183466
+ stat2 = fs8.statSync(full);
183337
183467
  } catch {
183338
183468
  continue;
183339
183469
  }
@@ -183343,7 +183473,7 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
183343
183473
  }
183344
183474
  if (stat2.mtimeMs < cutoff) {
183345
183475
  try {
183346
- fs7.unlinkSync(full);
183476
+ fs8.unlinkSync(full);
183347
183477
  removed++;
183348
183478
  } catch {
183349
183479
  continue;
@@ -183359,7 +183489,7 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
183359
183489
  kept = kept.slice(kept.length - countBudget);
183360
183490
  for (const [full] of excess) {
183361
183491
  try {
183362
- fs7.unlinkSync(full);
183492
+ fs8.unlinkSync(full);
183363
183493
  removed++;
183364
183494
  } catch {
183365
183495
  continue;
@@ -183374,7 +183504,7 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
183374
183504
  if (!oldest) break;
183375
183505
  const [full, , size] = oldest;
183376
183506
  try {
183377
- fs7.unlinkSync(full);
183507
+ fs8.unlinkSync(full);
183378
183508
  removed++;
183379
183509
  total -= size;
183380
183510
  } catch {
@@ -183390,13 +183520,13 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
183390
183520
 
183391
183521
  // src/session_store.ts
183392
183522
  init_define_import_meta_env();
183393
- import * as fs9 from "node:fs";
183523
+ import * as fs10 from "node:fs";
183394
183524
  import * as path12 from "node:path";
183395
183525
 
183396
183526
  // src/session.ts
183397
183527
  init_define_import_meta_env();
183398
183528
  import { randomBytes, randomUUID } from "node:crypto";
183399
- import * as fs8 from "node:fs";
183529
+ import * as fs9 from "node:fs";
183400
183530
  var _files = /* @__PURE__ */ new Map();
183401
183531
  var _filesAtLoad = /* @__PURE__ */ new Map();
183402
183532
  var _hintsShown = /* @__PURE__ */ new Set();
@@ -183410,7 +183540,7 @@ var _pendingLargeFileHintsAtLoad = /* @__PURE__ */ new Map();
183410
183540
  var _sessionId = null;
183411
183541
  function fileSize(absPath) {
183412
183542
  try {
183413
- return fs8.statSync(absPath).size;
183543
+ return fs9.statSync(absPath).size;
183414
183544
  } catch {
183415
183545
  return 0;
183416
183546
  }
@@ -183548,6 +183678,9 @@ function recordCurlDownload(url2, savedPath) {
183548
183678
  function getCurlDownloadPath(url2) {
183549
183679
  return _curlDownloads.get(url2) ?? null;
183550
183680
  }
183681
+ function clearCurlDownload(url2) {
183682
+ _curlDownloads.delete(url2);
183683
+ }
183551
183684
  var MAX_RANGES_PER_FILE = 64;
183552
183685
  function recordFileLineRange(filePath, start, end) {
183553
183686
  const key = foldPath(normalizePath(filePath));
@@ -183639,6 +183772,7 @@ registerReset(() => {
183639
183772
  var SAFE_RE = /[^a-zA-Z0-9_-]/g;
183640
183773
  var MAX_FILES = 500;
183641
183774
  var SESSIONS_SUBDIR = "sessions";
183775
+ var AGENT_SALT_MARKER = ":agent:".replace(SAFE_RE, "_");
183642
183776
  function sessionPath(sessionId) {
183643
183777
  if (!sessionId) return null;
183644
183778
  const safe = sessionId.replace(SAFE_RE, "_").slice(0, 64);
@@ -183816,8 +183950,8 @@ function capFiles(s, max2) {
183816
183950
  }
183817
183951
  function readDiskState(p) {
183818
183952
  try {
183819
- if (!fs9.existsSync(p)) return null;
183820
- return coerce(JSON.parse(fs9.readFileSync(p, "utf8")));
183953
+ if (!fs10.existsSync(p)) return null;
183954
+ return coerce(JSON.parse(fs10.readFileSync(p, "utf8")));
183821
183955
  } catch {
183822
183956
  return null;
183823
183957
  }
@@ -183827,6 +183961,25 @@ function readSessionStateFile(sessionId) {
183827
183961
  if (!p) return null;
183828
183962
  return readDiskState(p);
183829
183963
  }
183964
+ function listSiblingSessionStates(sessionId) {
183965
+ if (!sessionId) return [];
183966
+ const safeSessionId = sessionId.replace(SAFE_RE, "_");
183967
+ if (!safeSessionId) return [];
183968
+ const prefix = `${safeSessionId}${AGENT_SALT_MARKER}`;
183969
+ const dir = path12.join(tokenGoatHome(), SESSIONS_SUBDIR);
183970
+ const out2 = [];
183971
+ try {
183972
+ if (!fs10.existsSync(dir)) return out2;
183973
+ for (const file2 of fs10.readdirSync(dir)) {
183974
+ if (!file2.endsWith(".json") || !file2.startsWith(prefix)) continue;
183975
+ const state = readDiskState(path12.join(dir, file2));
183976
+ if (state !== null) out2.push(state);
183977
+ }
183978
+ } catch {
183979
+ return out2;
183980
+ }
183981
+ return out2;
183982
+ }
183830
183983
  function loadSessionState(sessionId) {
183831
183984
  const p = sessionPath(sessionId);
183832
183985
  if (!p) return;
@@ -183839,7 +183992,7 @@ function saveSessionState(sessionId) {
183839
183992
  if (!p) return;
183840
183993
  try {
183841
183994
  const dir = path12.dirname(p);
183842
- if (!fs9.existsSync(dir)) fs9.mkdirSync(dir, { recursive: true });
183995
+ if (!fs10.existsSync(dir)) fs10.mkdirSync(dir, { recursive: true });
183843
183996
  const mem = exportSessionState();
183844
183997
  const writeMerged = () => {
183845
183998
  const disk = readDiskState(p);
@@ -183989,7 +184142,7 @@ function getEffectiveAutoTriggerWindow() {
183989
184142
  }
183990
184143
  function isAutoTriggerMultiplierExplicit() {
183991
184144
  try {
183992
- const text = fs10.readFileSync(configPath(), "utf8");
184145
+ const text = fs11.readFileSync(configPath(), "utf8");
183993
184146
  const raw = parse(text);
183994
184147
  const ca_raw = raw["compact_assist"];
183995
184148
  if (ca_raw === null || typeof ca_raw !== "object" || Array.isArray(ca_raw)) {
@@ -184067,11 +184220,11 @@ function isNoisePath(inputPath) {
184067
184220
  function findLatestSessionId() {
184068
184221
  try {
184069
184222
  const sessionsDir = path13.join(tokenGoatHome(), "sessions");
184070
- if (!fs10.existsSync(sessionsDir)) {
184223
+ if (!fs11.existsSync(sessionsDir)) {
184071
184224
  return null;
184072
184225
  }
184073
- const files = fs10.readdirSync(sessionsDir);
184074
- const jsonFiles = files.filter((f) => f.endsWith(".json"));
184226
+ const files = fs11.readdirSync(sessionsDir);
184227
+ const jsonFiles = files.filter((f) => f.endsWith(".json") && !f.includes(AGENT_SALT_MARKER));
184075
184228
  if (jsonFiles.length === 0) {
184076
184229
  return null;
184077
184230
  }
@@ -184080,9 +184233,9 @@ function findLatestSessionId() {
184080
184233
  return null;
184081
184234
  }
184082
184235
  let latestFile = firstFile;
184083
- let latestMtime = fs10.statSync(path13.join(sessionsDir, firstFile)).mtimeMs;
184236
+ let latestMtime = fs11.statSync(path13.join(sessionsDir, firstFile)).mtimeMs;
184084
184237
  for (const file2 of jsonFiles) {
184085
- const mtime = fs10.statSync(path13.join(sessionsDir, file2)).mtimeMs;
184238
+ const mtime = fs11.statSync(path13.join(sessionsDir, file2)).mtimeMs;
184086
184239
  if (mtime > latestMtime) {
184087
184240
  latestFile = file2;
184088
184241
  latestMtime = mtime;
@@ -184098,36 +184251,36 @@ function writeSessionManifest(projectHash2, sessionId, manifestJson) {
184098
184251
  const safeSessionId = sessionId.replace(SESSION_ID_SAFE_RE, "_").slice(0, 64);
184099
184252
  if (!safeSessionId) return;
184100
184253
  const sessionsDir = path13.join(dataDir(), "projects", projectHash2, "sessions");
184101
- if (!fs10.existsSync(sessionsDir)) {
184102
- fs10.mkdirSync(sessionsDir, { recursive: true });
184254
+ if (!fs11.existsSync(sessionsDir)) {
184255
+ fs11.mkdirSync(sessionsDir, { recursive: true });
184103
184256
  }
184104
184257
  const dest = path13.join(sessionsDir, `${safeSessionId}.json`);
184105
184258
  atomicWriteText(dest, JSON.stringify(manifestJson));
184106
184259
  }
184107
184260
  function readAllSessionManifests(projectHash2, maxAgeSecs = 3600) {
184108
184261
  const sessionsDir = path13.join(dataDir(), "projects", projectHash2, "sessions");
184109
- if (!fs10.existsSync(sessionsDir)) {
184262
+ if (!fs11.existsSync(sessionsDir)) {
184110
184263
  return [];
184111
184264
  }
184112
184265
  const now = Date.now() / 1e3;
184113
184266
  const results = [];
184114
184267
  try {
184115
- const files = fs10.readdirSync(sessionsDir);
184268
+ const files = fs11.readdirSync(sessionsDir);
184116
184269
  for (const file2 of files) {
184117
184270
  if (!file2.endsWith(".json")) {
184118
184271
  continue;
184119
184272
  }
184120
184273
  try {
184121
184274
  const fullPath = path13.join(sessionsDir, file2);
184122
- const stat2 = fs10.statSync(fullPath);
184275
+ const stat2 = fs11.statSync(fullPath);
184123
184276
  if (now - stat2.mtimeMs / 1e3 > maxAgeSecs) {
184124
184277
  try {
184125
- fs10.unlinkSync(fullPath);
184278
+ fs11.unlinkSync(fullPath);
184126
184279
  } catch {
184127
184280
  }
184128
184281
  continue;
184129
184282
  }
184130
- const text = fs10.readFileSync(fullPath, "utf8");
184283
+ const text = fs11.readFileSync(fullPath, "utf8");
184131
184284
  const data = JSON.parse(text);
184132
184285
  if (typeof data === "object" && data !== null && "files" in data) {
184133
184286
  results.push(data);
@@ -184360,7 +184513,7 @@ function collectWalkIndexFiles(root) {
184360
184513
 
184361
184514
  // src/parser.ts
184362
184515
  init_define_import_meta_env();
184363
- import * as fs12 from "node:fs";
184516
+ import * as fs13 from "node:fs";
184364
184517
  import { createRequire as createRequire4 } from "node:module";
184365
184518
  import * as path18 from "node:path";
184366
184519
 
@@ -184382,6 +184535,12 @@ function ensureTransformerLoaded() {
184382
184535
  }
184383
184536
  var DEFAULT_MODEL = "Xenova/bge-small-en-v1.5";
184384
184537
  var DEFAULT_DIM = 384;
184538
+ var _extractorCache = /* @__PURE__ */ new Map();
184539
+ var _pipelineFnOverride = null;
184540
+ registerReset(() => {
184541
+ _extractorCache.clear();
184542
+ _pipelineFnOverride = null;
184543
+ });
184385
184544
  var MIN_CHUNK_CHARS = 50;
184386
184545
  var MAX_CHUNK_CHARS = 8e3;
184387
184546
  var DEFAULT_DISTANCE_THRESHOLD = 1.2;
@@ -184430,9 +184589,14 @@ async function embedTexts(texts, modelName = DEFAULT_MODEL) {
184430
184589
  if (!_transformer || typeof _transformer !== "object") {
184431
184590
  throw new Error("Transformer module is unavailable");
184432
184591
  }
184433
- const transformerObj = _transformer;
184434
- const pipelineFn = transformerObj["pipeline"];
184435
- const extractor = await pipelineFn("feature-extraction", modelName);
184592
+ let extractorPromise = _extractorCache.get(modelName);
184593
+ if (!extractorPromise) {
184594
+ const transformerObj = _transformer;
184595
+ const pipelineFn = _pipelineFnOverride ?? transformerObj["pipeline"];
184596
+ extractorPromise = pipelineFn("feature-extraction", modelName);
184597
+ _extractorCache.set(modelName, extractorPromise);
184598
+ }
184599
+ const extractor = await extractorPromise;
184436
184600
  const vecs = [];
184437
184601
  const expectedDim = DEFAULT_DIM;
184438
184602
  try {
@@ -184714,7 +184878,7 @@ function rerankHits(hits, query, topK) {
184714
184878
  return { hit, index, adjusted: hit.distance - boost + penalty };
184715
184879
  });
184716
184880
  scored.sort((a, b) => a.adjusted - b.adjusted || a.index - b.index);
184717
- return scored.slice(0, topK).map((entry) => entry.hit);
184881
+ return scored.slice(0, topK).map((entry) => ({ ...entry.hit, adjustedDistance: entry.adjusted }));
184718
184882
  }
184719
184883
  function mergeNearbyHits(hits, proximity = 20) {
184720
184884
  if (hits.length <= 1) {
@@ -184739,6 +184903,7 @@ function mergeNearbyHits(hits, proximity = 20) {
184739
184903
  let curStart = current.startLine;
184740
184904
  let curEnd = current.endLine;
184741
184905
  let curDist = current.distance;
184906
+ let curAdjusted = current.adjustedDistance ?? current.distance;
184742
184907
  const mergedTexts = [current.text];
184743
184908
  for (let i = 1; i < fileHits.length; i++) {
184744
184909
  const hit = fileHits[i];
@@ -184749,6 +184914,7 @@ function mergeNearbyHits(hits, proximity = 20) {
184749
184914
  if (gap <= proximity) {
184750
184915
  curEnd = Math.max(curEnd, hit.endLine);
184751
184916
  curDist = Math.min(curDist, hit.distance);
184917
+ curAdjusted = Math.min(curAdjusted, hit.adjustedDistance ?? hit.distance);
184752
184918
  mergedTexts.push(hit.text);
184753
184919
  } else {
184754
184920
  merged.push({
@@ -184757,12 +184923,14 @@ function mergeNearbyHits(hits, proximity = 20) {
184757
184923
  endLine: curEnd,
184758
184924
  kind: current.kind,
184759
184925
  distance: curDist,
184926
+ adjustedDistance: curAdjusted,
184760
184927
  text: mergedTexts.join("\n---\n")
184761
184928
  });
184762
184929
  current = hit;
184763
184930
  curStart = hit.startLine;
184764
184931
  curEnd = hit.endLine;
184765
184932
  curDist = hit.distance;
184933
+ curAdjusted = hit.adjustedDistance ?? hit.distance;
184766
184934
  mergedTexts.length = 0;
184767
184935
  mergedTexts.push(hit.text);
184768
184936
  }
@@ -184773,10 +184941,11 @@ function mergeNearbyHits(hits, proximity = 20) {
184773
184941
  endLine: curEnd,
184774
184942
  kind: current.kind,
184775
184943
  distance: curDist,
184944
+ adjustedDistance: curAdjusted,
184776
184945
  text: mergedTexts.join("\n---\n")
184777
184946
  });
184778
184947
  }
184779
- merged.sort((a, b) => a.distance - b.distance);
184948
+ merged.sort((a, b) => (a.adjustedDistance ?? a.distance) - (b.adjustedDistance ?? b.distance));
184780
184949
  return merged;
184781
184950
  }
184782
184951
  async function indexFile(db, filePath, content, boundaries = []) {
@@ -184822,7 +184991,7 @@ function _isGeneratedPath(filePath) {
184822
184991
  // src/fingerprint.ts
184823
184992
  init_define_import_meta_env();
184824
184993
  import { createHash } from "node:crypto";
184825
- import * as fs11 from "node:fs";
184994
+ import * as fs12 from "node:fs";
184826
184995
  function fingerprintContent(content) {
184827
184996
  const hash2 = createHash("sha256");
184828
184997
  hash2.update(typeof content === "string" ? Buffer.from(content, "utf-8") : content);
@@ -184834,7 +185003,7 @@ function shortFingerprint(content) {
184834
185003
  function fingerprintFile(filePath) {
184835
185004
  let data;
184836
185005
  try {
184837
- data = fs11.readFileSync(filePath);
185006
+ data = fs12.readFileSync(filePath);
184838
185007
  } catch {
184839
185008
  return null;
184840
185009
  }
@@ -185130,6 +185299,139 @@ function stripStringLiterals(line) {
185130
185299
  }
185131
185300
  return out2;
185132
185301
  }
185302
+ function escapeRegExp(s) {
185303
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
185304
+ }
185305
+ function findMultilineCloser(line, from2, state) {
185306
+ switch (state.kind) {
185307
+ case "heredoc":
185308
+ case "nowdoc": {
185309
+ const re = new RegExp(`^[ \\t]*${escapeRegExp(state.identifier)}\\b`);
185310
+ const m = re.exec(line);
185311
+ return m ? { maskEnd: m[0].length } : null;
185312
+ }
185313
+ case "tripleQuote": {
185314
+ const n = state.identifier !== "" ? parseInt(state.identifier, 10) : 3;
185315
+ const re = new RegExp(`"{${n},}`);
185316
+ const m = re.exec(line.slice(from2));
185317
+ return m === null ? null : { maskEnd: from2 + m.index + m[0].length };
185318
+ }
185319
+ case "verbatim": {
185320
+ let j = from2;
185321
+ while (j < line.length) {
185322
+ if (line[j] === '"') {
185323
+ if (line[j + 1] === '"') {
185324
+ j += 2;
185325
+ continue;
185326
+ }
185327
+ return { maskEnd: j + 1 };
185328
+ }
185329
+ j++;
185330
+ }
185331
+ return null;
185332
+ }
185333
+ case "psHereDouble":
185334
+ return line.startsWith('"@', from2) ? { maskEnd: from2 + 2 } : null;
185335
+ case "psHereSingle":
185336
+ return line.startsWith("'@", from2) ? { maskEnd: from2 + 2 } : null;
185337
+ default:
185338
+ return null;
185339
+ }
185340
+ }
185341
+ function findMultilineOpener(line, from2, lang) {
185342
+ if (lang === "php") {
185343
+ const re = /<<<\s*(['"]?)([A-Za-z_]\w*)\1/g;
185344
+ re.lastIndex = from2;
185345
+ const m = re.exec(line);
185346
+ if (!m || isInsideStringLiteral(line, m.index)) return null;
185347
+ const identifier = m[2] ?? "";
185348
+ const kind = m[1] === "'" ? "nowdoc" : "heredoc";
185349
+ return { openStart: m.index, closesSameLine: null, state: { kind, identifier } };
185350
+ }
185351
+ if (lang === "kotlin") {
185352
+ const idx = line.indexOf('"""', from2);
185353
+ if (idx === -1 || isInsideStringLiteral(line, idx)) return null;
185354
+ const closeIdx = line.indexOf('"""', idx + 3);
185355
+ if (closeIdx !== -1) {
185356
+ return { openStart: idx, closesSameLine: closeIdx + 3, state: { kind: "tripleQuote", identifier: "3" } };
185357
+ }
185358
+ return { openStart: idx, closesSameLine: null, state: { kind: "tripleQuote", identifier: "3" } };
185359
+ }
185360
+ if (lang === "csharp") {
185361
+ const tripleRe = /"{3,}/g;
185362
+ tripleRe.lastIndex = from2;
185363
+ const tripleM = tripleRe.exec(line);
185364
+ let tripleIdx = tripleM ? tripleM.index : -1;
185365
+ const tripleLen = tripleM ? tripleM[0].length : 0;
185366
+ if (tripleIdx !== -1 && isInsideStringLiteral(line, tripleIdx)) tripleIdx = -1;
185367
+ const verbRe = /\$?@\$?"/g;
185368
+ verbRe.lastIndex = from2;
185369
+ const verbM = verbRe.exec(line);
185370
+ const verbIdx = verbM ? verbM.index : -1;
185371
+ if (tripleIdx === -1 && verbIdx === -1) return null;
185372
+ const useTriple = tripleIdx !== -1 && (verbIdx === -1 || tripleIdx < verbIdx);
185373
+ if (useTriple) {
185374
+ const closeRe = new RegExp(`"{${tripleLen},}`);
185375
+ const closeM = closeRe.exec(line.slice(tripleIdx + tripleLen));
185376
+ if (closeM !== null) {
185377
+ const closeIdx = tripleIdx + tripleLen + closeM.index;
185378
+ return { openStart: tripleIdx, closesSameLine: closeIdx + closeM[0].length, state: { kind: "tripleQuote", identifier: String(tripleLen) } };
185379
+ }
185380
+ return { openStart: tripleIdx, closesSameLine: null, state: { kind: "tripleQuote", identifier: String(tripleLen) } };
185381
+ }
185382
+ const quoteIdx = verbIdx + (verbM?.[0].length ?? 1) - 1;
185383
+ const closer = findMultilineCloser(line, quoteIdx + 1, { kind: "verbatim", identifier: "" });
185384
+ if (closer !== null) {
185385
+ return { openStart: verbIdx, closesSameLine: closer.maskEnd, state: { kind: "verbatim", identifier: "" } };
185386
+ }
185387
+ return { openStart: verbIdx, closesSameLine: null, state: { kind: "verbatim", identifier: "" } };
185388
+ }
185389
+ if (lang === "powershell") {
185390
+ const re = /@("|')\s*$/;
185391
+ const tail = line.slice(from2);
185392
+ const m = re.exec(tail);
185393
+ if (!m) return null;
185394
+ const openStart = from2 + m.index;
185395
+ const kind = m[1] === '"' ? "psHereDouble" : "psHereSingle";
185396
+ return { openStart, closesSameLine: null, state: { kind, identifier: "" } };
185397
+ }
185398
+ return null;
185399
+ }
185400
+ function stripMultilineStringSpan(line, state, lang) {
185401
+ let code = "";
185402
+ let i = 0;
185403
+ let cur = state;
185404
+ while (i < line.length) {
185405
+ if (cur !== null) {
185406
+ const closed = findMultilineCloser(line, i, cur);
185407
+ if (closed === null) {
185408
+ code += " ".repeat(line.length - i);
185409
+ i = line.length;
185410
+ continue;
185411
+ }
185412
+ code += " ".repeat(closed.maskEnd - i);
185413
+ i = closed.maskEnd;
185414
+ cur = null;
185415
+ continue;
185416
+ }
185417
+ const opened = findMultilineOpener(line, i, lang);
185418
+ if (opened === null) {
185419
+ code += line.slice(i);
185420
+ break;
185421
+ }
185422
+ code += line.slice(i, opened.openStart);
185423
+ if (opened.closesSameLine !== null) {
185424
+ code += " ".repeat(opened.closesSameLine - opened.openStart);
185425
+ i = opened.closesSameLine;
185426
+ cur = null;
185427
+ } else {
185428
+ code += " ".repeat(line.length - opened.openStart);
185429
+ i = line.length;
185430
+ cur = opened.state;
185431
+ }
185432
+ }
185433
+ return { code, state: cur };
185434
+ }
185133
185435
  function makeSymbolEmitter(symbols, sections, seen, filePath, maxSymbols = 500, maxHeadingLen = 120) {
185134
185436
  return function emit5(name2, kind, line) {
185135
185437
  if (!name2 || name2.length > maxHeadingLen) return;
@@ -185213,11 +185515,18 @@ function extractCsharp(content, filePath) {
185213
185515
  const classStack = [];
185214
185516
  let braceDepth = 0;
185215
185517
  let inComment = false;
185518
+ let mlState = null;
185216
185519
  for (let i = 0; i < lines.length; i++) {
185217
185520
  const rawLine = lines[i] ?? "";
185218
185521
  const lineNum = i + 1;
185219
185522
  let openedFrameThisLine = false;
185220
- const { code: codeLine, inComment: nextInComment } = stripBlockCommentSpan(rawLine, inComment);
185523
+ let mlLine = rawLine;
185524
+ if (mlState !== null || !inComment) {
185525
+ const masked = stripMultilineStringSpan(rawLine, mlState, "csharp");
185526
+ mlLine = masked.code;
185527
+ mlState = masked.state;
185528
+ }
185529
+ const { code: codeLine, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment);
185221
185530
  inComment = nextInComment;
185222
185531
  const line = codeLine.trimEnd();
185223
185532
  const stripped = line.trim();
@@ -185333,13 +185642,20 @@ function extractPhp(content, filePath) {
185333
185642
  const contextStack = [];
185334
185643
  let braceDepth = 0;
185335
185644
  let inComment = false;
185645
+ let mlState = null;
185336
185646
  function currentClass() {
185337
185647
  return contextStack.length > 0 ? contextStack[contextStack.length - 1]?.[0] ?? null : null;
185338
185648
  }
185339
185649
  for (let i = 0; i < lines.length; i++) {
185340
185650
  const rawLine = lines[i] ?? "";
185341
185651
  const lineNum = i + 1;
185342
- const { code: codeLine, inComment: nextInComment } = stripBlockCommentSpan(rawLine, inComment);
185652
+ let mlLine = rawLine;
185653
+ if (mlState !== null || !inComment) {
185654
+ const masked = stripMultilineStringSpan(rawLine, mlState, "php");
185655
+ mlLine = masked.code;
185656
+ mlState = masked.state;
185657
+ }
185658
+ const { code: codeLine, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment);
185343
185659
  inComment = nextInComment;
185344
185660
  const line = codeLine.trimEnd();
185345
185661
  const stripped = line.trimStart();
@@ -185641,10 +185957,17 @@ function extractKotlin(content, filePath) {
185641
185957
  const classStack = [];
185642
185958
  let braceDepth = 0;
185643
185959
  let inComment = false;
185960
+ let mlState = null;
185644
185961
  for (let i = 0; i < lines.length; i++) {
185645
185962
  const rawLine = lines[i] ?? "";
185646
185963
  const lineNum = i + 1;
185647
- const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(rawLine, inComment);
185964
+ let mlLine = rawLine;
185965
+ if (mlState !== null || !inComment) {
185966
+ const masked = stripMultilineStringSpan(rawLine, mlState, "kotlin");
185967
+ mlLine = masked.code;
185968
+ mlState = masked.state;
185969
+ }
185970
+ const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment);
185648
185971
  inComment = nextInComment;
185649
185972
  const line = stripLineComment(blockStripped);
185650
185973
  const stripped = line.trim();
@@ -185735,6 +186058,16 @@ var KIND_MAP = /* @__PURE__ */ new Map([
185735
186058
  ]);
185736
186059
  var MAX_SYMBOLS = 500;
185737
186060
  var MAX_HEADING_LEN = 120;
186061
+ function stripGraphqlDescriptions(text) {
186062
+ let state = null;
186063
+ const outLines = [];
186064
+ for (const line of text.split("\n")) {
186065
+ const { code, state: nextState } = stripMultilineStringSpan(line, state, "kotlin");
186066
+ state = nextState;
186067
+ outLines.push(stripStringLiterals(code));
186068
+ }
186069
+ return outLines.join("\n");
186070
+ }
185738
186071
  function extractGraphql(content, filePath) {
185739
186072
  const symbols = [];
185740
186073
  const sections = [];
@@ -185748,7 +186081,7 @@ function extractGraphql(content, filePath) {
185748
186081
  imports.push({ kind: "import", target, line });
185749
186082
  }
185750
186083
  }
185751
- const stripped = stripHashComments(content);
186084
+ const stripped = stripGraphqlDescriptions(stripHashComments(content));
185752
186085
  const totalLines = content.split("\n").length;
185753
186086
  for (const m of stripped.matchAll(TYPE_RE)) {
185754
186087
  const keyword = m.groups?.["keyword"] ?? "";
@@ -185828,6 +186161,37 @@ var PATTERNS = [
185828
186161
  [TYPE_RE2, "sql_type"],
185829
186162
  [SCHEMA_RE3, "sql_schema"]
185830
186163
  ];
186164
+ function stripSqlStringLiterals(text) {
186165
+ let out2 = "";
186166
+ let i = 0;
186167
+ while (i < text.length) {
186168
+ const ch2 = text[i];
186169
+ if (ch2 === "'") {
186170
+ const quote = ch2;
186171
+ out2 += quote;
186172
+ i++;
186173
+ while (i < text.length) {
186174
+ const c = text[i];
186175
+ if (c === quote) {
186176
+ if (text[i + 1] === quote) {
186177
+ out2 += " ";
186178
+ i += 2;
186179
+ continue;
186180
+ }
186181
+ out2 += quote;
186182
+ i++;
186183
+ break;
186184
+ }
186185
+ out2 += c === "\n" ? "\n" : " ";
186186
+ i++;
186187
+ }
186188
+ continue;
186189
+ }
186190
+ out2 += ch2;
186191
+ i++;
186192
+ }
186193
+ return out2;
186194
+ }
185831
186195
  function unquote(name2) {
185832
186196
  if (name2.length >= 2 && (name2[0] === '"' && name2[name2.length - 1] === '"' || name2[0] === "`" && name2[name2.length - 1] === "`" || name2[0] === "[" && name2[name2.length - 1] === "]")) {
185833
186197
  return name2.slice(1, -1);
@@ -185842,9 +186206,10 @@ function extractSql(content, filePath) {
185842
186206
  let stripped = stripSqlLineComments(content);
185843
186207
  stripped = stripCstyleComments(stripped);
185844
186208
  const totalLines = content.split("\n").length;
186209
+ const noStrings = stripSqlStringLiterals(stripped);
185845
186210
  for (const [pattern, kind] of PATTERNS) {
185846
186211
  pattern.lastIndex = 0;
185847
- for (const m of stripped.matchAll(pattern)) {
186212
+ for (const m of noStrings.matchAll(pattern)) {
185848
186213
  const rawName = m[1];
185849
186214
  if (rawName) {
185850
186215
  const name2 = unquote(rawName).trim();
@@ -186123,9 +186488,17 @@ function extractPowershell(content, filePath) {
186123
186488
  let classBodyEntered = false;
186124
186489
  let braceDepth = 0;
186125
186490
  let inBlockComment = false;
186491
+ let mlState = null;
186126
186492
  for (let i = 0; i < lines.length; i++) {
186127
- const rawLine = lines[i] ?? "";
186493
+ const sourceLine = lines[i] ?? "";
186128
186494
  const lineNum = i + 1;
186495
+ let mlLine = sourceLine;
186496
+ if (mlState !== null || !inBlockComment) {
186497
+ const masked = stripMultilineStringSpan(sourceLine, mlState, "powershell");
186498
+ mlLine = masked.code;
186499
+ mlState = masked.state;
186500
+ }
186501
+ const rawLine = mlLine;
186129
186502
  let line = rawLine;
186130
186503
  let openedBlockCommentThisLine = false;
186131
186504
  if (!inBlockComment) {
@@ -186308,8 +186681,8 @@ function extractApex(content, filePath) {
186308
186681
  const seen = /* @__PURE__ */ new Set();
186309
186682
  const lineIndex = buildLineIndex(content);
186310
186683
  const rawLines = content.split(/\r?\n/);
186311
- const commentFree = stripCstyleComments(content, /\/\/.*$/gm);
186312
- const code = stripStringLiterals(commentFree);
186684
+ const stringFree = stripStringLiterals(content);
186685
+ const code = stripCstyleComments(stringFree, /\/\/.*$/gm);
186313
186686
  const emit5 = (name2, kind, span, docstring = "") => {
186314
186687
  if (!name2 || symbols.length >= MAX_SYMBOLS6) return;
186315
186688
  const key = `${name2}\0${kind}\0${span.startLine}`;
@@ -187356,6 +187729,9 @@ function extractWithRegex(content, filePath) {
187356
187729
  return out2;
187357
187730
  }
187358
187731
  function parseContent(content, filePath, language) {
187732
+ if (content.charCodeAt(0) === 65279) {
187733
+ content = content.slice(1);
187734
+ }
187359
187735
  if (isTreeSitterAvailable(language)) {
187360
187736
  try {
187361
187737
  const Ctor = loadParserCtor();
@@ -187469,7 +187845,7 @@ function indexFileSync(filePath, dbPath = globalDbPath()) {
187469
187845
  const language = detectLanguage(filePath);
187470
187846
  let raw;
187471
187847
  try {
187472
- raw = fs12.readFileSync(filePath);
187848
+ raw = fs13.readFileSync(filePath);
187473
187849
  } catch (err3) {
187474
187850
  if (err3.code === "ENOENT") return;
187475
187851
  throw err3;
@@ -187493,15 +187869,24 @@ function buildEmbeddingBoundaries(filePath, content, dbPath) {
187493
187869
  const symbols = querySymbols({ filePath, limit: 1e4 }, dbPath);
187494
187870
  return symbols.map((s) => ({ start: s.lineStart, end: s.lineEnd, kind: "symbol" }));
187495
187871
  }
187496
- async function indexFileEmbeddings(filePath, dbPath = globalDbPath()) {
187497
- if (!loadConfig().indexing.embeddings_enabled) return;
187872
+ var DISABLED_EMBED_SHA_PREFIX = "disabled:";
187873
+ function disabledEmbedSha(sha) {
187874
+ return DISABLED_EMBED_SHA_PREFIX + sha;
187875
+ }
187876
+ async function indexFileEmbeddings(filePath, dbPath = globalDbPath(), sha) {
187877
+ if (!loadConfig().indexing.embeddings_enabled) {
187878
+ if (sha !== void 0) {
187879
+ getDb(dbPath).prepare(`UPDATE files SET embed_sha = ? WHERE ${pathEqClause("path")}`).run(disabledEmbedSha(sha), foldPath(filePath));
187880
+ }
187881
+ return;
187882
+ }
187498
187883
  if (filePath.toLowerCase().endsWith(".profile-meta.xml")) {
187499
187884
  deleteFileEmbeddings(getDb(dbPath), filePath);
187500
187885
  return;
187501
187886
  }
187502
187887
  let content;
187503
187888
  try {
187504
- content = await fs12.promises.readFile(filePath, "utf8");
187889
+ content = await fs13.promises.readFile(filePath, "utf8");
187505
187890
  } catch {
187506
187891
  return;
187507
187892
  }
@@ -187513,6 +187898,12 @@ async function indexFileEmbeddings(filePath, dbPath = globalDbPath()) {
187513
187898
  const db = getDb(dbPath);
187514
187899
  const boundaries = buildEmbeddingBoundaries(filePath, content, dbPath);
187515
187900
  await indexFile(db, filePath, content, boundaries);
187901
+ if (sha !== void 0) {
187902
+ db.prepare(`UPDATE files SET embed_sha = ? WHERE ${pathEqClause("path")}`).run(
187903
+ sha,
187904
+ foldPath(filePath)
187905
+ );
187906
+ }
187516
187907
  } catch {
187517
187908
  }
187518
187909
  }
@@ -187525,7 +187916,7 @@ function safeSha(filePath) {
187525
187916
  }
187526
187917
  function safeMtime(filePath) {
187527
187918
  try {
187528
- return fs12.statSync(filePath).mtimeMs / 1e3;
187919
+ return fs13.statSync(filePath).mtimeMs / 1e3;
187529
187920
  } catch {
187530
187921
  return 0;
187531
187922
  }
@@ -187533,7 +187924,7 @@ function safeMtime(filePath) {
187533
187924
 
187534
187925
  // src/index_prune.ts
187535
187926
  init_define_import_meta_env();
187536
- import * as fs13 from "node:fs";
187927
+ import * as fs14 from "node:fs";
187537
187928
  function removeFileFromIndex(db, filePath) {
187538
187929
  deleteFileRows(db, filePath);
187539
187930
  deleteFileEmbeddings(db, filePath);
@@ -187555,7 +187946,7 @@ function pruneDeletedFiles(rootPrefix, dbPath = globalDbPath()) {
187555
187946
  if (foldedP !== foldedRootPrefix && !foldedP.startsWith(foldedPrefix)) continue;
187556
187947
  let stillExists;
187557
187948
  try {
187558
- stillExists = fs13.statSync(p, { throwIfNoEntry: false }) !== void 0;
187949
+ stillExists = fs14.statSync(p, { throwIfNoEntry: false }) !== void 0;
187559
187950
  } catch {
187560
187951
  continue;
187561
187952
  }
@@ -187571,7 +187962,7 @@ function pruneDeletedFiles(rootPrefix, dbPath = globalDbPath()) {
187571
187962
 
187572
187963
  // src/hooks_index.ts
187573
187964
  init_define_import_meta_env();
187574
- import * as fs16 from "node:fs";
187965
+ import * as fs17 from "node:fs";
187575
187966
  import * as path21 from "node:path";
187576
187967
 
187577
187968
  // src/hook_registry.ts
@@ -187673,14 +188064,14 @@ function contextOutput(context2) {
187673
188064
  // src/worker.ts
187674
188065
  init_define_import_meta_env();
187675
188066
  import { spawn as spawn2 } from "node:child_process";
187676
- import * as fs15 from "node:fs";
188067
+ import * as fs16 from "node:fs";
187677
188068
  import * as path20 from "node:path";
187678
188069
  import { Worker as Worker2, isMainThread, parentPort, workerData } from "node:worker_threads";
187679
188070
  import { fileURLToPath } from "node:url";
187680
188071
 
187681
188072
  // src/snapshots.ts
187682
188073
  init_define_import_meta_env();
187683
- import * as fs14 from "node:fs";
188074
+ import * as fs15 from "node:fs";
187684
188075
  import * as path19 from "node:path";
187685
188076
  import * as crypto2 from "node:crypto";
187686
188077
  var MAX_SNAPSHOTS_PER_SESSION = 150;
@@ -187719,10 +188110,10 @@ function writeSnapshotKind(sidecarPath, kind) {
187719
188110
  try {
187720
188111
  const safeKind = VALID_KINDS.has(kind) ? kind : KIND_READ;
187721
188112
  const dir = path19.dirname(sidecarPath);
187722
- if (!fs14.existsSync(dir)) {
187723
- fs14.mkdirSync(dir, { recursive: true });
188113
+ if (!fs15.existsSync(dir)) {
188114
+ fs15.mkdirSync(dir, { recursive: true });
187724
188115
  }
187725
- fs14.writeFileSync(sidecarPath, safeKind, "utf8");
188116
+ fs15.writeFileSync(sidecarPath, safeKind, "utf8");
187726
188117
  return true;
187727
188118
  } catch {
187728
188119
  return false;
@@ -187731,12 +188122,12 @@ function writeSnapshotKind(sidecarPath, kind) {
187731
188122
  function evictOldest(d, maxCount) {
187732
188123
  try {
187733
188124
  const entries = [];
187734
- const files = fs14.readdirSync(d);
188125
+ const files = fs15.readdirSync(d);
187735
188126
  for (const file2 of files) {
187736
188127
  const fullPath = path19.join(d, file2);
187737
188128
  if (!file2.endsWith(".bin")) continue;
187738
188129
  try {
187739
- const stat2 = fs14.statSync(fullPath);
188130
+ const stat2 = fs15.statSync(fullPath);
187740
188131
  entries.push([fullPath, stat2.mtimeMs]);
187741
188132
  } catch {
187742
188133
  continue;
@@ -187748,10 +188139,10 @@ function evictOldest(d, maxCount) {
187748
188139
  const over = entries.length - maxCount;
187749
188140
  for (const [p] of entries.slice(0, over)) {
187750
188141
  try {
187751
- fs14.unlinkSync(p);
188142
+ fs15.unlinkSync(p);
187752
188143
  removed++;
187753
188144
  try {
187754
- fs14.unlinkSync(kindSidecarPath(p));
188145
+ fs15.unlinkSync(kindSidecarPath(p));
187755
188146
  } catch {
187756
188147
  }
187757
188148
  } catch {
@@ -187780,10 +188171,10 @@ function store(sessionId, filePath, content, opts = {}) {
187780
188171
  if (!p) return null;
187781
188172
  const sha = crypto2.createHash("sha256").update(stored).digest("hex");
187782
188173
  try {
187783
- const isNewEntry = !fs14.existsSync(p);
188174
+ const isNewEntry = !fs15.existsSync(p);
187784
188175
  if (!isNewEntry) {
187785
188176
  try {
187786
- const existing = fs14.readFileSync(p);
188177
+ const existing = fs15.readFileSync(p);
187787
188178
  if (Buffer.from(existing).equals(stored)) {
187788
188179
  return {
187789
188180
  path: p,
@@ -187795,8 +188186,8 @@ function store(sessionId, filePath, content, opts = {}) {
187795
188186
  }
187796
188187
  }
187797
188188
  const dir = path19.dirname(p);
187798
- if (!fs14.existsSync(dir)) {
187799
- fs14.mkdirSync(dir, { recursive: true });
188189
+ if (!fs15.existsSync(dir)) {
188190
+ fs15.mkdirSync(dir, { recursive: true });
187800
188191
  }
187801
188192
  if (isNewEntry) {
187802
188193
  evictOldest(dir, MAX_SNAPSHOTS_PER_SESSION - 1);
@@ -187815,9 +188206,9 @@ function store(sessionId, filePath, content, opts = {}) {
187815
188206
  }
187816
188207
  function load(sessionId, filePath, opts = {}) {
187817
188208
  const p = snapshot_path(sessionId, filePath);
187818
- if (!p || !fs14.existsSync(p)) return null;
188209
+ if (!p || !fs15.existsSync(p)) return null;
187819
188210
  try {
187820
- const stat2 = fs14.statSync(p);
188211
+ const stat2 = fs15.statSync(p);
187821
188212
  if (stat2.size > MAX_SNAPSHOT_BYTES) {
187822
188213
  return null;
187823
188214
  }
@@ -187825,7 +188216,7 @@ function load(sessionId, filePath, opts = {}) {
187825
188216
  return null;
187826
188217
  }
187827
188218
  try {
187828
- const data = fs14.readFileSync(p);
188219
+ const data = fs15.readFileSync(p);
187829
188220
  if (opts.expected_sha) {
187830
188221
  const actualSha = crypto2.createHash("sha256").update(data).digest("hex");
187831
188222
  if (actualSha.toLowerCase() !== opts.expected_sha.toLowerCase()) {
@@ -187839,30 +188230,30 @@ function load(sessionId, filePath, opts = {}) {
187839
188230
  }
187840
188231
  function cleanup_stale(maxAgeHours = 24) {
187841
188232
  const base = path19.join(tokenGoatHome(), "session_snapshots");
187842
- if (!fs14.existsSync(base)) return 0;
188233
+ if (!fs15.existsSync(base)) return 0;
187843
188234
  const cutoff = Date.now() - maxAgeHours * 3600 * 1e3;
187844
188235
  let removed = 0;
187845
188236
  try {
187846
- const sessionDirs = fs14.readdirSync(base);
188237
+ const sessionDirs = fs15.readdirSync(base);
187847
188238
  for (const sessionDir2 of sessionDirs) {
187848
188239
  const sessionPath2 = path19.join(base, sessionDir2);
187849
188240
  try {
187850
- const stat2 = fs14.statSync(sessionPath2);
188241
+ const stat2 = fs15.statSync(sessionPath2);
187851
188242
  if (!stat2.isDirectory()) continue;
187852
188243
  } catch {
187853
188244
  continue;
187854
188245
  }
187855
188246
  try {
187856
- const files = fs14.readdirSync(sessionPath2);
188247
+ const files = fs15.readdirSync(sessionPath2);
187857
188248
  for (const file2 of files) {
187858
188249
  const fullPath = path19.join(sessionPath2, file2);
187859
188250
  try {
187860
- const stat2 = fs14.lstatSync(fullPath);
188251
+ const stat2 = fs15.lstatSync(fullPath);
187861
188252
  if ((stat2.mode & 61440) === 40960) {
187862
188253
  continue;
187863
188254
  }
187864
188255
  if (stat2.mtimeMs < cutoff) {
187865
- fs14.unlinkSync(fullPath);
188256
+ fs15.unlinkSync(fullPath);
187866
188257
  if (file2.endsWith(".bin")) {
187867
188258
  removed++;
187868
188259
  }
@@ -187872,7 +188263,7 @@ function cleanup_stale(maxAgeHours = 24) {
187872
188263
  }
187873
188264
  }
187874
188265
  try {
187875
- fs14.rmdirSync(sessionPath2);
188266
+ fs15.rmdirSync(sessionPath2);
187876
188267
  } catch {
187877
188268
  }
187878
188269
  } catch {
@@ -187890,9 +188281,31 @@ var DEFAULT_POLL_INTERVAL_MS = 2e3;
187890
188281
  var SNAPSHOT_CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
187891
188282
  var unclearedDrainingSnapshots = /* @__PURE__ */ new Map();
187892
188283
  var MAX_TRANSIENT_RETRIES = 5;
187893
- var transientRetryCounts = /* @__PURE__ */ new Map();
187894
- function resetTransientRetryCount(absPath) {
187895
- transientRetryCounts.delete(foldPath(normalizePath(absPath)));
188284
+ function bumpRetryCount(dbPath, absPath) {
188285
+ const db = getDb(dbPath);
188286
+ const folded = foldPath(absPath);
188287
+ const tx = db.transaction(() => {
188288
+ const row = db.prepare(`SELECT retry_count FROM files WHERE ${pathEqClause("path")}`).get(folded);
188289
+ if (row !== void 0) {
188290
+ const next = (row.retry_count ?? 0) + 1;
188291
+ db.prepare(`UPDATE files SET retry_count = ? WHERE ${pathEqClause("path")}`).run(next, folded);
188292
+ return next;
188293
+ }
188294
+ db.prepare("INSERT INTO files (path, retry_count) VALUES (?, 1)").run(absPath);
188295
+ return 1;
188296
+ });
188297
+ return tx();
188298
+ }
188299
+ function clearRetryCount(dbPath, absPath) {
188300
+ try {
188301
+ const db = getDb(dbPath);
188302
+ const folded = foldPath(absPath);
188303
+ db.prepare(`UPDATE files SET retry_count = 0 WHERE ${pathEqClause("path")}`).run(folded);
188304
+ } catch {
188305
+ }
188306
+ }
188307
+ function resetTransientRetryCount(absPath, dbPath = globalDbPath()) {
188308
+ clearRetryCount(dbPath, absPath);
187896
188309
  }
187897
188310
  function dirtyQueuePathFor(dir) {
187898
188311
  return path20.join(dir, "queue", "dirty.txt");
@@ -187920,7 +188333,7 @@ function workerErrorLogPath(dir) {
187920
188333
  var INDEX_FAILED = Symbol("indexFailed");
187921
188334
  function appendWorkerErrorLog(dir, line) {
187922
188335
  try {
187923
- fs15.appendFileSync(workerErrorLogPath(dir), line);
188336
+ fs16.appendFileSync(workerErrorLogPath(dir), line);
187924
188337
  } catch {
187925
188338
  }
187926
188339
  }
@@ -187937,9 +188350,8 @@ function logTransientReadFailure(dir, absPath) {
187937
188350
  );
187938
188351
  }
187939
188352
  function requeueDirtyPath(dir, absPath) {
187940
- const retryKey = foldPath(normalizePath(absPath));
187941
- const attempts = (transientRetryCounts.get(retryKey) ?? 0) + 1;
187942
- transientRetryCounts.set(retryKey, attempts);
188353
+ const dbPath = path20.join(dir, "global.db");
188354
+ const attempts = bumpRetryCount(dbPath, absPath);
187943
188355
  if (attempts > MAX_TRANSIENT_RETRIES) {
187944
188356
  if (attempts === MAX_TRANSIENT_RETRIES + 1) {
187945
188357
  appendWorkerErrorLog(
@@ -187952,14 +188364,14 @@ function requeueDirtyPath(dir, absPath) {
187952
188364
  }
187953
188365
  const queuePath = dirtyQueuePathFor(dir);
187954
188366
  try {
187955
- fs15.mkdirSync(path20.dirname(queuePath), { recursive: true });
188367
+ fs16.mkdirSync(path20.dirname(queuePath), { recursive: true });
187956
188368
  let leadingNewline = "";
187957
188369
  try {
187958
- const existing = fs15.readFileSync(queuePath, "utf8");
188370
+ const existing = fs16.readFileSync(queuePath, "utf8");
187959
188371
  if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
187960
188372
  } catch {
187961
188373
  }
187962
- fs15.appendFileSync(queuePath, `${leadingNewline}${absPath}
188374
+ fs16.appendFileSync(queuePath, `${leadingNewline}${absPath}
187963
188375
  `);
187964
188376
  } catch {
187965
188377
  }
@@ -187968,9 +188380,17 @@ function makeIndexer(dbPath) {
187968
188380
  const dir = path20.dirname(dbPath);
187969
188381
  return (absPath, sha) => {
187970
188382
  try {
187971
- if (getFileEntry(absPath, dbPath)?.sha === sha) return false;
187972
- indexFileSync(absPath, dbPath);
187973
- return indexFileEmbeddings(absPath, dbPath).catch(() => void 0);
188383
+ const entry = getFileEntry(absPath, dbPath);
188384
+ const parseUnchanged = entry?.sha === sha;
188385
+ if (!parseUnchanged) {
188386
+ indexFileSync(absPath, dbPath);
188387
+ }
188388
+ const embeddingsEnabled = loadConfig().indexing?.embeddings_enabled ?? true;
188389
+ const embedUnchanged = parseUnchanged && entry?.embedSha === (embeddingsEnabled ? sha : disabledEmbedSha(sha));
188390
+ if (embedUnchanged) {
188391
+ return false;
188392
+ }
188393
+ return indexFileEmbeddings(absPath, dbPath, sha).catch(() => void 0);
187974
188394
  } catch (err3) {
187975
188395
  logIndexFailure(dir, absPath, err3);
187976
188396
  return INDEX_FAILED;
@@ -187991,7 +188411,7 @@ function processDirtyBatch(paths, index = makeIndexer(globalDbPath()), remove =
187991
188411
  for (const p of paths) {
187992
188412
  if (!p) continue;
187993
188413
  if (isUnderBlockedRoot(p, blockedRoots)) continue;
187994
- if (!fs15.existsSync(p)) {
188414
+ if (!fs16.existsSync(p)) {
187995
188415
  remove(p);
187996
188416
  continue;
187997
188417
  }
@@ -188001,7 +188421,7 @@ function processDirtyBatch(paths, index = makeIndexer(globalDbPath()), remove =
188001
188421
  requeueDirtyPath(dir, p);
188002
188422
  continue;
188003
188423
  }
188004
- transientRetryCounts.delete(foldPath(normalizePath(p)));
188424
+ clearRetryCount(path20.join(dir, "global.db"), p);
188005
188425
  const result = index(p, sha);
188006
188426
  if (result !== false && result !== INDEX_FAILED) indexed += 1;
188007
188427
  }
@@ -188020,13 +188440,13 @@ function drainOnce(dir, index, remove) {
188020
188440
  const indexFn = index ?? makeIndexer(dbPath);
188021
188441
  const removeFn = remove ?? makeRemover(dbPath);
188022
188442
  let processed = 0;
188023
- if (fs15.existsSync(draining)) {
188443
+ if (fs16.existsSync(draining)) {
188024
188444
  let drainingContent;
188025
188445
  try {
188026
- drainingContent = fs15.readFileSync(draining, "utf8");
188446
+ drainingContent = fs16.readFileSync(draining, "utf8");
188027
188447
  } catch {
188028
188448
  try {
188029
- fs15.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188449
+ fs16.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188030
188450
  } catch {
188031
188451
  }
188032
188452
  return 0;
@@ -188035,22 +188455,22 @@ function drainOnce(dir, index, remove) {
188035
188455
  processed += processDirtyBatch(parseDirtyQueueLines(drainingContent), indexFn, removeFn, dir);
188036
188456
  }
188037
188457
  try {
188038
- fs15.rmSync(draining, { force: true });
188458
+ fs16.rmSync(draining, { force: true });
188039
188459
  unclearedDrainingSnapshots.delete(draining);
188040
188460
  } catch {
188041
188461
  try {
188042
- fs15.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188462
+ fs16.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188043
188463
  unclearedDrainingSnapshots.delete(draining);
188044
188464
  } catch {
188045
188465
  unclearedDrainingSnapshots.set(draining, drainingContent);
188046
188466
  }
188047
188467
  }
188048
188468
  }
188049
- if (fs15.existsSync(queuePath)) {
188469
+ if (fs16.existsSync(queuePath)) {
188050
188470
  let claimed = false;
188051
188471
  for (let attempt = 0; attempt < 5; attempt++) {
188052
188472
  try {
188053
- fs15.renameSync(queuePath, draining);
188473
+ fs16.renameSync(queuePath, draining);
188054
188474
  claimed = true;
188055
188475
  break;
188056
188476
  } catch {
@@ -188061,17 +188481,17 @@ function drainOnce(dir, index, remove) {
188061
188481
  let claimedContent = "";
188062
188482
  let readOk = false;
188063
188483
  try {
188064
- claimedContent = fs15.readFileSync(draining, "utf8");
188484
+ claimedContent = fs16.readFileSync(draining, "utf8");
188065
188485
  readOk = true;
188066
188486
  } catch {
188067
188487
  }
188068
188488
  if (readOk) {
188069
188489
  processed += processDirtyBatch(parseDirtyQueueLines(claimedContent), indexFn, removeFn, dir);
188070
188490
  try {
188071
- fs15.rmSync(draining, { force: true });
188491
+ fs16.rmSync(draining, { force: true });
188072
188492
  } catch {
188073
188493
  try {
188074
- fs15.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188494
+ fs16.renameSync(draining, `${draining}.corrupt-${Date.now()}`);
188075
188495
  } catch {
188076
188496
  unclearedDrainingSnapshots.set(draining, claimedContent);
188077
188497
  }
@@ -188091,7 +188511,7 @@ function pidAlive(pid) {
188091
188511
  }
188092
188512
  function readPidFile(dir) {
188093
188513
  try {
188094
- const raw = fs15.readFileSync(workerPidPath(dir), "utf8").trim();
188514
+ const raw = fs16.readFileSync(workerPidPath(dir), "utf8").trim();
188095
188515
  if (!/^\d+$/.test(raw)) return null;
188096
188516
  return parseInt(raw, 10);
188097
188517
  } catch {
@@ -188114,7 +188534,7 @@ function stopWorker(dir = dataDir()) {
188114
188534
  }
188115
188535
  }
188116
188536
  try {
188117
- fs15.rmSync(workerPidPath(dir), { force: true });
188537
+ fs16.rmSync(workerPidPath(dir), { force: true });
188118
188538
  } catch {
188119
188539
  }
188120
188540
  return alive;
@@ -188128,7 +188548,7 @@ var WorkerAlreadyRunningError = class extends Error {
188128
188548
  function claimWorkerPidFile(dir, pid) {
188129
188549
  const pidPath = workerPidPath(dir);
188130
188550
  try {
188131
- fs15.writeFileSync(pidPath, `${pid}
188551
+ fs16.writeFileSync(pidPath, `${pid}
188132
188552
  `, { flag: "wx" });
188133
188553
  return true;
188134
188554
  } catch (e) {
@@ -188139,11 +188559,11 @@ function claimWorkerPidFile(dir, pid) {
188139
188559
  return false;
188140
188560
  }
188141
188561
  try {
188142
- fs15.rmSync(pidPath, { force: true });
188562
+ fs16.rmSync(pidPath, { force: true });
188143
188563
  } catch {
188144
188564
  }
188145
188565
  try {
188146
- fs15.writeFileSync(pidPath, `${pid}
188566
+ fs16.writeFileSync(pidPath, `${pid}
188147
188567
  `, { flag: "wx" });
188148
188568
  return true;
188149
188569
  } catch (e2) {
@@ -188155,9 +188575,9 @@ function startDetachedWorker(opts) {
188155
188575
  const pollIntervalMs = opts?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
188156
188576
  const dir = opts?.dataDir ?? dataDir();
188157
188577
  try {
188158
- fs15.mkdirSync(dir, { recursive: true });
188578
+ fs16.mkdirSync(dir, { recursive: true });
188159
188579
  } catch (e) {
188160
- if (e.code !== "EEXIST" || !fs15.existsSync(dir)) throw e;
188580
+ if (e.code !== "EEXIST" || !fs16.existsSync(dir)) throw e;
188161
188581
  }
188162
188582
  const child = spawn2(
188163
188583
  process.execPath,
@@ -188214,7 +188634,7 @@ function runDetachedWorkerDaemon() {
188214
188634
  process.on("exit", () => {
188215
188635
  if (readPidFile(dir) === process.pid) {
188216
188636
  try {
188217
- fs15.rmSync(workerPidPath(dir), { force: true });
188637
+ fs16.rmSync(workerPidPath(dir), { force: true });
188218
188638
  } catch {
188219
188639
  }
188220
188640
  }
@@ -188246,17 +188666,17 @@ function appendDirtyPath(normalizedPath2) {
188246
188666
  const queuePath = dirtyQueuePath();
188247
188667
  const dir = path21.dirname(queuePath);
188248
188668
  try {
188249
- fs16.mkdirSync(dir, { recursive: true });
188669
+ fs17.mkdirSync(dir, { recursive: true });
188250
188670
  } catch (e) {
188251
- if (e.code !== "EEXIST" || !fs16.existsSync(dir)) throw e;
188671
+ if (e.code !== "EEXIST" || !fs17.existsSync(dir)) throw e;
188252
188672
  }
188253
188673
  let leadingNewline = "";
188254
188674
  try {
188255
- const existing = fs16.readFileSync(queuePath, "utf8");
188675
+ const existing = fs17.readFileSync(queuePath, "utf8");
188256
188676
  if (existing.length > 0 && !existing.endsWith("\n")) leadingNewline = "\n";
188257
188677
  } catch {
188258
188678
  }
188259
- fs16.appendFileSync(queuePath, `${leadingNewline}${normalizedPath2}
188679
+ fs17.appendFileSync(queuePath, `${leadingNewline}${normalizedPath2}
188260
188680
  `);
188261
188681
  resetTransientRetryCount(normalizedPath2);
188262
188682
  }
@@ -188264,7 +188684,7 @@ function getDirtyPaths() {
188264
188684
  const queuePath = dirtyQueuePath();
188265
188685
  let raw;
188266
188686
  try {
188267
- raw = fs16.readFileSync(queuePath, "utf8");
188687
+ raw = fs17.readFileSync(queuePath, "utf8");
188268
188688
  } catch {
188269
188689
  return [];
188270
188690
  }
@@ -188283,7 +188703,7 @@ function preCompactIndexHandler(_event) {
188283
188703
  if (paths.length > 0) {
188284
188704
  const sidecar = path21.join(dataDir(), "queue", "pending.txt");
188285
188705
  try {
188286
- fs16.mkdirSync(path21.dirname(sidecar), { recursive: true });
188706
+ fs17.mkdirSync(path21.dirname(sidecar), { recursive: true });
188287
188707
  atomicWriteBytes(sidecar, Buffer.from(`${paths.join("\n")}
188288
188708
  `, "utf8"));
188289
188709
  } catch {
@@ -188493,7 +188913,7 @@ var HOOK_EVENTS = [
188493
188913
 
188494
188914
  // src/hooks_read.ts
188495
188915
  init_define_import_meta_env();
188496
- import * as fs22 from "node:fs";
188916
+ import * as fs23 from "node:fs";
188497
188917
  import * as path26 from "node:path";
188498
188918
 
188499
188919
  // src/hints.ts
@@ -188849,6 +189269,10 @@ ${headings.join("\n")}` : "",
188849
189269
  }
188850
189270
  function handleTxt(filePath, content, contentLengthHint) {
188851
189271
  if ((contentLengthHint ?? content.length) < FILE_TYPE_THRESHOLDS.txt) return { shouldBlock: false, message: "" };
189272
+ const contentSniff = content.slice(0, 1e3);
189273
+ if (/^\s*<!DOCTYPE\s+html|^\s*<html[\s>]/i.test(contentSniff)) {
189274
+ return handleHtml(filePath, content, contentLengthHint);
189275
+ }
188852
189276
  const lines = content.split("\n");
188853
189277
  const isLog = /\.(log|out|err|trace)$/i.test(filePath) || filePath.includes("/logs/");
188854
189278
  const preview = [
@@ -188970,7 +189394,7 @@ function dispatchFileTypeHandler(filePath, content, contentLengthHint) {
188970
189394
  // src/project.ts
188971
189395
  init_define_import_meta_env();
188972
189396
  import * as crypto3 from "node:crypto";
188973
- import * as fs17 from "node:fs";
189397
+ import * as fs18 from "node:fs";
188974
189398
  import * as os7 from "node:os";
188975
189399
  import * as path22 from "node:path";
188976
189400
  var WSL_PREFIX_RE = /^\/mnt\/([a-zA-Z])\/(.*)$/;
@@ -189018,6 +189442,7 @@ function canonicalize(inputPath, baseDir) {
189018
189442
  if (isWin32) {
189019
189443
  normalized = normalizeShellDrivePrefix(normalized);
189020
189444
  }
189445
+ normalized = expandShortPath(normalized);
189021
189446
  normalized = lowercaseDriveLetter(normalized);
189022
189447
  return normalized;
189023
189448
  }
@@ -189036,7 +189461,7 @@ function makeProjectAt(root) {
189036
189461
  );
189037
189462
  }
189038
189463
  try {
189039
- const stat2 = fs17.statSync(canonical);
189464
+ const stat2 = fs18.statSync(canonical);
189040
189465
  if (!stat2.isDirectory()) {
189041
189466
  throw new Error(`makeProjectAt: path is not a directory: ${canonical}`);
189042
189467
  }
@@ -189052,14 +189477,14 @@ function makeProjectAt(root) {
189052
189477
  function isRepoContainer(pathStr) {
189053
189478
  let nestedRepos = 0;
189054
189479
  try {
189055
- const entries = fs17.readdirSync(pathStr, { withFileTypes: true });
189480
+ const entries = fs18.readdirSync(pathStr, { withFileTypes: true });
189056
189481
  for (const entry of entries) {
189057
189482
  if (entry.isDirectory()) {
189058
189483
  const gitPath = path22.join(pathStr, entry.name, ".git");
189059
- if (fs17.existsSync(gitPath)) {
189484
+ if (fs18.existsSync(gitPath)) {
189060
189485
  let isGitDir = false;
189061
189486
  try {
189062
- isGitDir = fs17.statSync(gitPath).isDirectory();
189487
+ isGitDir = fs18.statSync(gitPath).isDirectory();
189063
189488
  } catch {
189064
189489
  }
189065
189490
  if (isGitDir) {
@@ -189079,14 +189504,14 @@ function isRepoContainer(pathStr) {
189079
189504
  function markerExists(current, marker) {
189080
189505
  const markerPath = path22.join(current, marker);
189081
189506
  try {
189082
- if (!fs17.existsSync(markerPath)) {
189507
+ if (!fs18.existsSync(markerPath)) {
189083
189508
  return false;
189084
189509
  }
189085
- const stat2 = fs17.lstatSync(markerPath);
189510
+ const stat2 = fs18.lstatSync(markerPath);
189086
189511
  if (!stat2.isSymbolicLink()) {
189087
189512
  return true;
189088
189513
  }
189089
- const resolved = fs17.realpathSync(markerPath);
189514
+ const resolved = fs18.realpathSync(markerPath);
189090
189515
  const rel = path22.relative(path22.resolve(current), path22.resolve(resolved));
189091
189516
  return !rel.startsWith("..");
189092
189517
  } catch {
@@ -189133,11 +189558,11 @@ function findProject(cwd) {
189133
189558
 
189134
189559
  // src/skill_cache.ts
189135
189560
  init_define_import_meta_env();
189136
- import * as fs18 from "fs/promises";
189561
+ import * as fs19 from "fs/promises";
189137
189562
  import { createHash as createHash4 } from "crypto";
189138
189563
  import { resolve as resolve7 } from "path";
189139
189564
  import { homedir as homedir7 } from "os";
189140
- import { readdirSync as readdirSync6, readFileSync as readFileSync14, existsSync as existsSync13, statSync as statSync11, unlinkSync as unlinkSync7 } from "node:fs";
189565
+ import { readdirSync as readdirSync7, readFileSync as readFileSync14, existsSync as existsSync13, statSync as statSync11, unlinkSync as unlinkSync7 } from "node:fs";
189141
189566
  var COMPACT_END_MARKER = "<!-- COMPACT_END -->";
189142
189567
  var SKILLS_OUTPUT_SUBDIR = "skills";
189143
189568
  var _skillOutputsDirOverride = null;
@@ -189156,7 +189581,7 @@ function skillsSourceDir() {
189156
189581
  }
189157
189582
  async function ensureSkillsDir() {
189158
189583
  try {
189159
- await fs18.mkdir(skillOutputsDir(), { recursive: true });
189584
+ await fs19.mkdir(skillOutputsDir(), { recursive: true });
189160
189585
  } catch {
189161
189586
  }
189162
189587
  }
@@ -189264,14 +189689,14 @@ function extractNamedSection(body, heading) {
189264
189689
  async function listOutputs() {
189265
189690
  try {
189266
189691
  const dir = skillOutputsDir();
189267
- const entries = await fs18.readdir(dir, { withFileTypes: true });
189692
+ const entries = await fs19.readdir(dir, { withFileTypes: true });
189268
189693
  const metas = [];
189269
189694
  for (const entry of entries) {
189270
189695
  if (!entry.isFile() || !entry.name.endsWith(".meta")) {
189271
189696
  continue;
189272
189697
  }
189273
189698
  try {
189274
- const content = await fs18.readFile(resolve7(dir, entry.name), "utf-8");
189699
+ const content = await fs19.readFile(resolve7(dir, entry.name), "utf-8");
189275
189700
  const meta3 = JSON.parse(content);
189276
189701
  metas.push(meta3);
189277
189702
  } catch {
@@ -189308,8 +189733,8 @@ async function findCrossSessionEntry(skillName, contentSha) {
189308
189733
  const bodyPath = resolve7(dir, `${meta3.outputId}.txt`);
189309
189734
  const gzPath = resolve7(dir, `${meta3.outputId}.gz`);
189310
189735
  try {
189311
- const bodyExists = await fs18.access(bodyPath).then(() => true).catch(() => false);
189312
- const gzExists = await fs18.access(gzPath).then(() => true).catch(() => false);
189736
+ const bodyExists = await fs19.access(bodyPath).then(() => true).catch(() => false);
189737
+ const gzExists = await fs19.access(gzPath).then(() => true).catch(() => false);
189313
189738
  if (bodyExists || gzExists) {
189314
189739
  return meta3;
189315
189740
  }
@@ -189401,7 +189826,7 @@ function getCompactAnySessionSync(skillName) {
189401
189826
  const name2 = safeSkillName(skillName);
189402
189827
  if (!name2) return null;
189403
189828
  const dir = skillOutputsDir();
189404
- const entries = readdirSync6(dir, { withFileTypes: true });
189829
+ const entries = readdirSync7(dir, { withFileTypes: true });
189405
189830
  const suffix = `@${sanitizeSkillId(name2)}@compact`;
189406
189831
  for (const entry of entries) {
189407
189832
  if (!entry.isFile() || !entry.name.endsWith("@compact")) continue;
@@ -189436,7 +189861,7 @@ async function readSkillHits(skillName) {
189436
189861
  if (!name2) return { count: 0, lastTs: 0 };
189437
189862
  const dir = skillOutputsDir();
189438
189863
  const hitsFile = resolve7(dir, `${sanitizeSkillId(name2)}.hits`);
189439
- const content = await fs18.readFile(hitsFile, "utf-8").catch(() => null);
189864
+ const content = await fs19.readFile(hitsFile, "utf-8").catch(() => null);
189440
189865
  if (content) {
189441
189866
  const parsed = JSON.parse(content);
189442
189867
  return parsed;
@@ -189451,14 +189876,14 @@ var SKILL_HIT_LOCK_STALE_MS = 5e3;
189451
189876
  async function acquireSkillHitLock(lockPath) {
189452
189877
  for (let attempt = 0; attempt < SKILL_HIT_LOCK_MAX_ATTEMPTS; attempt++) {
189453
189878
  try {
189454
- await fs18.mkdir(lockPath);
189879
+ await fs19.mkdir(lockPath);
189455
189880
  return true;
189456
189881
  } catch (err3) {
189457
189882
  if (err3.code !== "EEXIST") return false;
189458
189883
  try {
189459
- const st = await fs18.stat(lockPath);
189884
+ const st = await fs19.stat(lockPath);
189460
189885
  if (Date.now() - st.mtimeMs > SKILL_HIT_LOCK_STALE_MS) {
189461
- await fs18.rmdir(lockPath).catch(() => {
189886
+ await fs19.rmdir(lockPath).catch(() => {
189462
189887
  });
189463
189888
  continue;
189464
189889
  }
@@ -189485,7 +189910,7 @@ async function incrementSkillHit(skillName) {
189485
189910
  hits.lastTs = Date.now();
189486
189911
  await atomicWriteText(hitsFile, JSON.stringify(hits, null, 2));
189487
189912
  } finally {
189488
- if (locked) await fs18.rmdir(lockPath).catch(() => {
189913
+ if (locked) await fs19.rmdir(lockPath).catch(() => {
189489
189914
  });
189490
189915
  }
189491
189916
  } catch {
@@ -189520,14 +189945,14 @@ async function listSkills(sessionId) {
189520
189945
  let compactLen = 0;
189521
189946
  let compactText = "";
189522
189947
  try {
189523
- const stat2 = await fs18.stat(resolve7(dir, compactFileId));
189948
+ const stat2 = await fs19.stat(resolve7(dir, compactFileId));
189524
189949
  compactLen = stat2.size;
189525
- compactText = await fs18.readFile(resolve7(dir, compactFileId), "utf-8").catch(() => "");
189950
+ compactText = await fs19.readFile(resolve7(dir, compactFileId), "utf-8").catch(() => "");
189526
189951
  } catch {
189527
189952
  compactLen = 0;
189528
189953
  }
189529
189954
  const hasMarker = extractCompactFromMarker(
189530
- await fs18.readFile(resolve7(dir, `${meta3.outputId}.txt`), "utf-8").catch(() => "")
189955
+ await fs19.readFile(resolve7(dir, `${meta3.outputId}.txt`), "utf-8").catch(() => "")
189531
189956
  ) !== null;
189532
189957
  const compactStale = isCompactStale(compactText, meta3.skillName, meta3.contentSha);
189533
189958
  const { count: hitCount } = await readSkillHits(meta3.skillName);
@@ -189567,7 +189992,7 @@ async function installedSkillPath(skillName) {
189567
189992
  if (!name2) return null;
189568
189993
  const diskPath = resolve7(skillsSourceDir(), name2, "SKILL.md");
189569
189994
  try {
189570
- await fs18.access(diskPath);
189995
+ await fs19.access(diskPath);
189571
189996
  return diskPath;
189572
189997
  } catch {
189573
189998
  return null;
@@ -189580,7 +190005,7 @@ function pruneSkillOutputs(maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_
189580
190005
  if (!existsSync13(dir)) return 0;
189581
190006
  const cutoff = Date.now() - maxAgeMs;
189582
190007
  const entries = [];
189583
- for (const file2 of readdirSync6(dir)) {
190008
+ for (const file2 of readdirSync7(dir)) {
189584
190009
  if (!file2.endsWith(".meta")) continue;
189585
190010
  const outputId = file2.slice(0, -".meta".length);
189586
190011
  let ts;
@@ -189627,7 +190052,7 @@ function pruneSkillOutputs(maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_
189627
190052
 
189628
190053
  // src/image_shrink.ts
189629
190054
  init_define_import_meta_env();
189630
- import * as fs19 from "node:fs";
190055
+ import * as fs20 from "node:fs";
189631
190056
  import * as path23 from "node:path";
189632
190057
  var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
189633
190058
  ".png",
@@ -189695,7 +190120,7 @@ async function shrinkImage(input, opts) {
189695
190120
  }
189696
190121
  function statSize(absPath) {
189697
190122
  try {
189698
- const st = fs19.statSync(absPath);
190123
+ const st = fs20.statSync(absPath);
189699
190124
  return st.isFile() ? st.size : null;
189700
190125
  } catch {
189701
190126
  return null;
@@ -189709,7 +190134,7 @@ async function preReadImageHandler(event) {
189709
190134
  if (size === null || size < DEFAULT_SIZE_THRESHOLD_BYTES) return passOutput();
189710
190135
  let input;
189711
190136
  try {
189712
- input = fs19.readFileSync(filePath);
190137
+ input = fs20.readFileSync(filePath);
189713
190138
  } catch {
189714
190139
  return passOutput();
189715
190140
  }
@@ -189726,7 +190151,7 @@ registerHook("pre_tool_use", preReadImageHandler, { toolName: "Read" });
189726
190151
 
189727
190152
  // src/doc_compact.ts
189728
190153
  init_define_import_meta_env();
189729
- import * as fs20 from "fs";
190154
+ import * as fs21 from "fs";
189730
190155
  import * as crypto4 from "crypto";
189731
190156
  import * as path24 from "path";
189732
190157
  var defaultSentencesPerSection = 2;
@@ -189735,7 +190160,7 @@ var headerRegex = /^<!-- token-goat doc-compact source-hash:(\S+) source:(.+?) -
189735
190160
  var compactSubdir = "doc_compacts";
189736
190161
  function sourceHash(filePath) {
189737
190162
  try {
189738
- const data = fs20.readFileSync(filePath);
190163
+ const data = fs21.readFileSync(filePath);
189739
190164
  return crypto4.createHash("sha256").update(data).digest("hex");
189740
190165
  } catch {
189741
190166
  return "";
@@ -189749,12 +190174,12 @@ function _compactSlug(absPathStr) {
189749
190174
  return `${h}_${safeStem}`;
189750
190175
  }
189751
190176
  function compactPathFor(sourcePath) {
189752
- const abs = path24.resolve(sourcePath);
190177
+ const abs = normalizePath(path24.resolve(sourcePath));
189753
190178
  return path24.join(dataDir(), compactSubdir, `${_compactSlug(abs)}.md`);
189754
190179
  }
189755
190180
  function readCompactHeader(compactPath) {
189756
190181
  try {
189757
- const text = fs20.readFileSync(compactPath, "utf-8");
190182
+ const text = fs21.readFileSync(compactPath, "utf-8");
189758
190183
  const firstLine = text.split("\n")[0] || "";
189759
190184
  const m = firstLine.match(headerRegex);
189760
190185
  if (!m || !m[1] || !m[2]) return null;
@@ -189773,8 +190198,8 @@ function isCompactFresh(compactPath, sourcePath) {
189773
190198
  }
189774
190199
  function markCompactStale(compactPath) {
189775
190200
  try {
189776
- if (!fs20.existsSync(compactPath)) return false;
189777
- const text = fs20.readFileSync(compactPath, "utf-8");
190201
+ if (!fs21.existsSync(compactPath)) return false;
190202
+ const text = fs21.readFileSync(compactPath, "utf-8");
189778
190203
  const lines = text.split("\n");
189779
190204
  if (!lines[0]) return false;
189780
190205
  const m = lines[0].match(headerRegex);
@@ -189789,7 +190214,7 @@ function markCompactStale(compactPath) {
189789
190214
  }
189790
190215
  function readCompactBody(compactPath) {
189791
190216
  try {
189792
- const text = fs20.readFileSync(compactPath, "utf-8");
190217
+ const text = fs21.readFileSync(compactPath, "utf-8");
189793
190218
  const lines = text.split("\n");
189794
190219
  if (lines.length < 2) return null;
189795
190220
  const body = lines.slice(1).join("\n").trimStart();
@@ -189806,8 +190231,8 @@ function writeCompact(compactPath, sourcePath, compactBody, sourceRel) {
189806
190231
  `;
189807
190232
  const fullText = header + compactBody.trimStart();
189808
190233
  const dir = path24.dirname(compactPath);
189809
- if (!fs20.existsSync(dir)) {
189810
- fs20.mkdirSync(dir, { recursive: true });
190234
+ if (!fs21.existsSync(dir)) {
190235
+ fs21.mkdirSync(dir, { recursive: true });
189811
190236
  }
189812
190237
  atomicWriteText(compactPath, fullText);
189813
190238
  }
@@ -189918,7 +190343,7 @@ function extractDocCompact(body, heading) {
189918
190343
  }
189919
190344
  function compactDoc(filePath, heading) {
189920
190345
  try {
189921
- const body = fs20.readFileSync(filePath, "utf-8");
190346
+ const body = fs21.readFileSync(filePath, "utf-8");
189922
190347
  const compact = extractDocCompact(body, heading);
189923
190348
  return compact || null;
189924
190349
  } catch {
@@ -189928,7 +190353,7 @@ function compactDoc(filePath, heading) {
189928
190353
 
189929
190354
  // src/notebook_compact.ts
189930
190355
  init_define_import_meta_env();
189931
- import * as fs21 from "node:fs";
190356
+ import * as fs22 from "node:fs";
189932
190357
  import * as path25 from "node:path";
189933
190358
  import * as crypto5 from "node:crypto";
189934
190359
  var NB_STRIP_MIN_SAVINGS = 4096;
@@ -189953,20 +190378,20 @@ function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs
189953
190378
  const nbStripDir = path25.join(cacheRoot, "nb_strip");
189954
190379
  let removed = 0;
189955
190380
  try {
189956
- if (!fs21.existsSync(nbStripDir)) return 0;
190381
+ if (!fs22.existsSync(nbStripDir)) return 0;
189957
190382
  const cutoff = Date.now() - maxAgeMs;
189958
190383
  const kept = [];
189959
- for (const entry of fs21.readdirSync(nbStripDir)) {
190384
+ for (const entry of fs22.readdirSync(nbStripDir)) {
189960
190385
  const dir = path25.join(nbStripDir, entry);
189961
190386
  let mtime;
189962
190387
  try {
189963
- mtime = fs21.statSync(dir).mtimeMs;
190388
+ mtime = fs22.statSync(dir).mtimeMs;
189964
190389
  } catch {
189965
190390
  continue;
189966
190391
  }
189967
190392
  if (mtime < cutoff) {
189968
190393
  try {
189969
- fs21.rmSync(dir, { recursive: true, force: true });
190394
+ fs22.rmSync(dir, { recursive: true, force: true });
189970
190395
  removed++;
189971
190396
  } catch {
189972
190397
  continue;
@@ -189979,7 +190404,7 @@ function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs
189979
190404
  kept.sort((a, b) => a[1] - b[1]);
189980
190405
  for (const [dir] of kept.slice(0, kept.length - maxCount)) {
189981
190406
  try {
189982
- fs21.rmSync(dir, { recursive: true, force: true });
190407
+ fs22.rmSync(dir, { recursive: true, force: true });
189983
190408
  removed++;
189984
190409
  } catch {
189985
190410
  continue;
@@ -189995,7 +190420,7 @@ function getOrCreateSidecar(rawBytes, cacheRoot, opts = {}) {
189995
190420
  const sha = crypto5.createHash("sha256").update(rawBytes).digest("hex");
189996
190421
  const sidecarDir = path25.join(cacheRoot, "nb_strip", sha);
189997
190422
  const sidecarPath = path25.join(sidecarDir, "stripped.ipynb");
189998
- if (fs21.existsSync(sidecarPath)) {
190423
+ if (fs22.existsSync(sidecarPath)) {
189999
190424
  return [sidecarPath, false];
190000
190425
  }
190001
190426
  let nb;
@@ -190010,9 +190435,9 @@ function getOrCreateSidecar(rawBytes, cacheRoot, opts = {}) {
190010
190435
  const nbDict = nb;
190011
190436
  const stripped = stripNotebook(nbDict);
190012
190437
  try {
190013
- fs21.mkdirSync(sidecarDir, { recursive: true });
190438
+ fs22.mkdirSync(sidecarDir, { recursive: true });
190014
190439
  } catch (err3) {
190015
- if (!fs21.existsSync(sidecarDir)) {
190440
+ if (!fs22.existsSync(sidecarDir)) {
190016
190441
  throw err3;
190017
190442
  }
190018
190443
  }
@@ -190029,6 +190454,7 @@ function isTsConfigFile(basename17) {
190029
190454
  }
190030
190455
  var LARGE_FILE_BYTES = FILE_TYPE_THRESHOLDS.generic;
190031
190456
  var REREAD_DENY_BYTES = 50 * 1024;
190457
+ var TASK_OUTPUT_DENY_BYTES = 20 * 1024;
190032
190458
  var DENY_THRESHOLD_TIER_MULTIPLIERS = {
190033
190459
  cool: 1,
190034
190460
  warm: 0.67,
@@ -190058,7 +190484,7 @@ function sessionArtifactRecall(filePath) {
190058
190484
  }
190059
190485
  function statSize2(absPath) {
190060
190486
  try {
190061
- return fs22.statSync(absPath).size;
190487
+ return fs23.statSync(absPath).size;
190062
190488
  } catch {
190063
190489
  return null;
190064
190490
  }
@@ -190078,7 +190504,7 @@ function scanRequestedSlice(absPath, offset, limit) {
190078
190504
  const windowEnd = offset + limit;
190079
190505
  let fd2;
190080
190506
  try {
190081
- fd2 = fs22.openSync(absPath, "r");
190507
+ fd2 = fs23.openSync(absPath, "r");
190082
190508
  } catch {
190083
190509
  return null;
190084
190510
  }
@@ -190092,7 +190518,7 @@ function scanRequestedSlice(absPath, offset, limit) {
190092
190518
  const nearSingleLine = lineNumber < NEAR_SINGLE_LINE_SCAN_THRESHOLD;
190093
190519
  return { bytes: sliceBytes, trustworthy: nearSingleLine, nearSingleLine };
190094
190520
  }
190095
- const bytesRead = fs22.readSync(fd2, buf, 0, buf.length, null);
190521
+ const bytesRead = fs23.readSync(fd2, buf, 0, buf.length, null);
190096
190522
  if (bytesRead === 0) {
190097
190523
  return {
190098
190524
  bytes: sliceBytes,
@@ -190111,7 +190537,7 @@ function scanRequestedSlice(absPath, offset, limit) {
190111
190537
  }
190112
190538
  } finally {
190113
190539
  try {
190114
- fs22.closeSync(fd2);
190540
+ fs23.closeSync(fd2);
190115
190541
  } catch {
190116
190542
  }
190117
190543
  }
@@ -190269,7 +190695,7 @@ function preReadHandler(event) {
190269
190695
  const skillName = detectSkillFile(normalized);
190270
190696
  if (skillName && basename17 === "SKILL.md") {
190271
190697
  try {
190272
- const body = fs22.readFileSync(normalized, "utf-8");
190698
+ const body = fs23.readFileSync(normalized, "utf-8");
190273
190699
  const bodySha = contentHash(body);
190274
190700
  const compact = getCompactAnySessionSync(skillName);
190275
190701
  const stale = isCompactStale(compact, skillName, bodySha);
@@ -190292,7 +190718,7 @@ function preReadHandler(event) {
190292
190718
  const savedBytes = Math.max(0, fullSize - compactBody.length);
190293
190719
  recordStat("session_hint", savedBytes, Math.round(savedBytes / 4));
190294
190720
  return denyOutput(
190295
- "Serving the extractive compact sidecar in place of the full file (source unchanged since the last `compact-doc` build):\n\n" + compactBody + '\n\nUse `token-goat compact-doc "' + normalized + '" --force` to rebuild it, or `token-goat compact-doc "' + normalized + '" --show` to view it directly. To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190721
+ "Serving the extractive compact sidecar in place of the full file (source unchanged since the last `compact-doc` build):\n\n" + compactBody + '\n\nUse `token-goat compact-doc "' + normalized + '" --force` to rebuild it, or `token-goat compact-doc "' + normalized + '" --show` to view it directly. To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190296
190722
  );
190297
190723
  }
190298
190724
  }
@@ -190300,15 +190726,15 @@ function preReadHandler(event) {
190300
190726
  const isNotebook = /\.ipynb$/i.test(basename17);
190301
190727
  if (isNotebook) {
190302
190728
  try {
190303
- const rawBytes = fs22.readFileSync(normalized);
190729
+ const rawBytes = fs23.readFileSync(normalized);
190304
190730
  const [sidecarPath] = getOrCreateSidecar(rawBytes, dataDir());
190305
- const sidecarContent = fs22.readFileSync(sidecarPath, "utf-8");
190731
+ const sidecarContent = fs23.readFileSync(sidecarPath, "utf-8");
190306
190732
  const savedBytes = rawBytes.length - sidecarContent.length;
190307
190733
  if (savedBytes >= NB_STRIP_MIN_SAVINGS) {
190308
190734
  recordActualRead(event, normalized);
190309
190735
  recordStat("session_hint", savedBytes, Math.round(savedBytes / 4));
190310
190736
  return denyOutput(
190311
- "Serving the output-stripped notebook in place of the full file (code-cell outputs and execution counts removed; source and metadata preserved):\n\n" + sidecarContent + '\n\nTo edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190737
+ "Serving the output-stripped notebook in place of the full file (code-cell outputs and execution counts removed; source and metadata preserved):\n\n" + sidecarContent + '\n\nTo edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190312
190738
  );
190313
190739
  }
190314
190740
  } catch {
@@ -190322,7 +190748,7 @@ function preReadHandler(event) {
190322
190748
  const sz = statSize2(normalized);
190323
190749
  if (sz !== null && sz >= MARKDOWN_SIZE_THRESHOLD) {
190324
190750
  markdownSize = sz;
190325
- fileContent = fs22.readFileSync(normalized, "utf8");
190751
+ fileContent = fs23.readFileSync(normalized, "utf8");
190326
190752
  }
190327
190753
  } catch {
190328
190754
  }
@@ -190330,7 +190756,6 @@ function preReadHandler(event) {
190330
190756
  const headings = extractMarkdownHeadings(fileContent);
190331
190757
  if (headings.length >= 3) {
190332
190758
  const alreadyRead = wasFileReadThisSession(normalized);
190333
- recordActualRead(event, normalized);
190334
190759
  const hintText = formatHeadingTree(headings, normalized);
190335
190760
  const wellKnown = getWellKnownSections(basename17);
190336
190761
  const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' + normalized + "::" + s + '"').join(" | ") : "";
@@ -190338,9 +190763,13 @@ function preReadHandler(event) {
190338
190763
  let message = hintText + wellKnownText + changelogExtra;
190339
190764
  const tooLargeForFirstRead = markdownSize !== null && markdownSize >= largeFileDenyBytes();
190340
190765
  if (alreadyRead || tooLargeForFirstRead) {
190341
- message += ' To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny.";
190766
+ if (alreadyRead) {
190767
+ recordActualRead(event, normalized);
190768
+ }
190769
+ message += ' To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny.";
190342
190770
  return denyOutput(message);
190343
190771
  }
190772
+ recordActualRead(event, normalized);
190344
190773
  return contextOutput(message);
190345
190774
  }
190346
190775
  }
@@ -190383,7 +190812,7 @@ function preReadHandler(event) {
190383
190812
  try {
190384
190813
  const sz = statSize2(normalized);
190385
190814
  if (sz !== null && sz <= 256 * 1024) {
190386
- const currentContent = fs22.readFileSync(normalized, "utf8");
190815
+ const currentContent = fs23.readFileSync(normalized, "utf8");
190387
190816
  const TRUNC_MARKER = "\n<snapshot truncated at ";
190388
190817
  const oldRaw = oldArtifactSnap.toString("utf8");
190389
190818
  const truncIdx = oldRaw.indexOf(TRUNC_MARKER);
@@ -190415,7 +190844,14 @@ function preReadHandler(event) {
190415
190844
  );
190416
190845
  }
190417
190846
  if (/[/\\]tasks[/\\][a-z0-9]+\.output$/i.test(normalized)) {
190847
+ const outputSize = statSize2(normalized);
190418
190848
  recordActualRead(event, normalized);
190849
+ if (outputSize !== null && outputSize >= TASK_OUTPUT_DENY_BYTES) {
190850
+ recordStat("session_hint", outputSize, Math.round(outputSize / 4));
190851
+ return denyOutput(
190852
+ "Session transcript is large (" + Math.round(outputSize / 1024) + "KB). " + sessionArtifactRecall(normalized)
190853
+ );
190854
+ }
190419
190855
  return contextOutput("Session transcript: " + sessionArtifactRecall(normalized));
190420
190856
  }
190421
190857
  }
@@ -190426,7 +190862,7 @@ function preReadHandler(event) {
190426
190862
  recordActualRead(event, normalized);
190427
190863
  recordStat("session_hint", 0, 0);
190428
190864
  return denyOutput(
190429
- 'File was truncated on last read (>33K tokens). Use `token-goat skeleton "' + normalized + '"` for structure or `token-goat read "' + normalized + '::SymbolName"` for one function. To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190865
+ 'File was truncated on last read (>33K tokens). Use `token-goat skeleton "' + normalized + '"` for structure or `token-goat read "' + normalized + '::SymbolName"` for one function. To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190430
190866
  );
190431
190867
  }
190432
190868
  const sessionId = getSessionId();
@@ -190435,7 +190871,7 @@ function preReadHandler(event) {
190435
190871
  try {
190436
190872
  const sz = statSize2(normalized);
190437
190873
  if (sz !== null && sz <= 256 * 1024) {
190438
- const currentContent = fs22.readFileSync(normalized, "utf8");
190874
+ const currentContent = fs23.readFileSync(normalized, "utf8");
190439
190875
  const TRUNC_MARKER = "\n<snapshot truncated at ";
190440
190876
  const oldRaw = oldSnap.toString("utf8");
190441
190877
  const truncIdx = oldRaw.indexOf(TRUNC_MARKER);
@@ -190501,25 +190937,25 @@ function preReadHandler(event) {
190501
190937
  }
190502
190938
  if (wasFileTruncatedThisSession(normalized)) {
190503
190939
  return denyOutput(
190504
- 'File was truncated on last read (>33K tokens). Use `token-goat skeleton "' + normalized + '"` for structure or `token-goat read "' + normalized + '::SymbolName"` for one function. To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190940
+ 'File was truncated on last read (>33K tokens). Use `token-goat skeleton "' + normalized + '"` for structure or `token-goat read "' + normalized + '::SymbolName"` for one function. To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190505
190941
  );
190506
190942
  }
190507
190943
  if (/\.(md|mdx|markdown|rst)$/i.test(basename17)) {
190508
190944
  return denyOutput(
190509
- 'Markdown file already read this session. Use `token-goat section "' + normalized + '::HeadingName"` to read one section. To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190945
+ 'Markdown file already read this session. Use `token-goat section "' + normalized + '::HeadingName"` to read one section. To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190510
190946
  );
190511
190947
  }
190512
190948
  const isSourceExt = isSourceExtension(basename17);
190513
190949
  if (isSourceExt && reads >= 2) {
190514
190950
  recordStat("read_count_deny", rereadBytes, Math.round(rereadBytes / 4));
190515
190951
  return denyOutput(
190516
- "Read this file " + reads + ' times already \u2014 use `token-goat read "' + normalized + '::Symbol"`, `token-goat skeleton ' + normalized + "`, or `token-goat outline " + normalized + '` to pull just the part you need. To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190952
+ "Read this file " + reads + ' times already \u2014 use `token-goat read "' + normalized + '::Symbol"`, `token-goat skeleton ' + normalized + "`, or `token-goat outline " + normalized + '` to pull just the part you need. To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190517
190953
  );
190518
190954
  }
190519
190955
  const hint = _isDocFile(normalized) ? 'Use `token-goat section "' + normalized + '::SectionName"` to read one section.' : "Use token-goat read/section/symbol to re-read surgically.";
190520
190956
  if (rereadBytes >= REREAD_DENY_BYTES || reads >= 2) {
190521
190957
  return denyOutput(
190522
- normalized + " was already read this session (" + reads + " " + plural2 + "). " + hint + ' To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190958
+ normalized + " was already read this session (" + reads + " " + plural2 + "). " + hint + ' To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190523
190959
  );
190524
190960
  }
190525
190961
  return contextOutput(
@@ -190540,7 +190976,7 @@ function preReadHandler(event) {
190540
190976
  recordStat("session_hint", size, Math.round(size / 4));
190541
190977
  if (gateSize >= largeFileDenyBytes()) {
190542
190978
  return denyOutput(
190543
- normalized + " is very large (" + kb + "KB). " + hint + " " + describeSliceAdvice(slice, normalized) + ' To edit it anyway, use `token-goat replace "' + normalized + "\" --old-from <oldfile> --new-from <newfile>` \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190979
+ normalized + " is very large (" + kb + "KB). " + hint + " " + describeSliceAdvice(slice, normalized) + ' To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny."
190544
190980
  );
190545
190981
  }
190546
190982
  recordActualRead(event, normalized);
@@ -190558,7 +190994,7 @@ function preReadHandler(event) {
190558
190994
  let ftContent = "";
190559
190995
  if (!BINARY_FILE_TYPE_EXTS.has(fileTypeExt)) {
190560
190996
  try {
190561
- ftContent = fs22.readFileSync(normalized, "utf8");
190997
+ ftContent = fs23.readFileSync(normalized, "utf8");
190562
190998
  } catch {
190563
190999
  }
190564
191000
  }
@@ -190605,7 +191041,7 @@ function postReadHandler(event) {
190605
191041
  try {
190606
191042
  const sz = statSize2(normalized);
190607
191043
  if (sz !== null && sz <= 256 * 1024) {
190608
- const content = fs22.readFileSync(normalized);
191044
+ const content = fs23.readFileSync(normalized);
190609
191045
  store(getSessionId(), normalized, content);
190610
191046
  }
190611
191047
  } catch {
@@ -190637,7 +191073,7 @@ function postReadHandler(event) {
190637
191073
  try {
190638
191074
  const sz = statSize2(normalized);
190639
191075
  if (sz !== null && sz <= SLICE_ESTIMATE_SCAN_CAP_BYTES) {
190640
- const lineCount = countTextLines(fs22.readFileSync(normalized, "utf8"));
191076
+ const lineCount = countTextLines(fs23.readFileSync(normalized, "utf8"));
190641
191077
  const minLines = loadConfig().post_read_code_compress.min_lines;
190642
191078
  if (lineCount >= minLines) {
190643
191079
  recordStat("session_hint", sz, Math.round(sz / 4));
@@ -190691,8 +191127,31 @@ function renderReadRow(entry) {
190691
191127
  const edited = entry.wasEdited ? ", edited" : "";
190692
191128
  return `- ${entry.path} (${kb}kb, ${entry.readCount} ${plural2}${edited})`;
190693
191129
  }
190694
- function buildManifest2() {
190695
- const files = [...getSessionFiles().values()];
191130
+ function mergeManifestFiles(parent, siblingFiles) {
191131
+ const byPath = /* @__PURE__ */ new Map();
191132
+ for (const f of parent) byPath.set(foldPath(f.path), f);
191133
+ for (const f of siblingFiles) {
191134
+ const key = foldPath(f.path);
191135
+ const prev = byPath.get(key);
191136
+ if (prev === void 0) {
191137
+ byPath.set(key, f);
191138
+ continue;
191139
+ }
191140
+ byPath.set(key, {
191141
+ path: prev.path,
191142
+ readCount: Math.max(prev.readCount, f.readCount),
191143
+ lastReadAt: Math.max(prev.lastReadAt, f.lastReadAt),
191144
+ wasEdited: prev.wasEdited || f.wasEdited,
191145
+ sizeBytes: f.lastReadAt >= prev.lastReadAt ? f.sizeBytes : prev.sizeBytes,
191146
+ ...prev.wasTruncated || f.wasTruncated ? { wasTruncated: true } : {}
191147
+ });
191148
+ }
191149
+ return Array.from(byPath.values());
191150
+ }
191151
+ function buildManifest2(sessionId) {
191152
+ const ownFiles = [...getSessionFiles().values()];
191153
+ const siblingFiles = sessionId !== void 0 ? listSiblingSessionStates(sessionId).flatMap((s) => s.files) : [];
191154
+ const files = siblingFiles.length > 0 ? mergeManifestFiles(ownFiles, siblingFiles) : ownFiles;
190696
191155
  const editedFiles = files.filter((f) => f.wasEdited);
190697
191156
  const readFiles = files.filter((f) => f.readCount > 0 && !f.wasEdited);
190698
191157
  const webFetches = [...getSessionWebFetches().entries()];
@@ -190736,8 +191195,8 @@ function buildManifest2() {
190736
191195
  }
190737
191196
  return lines.join("\n");
190738
191197
  }
190739
- function preCompactHandler(_event) {
190740
- return contextOutput(buildManifest2());
191198
+ function preCompactHandler(event) {
191199
+ return contextOutput(buildManifest2(event.sessionId));
190741
191200
  }
190742
191201
  registerHook("pre_compact", preCompactHandler);
190743
191202
 
@@ -190817,7 +191276,7 @@ init_define_import_meta_env();
190817
191276
 
190818
191277
  // src/web_cache.ts
190819
191278
  init_define_import_meta_env();
190820
- import fs23 from "fs";
191279
+ import fs24 from "fs";
190821
191280
  var WEB_OUTPUT_SUBDIR = "web_outputs";
190822
191281
  var _byId = /* @__PURE__ */ new Map();
190823
191282
  var _urlIndex = /* @__PURE__ */ new Map();
@@ -190843,8 +191302,8 @@ function getWebOutput(cacheId) {
190843
191302
  const p = blobPath(WEB_OUTPUT_SUBDIR, cacheId);
190844
191303
  if (p !== null) {
190845
191304
  try {
190846
- if (fs23.existsSync(p)) {
190847
- const stat2 = fs23.statSync(p);
191305
+ if (fs24.existsSync(p)) {
191306
+ const stat2 = fs24.statSync(p);
190848
191307
  const ageMs = Date.now() - stat2.mtimeMs;
190849
191308
  if (ageMs > DEFAULT_MAX_AGE_MS) {
190850
191309
  return null;
@@ -191361,11 +191820,11 @@ function toRegExp(r, i) {
191361
191820
  if (r.str.length === 0) {
191362
191821
  throw new Error(`Rule #${i} ("${r.name}") has empty "str" property, which is not allowed.`);
191363
191822
  }
191364
- return new RegExp(escapeRegExp(r.str), "y");
191823
+ return new RegExp(escapeRegExp2(r.str), "y");
191365
191824
  }
191366
- return new RegExp(escapeRegExp(r.name), "y");
191825
+ return new RegExp(escapeRegExp2(r.name), "y");
191367
191826
  }
191368
- function escapeRegExp(str) {
191827
+ function escapeRegExp2(str) {
191369
191828
  return str.replace(/[-[\]{}()*+!<=:?./\\^$|#\s,]/g, "\\$&");
191370
191829
  }
191371
191830
  function toSticky(re) {
@@ -197002,7 +197461,6 @@ var _byId2 = /* @__PURE__ */ new Map();
197002
197461
  var COMMAND_PATTERNS = {
197003
197462
  gitMutable: /^\s*git\s+(diff|status)\b/i,
197004
197463
  gitImmutable: /^\s*git\s+show\s+[0-9a-f]{40}\b/i,
197005
- gitDiffUnscoped: /^\s*git\s+diff\b/i,
197006
197464
  gitDiffScoped: /\s--\s+\S/,
197007
197465
  dirListing: /^\s*(?:ls|eza|exa|dir|Get-ChildItem|gci)\b/i,
197008
197466
  depList: /^\s*(?:npm\s+(?:-\S+\s+)*(?:ls|list)\b|pip\s+(?:-\S+\s+)*(?:list|freeze)\b|uv\s+pip\s+(?:-\S+\s+)*(?:list|freeze)\b|pnpm\s+(?:-\S+\s+)*(?:list|ls)\b|yarn\s+(?:-\S+\s+)*(?:list)\b|cargo\s+(?:-\S+\s+)*tree\b|bundle\s+(?:-\S+\s+)*(?:list|show)\b|composer\s+(?:-\S+\s+)*show\b)/i,
@@ -197040,6 +197498,12 @@ var isTestRunnerCommand = (cmd) => isCommandOfType(cmd, "testRunner");
197040
197498
  var isLintCommand = (cmd) => isCommandOfType(cmd, "lintCommand");
197041
197499
  var isNpmRunScriptCommand = (cmd) => isCommandOfType(cmd, "npmRunScript");
197042
197500
  var isCatCommand = (cmd) => isCommandOfType(cmd, "catCommand");
197501
+ function isScopedGitStatusOrDiffStatCommand(cmd) {
197502
+ if (!isCommandOfType(cmd, "gitMutable")) return false;
197503
+ if (!isCommandOfType(cmd, "gitDiffScoped")) return false;
197504
+ if (/^\s*git\s+diff\b/i.test(cmd) && !/--stat\b/.test(cmd)) return false;
197505
+ return true;
197506
+ }
197043
197507
  function gitStateFingerprintSync(cwd) {
197044
197508
  try {
197045
197509
  const headResult = runGit(["rev-parse", "HEAD"], { cwd });
@@ -197161,7 +197625,7 @@ async function commandHash(command2, cwd = null) {
197161
197625
  }
197162
197626
  function computeBashFingerprints(command2, cwd) {
197163
197627
  const fingerprints = {};
197164
- if (cwd && (isGitMutableCommand(command2) || isGitPushCommand(command2) || isTestRunnerCommand(command2) || isLintCommand(command2) || isNpmRunScriptCommand(command2))) {
197628
+ if (cwd && (isGitMutableCommand(command2) || isGitPushCommand(command2) || isTestRunnerCommand(command2) || isLintCommand(command2) || isBuildCommand(command2) || isNpmRunScriptCommand(command2))) {
197165
197629
  const fp = gitStateFingerprintSync(cwd);
197166
197630
  if (fp) fingerprints.git = fp;
197167
197631
  }
@@ -210628,12 +211092,12 @@ function filterByName(name2) {
210628
211092
 
210629
211093
  // src/shell.ts
210630
211094
  init_define_import_meta_env();
210631
- import * as fs24 from "node:fs";
211095
+ import * as fs25 from "node:fs";
210632
211096
  import * as path28 from "node:path";
210633
211097
  var WSL_LAUNCHER_SEGMENTS = /* @__PURE__ */ new Set(["system32", "syswow64", "windowsapps"]);
210634
211098
  function isExecutable(p) {
210635
211099
  try {
210636
- return fs24.statSync(p).isFile();
211100
+ return fs25.statSync(p).isFile();
210637
211101
  } catch {
210638
211102
  return false;
210639
211103
  }
@@ -210770,12 +211234,7 @@ function extractCatSourceFile(cmd) {
210770
211234
  const m = /^cat\s+(\S+\.(?:java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less))\s*$/.exec(cmd);
210771
211235
  return m?.[1] ?? null;
210772
211236
  }
210773
- function extractCatFile(cmd) {
210774
- const m = /^(cat|bat|type|Get-Content|gc)(?:\s+(?:-[a-zA-Z]+|--[a-zA-Z-]+))*\s+(?:"([^"]+)"|'([^']+)'|(\S+))\s*$/i.exec(cmd);
210775
- if (!m) return null;
210776
- const cmd0 = m[1];
210777
- const filePath = m[2] ?? m[3] ?? m[4];
210778
- if (filePath === void 0) return null;
211237
+ function classifyCatPath(filePath, cmd0) {
210779
211238
  if (isTempPath(filePath)) return null;
210780
211239
  const basename17 = (filePath.includes("/") ? filePath.split("/").at(-1) : filePath.split("\\").at(-1)) ?? filePath;
210781
211240
  const isEnvFile = /^\.env(\.\w+)?$/i.test(basename17);
@@ -210787,6 +211246,25 @@ function extractCatFile(cmd) {
210787
211246
  const isConfig = /\.(?:json|yaml|yml|toml|conf|cfg|ini|properties)$/i.test(filePath);
210788
211247
  return { filePath, isDoc, isEnv, isConfig, isSql, cmd0 };
210789
211248
  }
211249
+ function extractCatFile(cmd) {
211250
+ const m = /^(cat|bat|type|Get-Content|gc)(?:\s+(?:-[a-zA-Z]+|--[a-zA-Z-]+))*\s+(?:"([^"]+)"|'([^']+)'|(\S+?))(?:\s+-[a-zA-Z].*)?\s*$/i.exec(cmd);
211251
+ if (!m) return null;
211252
+ const cmd0 = m[1];
211253
+ const filePath = m[2] ?? m[3] ?? m[4];
211254
+ if (filePath === void 0) return null;
211255
+ return classifyCatPath(filePath, cmd0);
211256
+ }
211257
+ function extractCatFilesMulti(cmd) {
211258
+ if (/[|<>;&`]/.test(cmd) || cmd.includes("$(")) return null;
211259
+ const m = /^(cat|bat|type|Get-Content|gc)\s+(.+?)\s*$/i.exec(cmd);
211260
+ if (!m) return null;
211261
+ const cmd0 = m[1];
211262
+ const tokens = m[2].match(/"[^"]+"|'[^']+'|\S+/g) ?? [];
211263
+ const paths = tokens.filter((t) => !/^-/.test(t)).map((t) => t.replace(/^["']|["']$/g, ""));
211264
+ if (paths.length < 2) return null;
211265
+ const out2 = paths.map((p) => classifyCatPath(p, cmd0)).filter((r) => r !== null);
211266
+ return out2.length >= 2 ? out2 : null;
211267
+ }
210790
211268
  var POWERSHELL_WRAP_RE = /^(?:powershell|pwsh)(?:\.exe)?(?:\s+-[a-zA-Z]+(?:\s+\S+)?)*\s+(?:-Command|-c|-EncodedCommand)\s+(?:"([^"]*)"|'([^']*)')\s*$/i;
210791
211269
  var PS_GETCONTENT_INNER_RE = /^(?:Get-Content|gc|cat|type)(?:\s+(?:-[a-zA-Z]+|--[a-zA-Z-]+))*\s+(?:"([^"]+)"|'([^']+)'|(\S+?))(?:\s+-[a-zA-Z].*)?\s*$/i;
210792
211270
  var PS_TEMP_READ_FLOOD_BYTES = 16 * 1024;
@@ -211443,7 +211921,7 @@ function preBashHandler(event) {
211443
211921
  recordStat("session_hint", 0, 0);
211444
211922
  const tail = n ?? 50;
211445
211923
  return denyOutput(
211446
- "Task output " + id + ' is a JSONL agent transcript on disk. Use `token-goat bash-output --file "' + outPath + '" --transcript` to read the assistant text, then narrow with `--grep PATTERN` or `--tail ' + tail + "`, instead of reading the whole file."
211924
+ "Task output " + id + ' is a JSONL agent transcript on disk. Use `token-goat bash-output --file "' + outPath + '" --transcript` to read the assistant text, then narrow with `--grep PATTERN` or `--tail ' + tail + '`, or read a specific line range (the only way to reach the MIDDLE of a large artifact) with `token-goat read "' + outPath + '@START-END"`, instead of reading the whole file.'
211447
211925
  );
211448
211926
  }
211449
211927
  const findResult = extractFindCommand(cmd);
@@ -211513,6 +211991,18 @@ function preBashHandler(event) {
211513
211991
  const hint = isEnv ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` to read a specific variable.' : isConfig ? 'Use `token-goat config-get "' + hintPath + '" KEY_NAME` or `token-goat section "' + hintPath + '::sectionName"` to read a specific value.' : isDoc ? 'Use `token-goat section "' + hintPath + '::SectionHeading"` to read one section.' : 'Use `token-goat read "' + hintPath + '::SymbolName"` to read one function or class.';
211514
211992
  return cdStripped ? contextOutput("`" + cmd0 + "` loads the entire file into context. " + hint) : denyOutput("`" + cmd0 + "` loads the entire file into context. " + hint);
211515
211993
  }
211994
+ const catMulti = extractCatFilesMulti(cmd);
211995
+ if (catMulti !== null) {
211996
+ recordStat("session_hint", 0, 0);
211997
+ const cmd0 = catMulti[0].cmd0;
211998
+ const perPath = catMulti.map(({ filePath, isDoc, isEnv, isConfig, isSql }) => {
211999
+ const hintPath = cdStripped ? resolveCdHintPath(rawCmd, filePath, hintCwd) : filePath;
212000
+ const how = isSql ? 'token-goat section "' + hintPath + '::table_name"' : isEnv || isConfig ? 'token-goat config-get "' + hintPath + '" KEY_NAME' : isDoc ? 'token-goat section "' + hintPath + '::SectionHeading"' : 'token-goat read "' + hintPath + '::SymbolName"';
212001
+ return " " + hintPath + " -> `" + how + "`";
212002
+ });
212003
+ const msg = "`" + cmd0 + "` on multiple files loads them all into context. Read each surgically instead:\n" + perPath.join("\n");
212004
+ return cdStripped ? contextOutput(msg) : denyOutput(msg);
212005
+ }
211516
212006
  const psGetContentResult = extractPowerShellWrappedGetContent(cmd);
211517
212007
  if (psGetContentResult !== null) {
211518
212008
  const { filePath, isDoc, isEnv, isConfig, isSql } = psGetContentResult;
@@ -211641,7 +212131,9 @@ function preBashHandler(event) {
211641
212131
  const curlDl = extractCurlDownload(cmd);
211642
212132
  if (curlDl !== null) {
211643
212133
  const prevPath = getCurlDownloadPath(curlDl.url);
211644
- if (prevPath !== null) {
212134
+ if (prevPath !== null && !existsSync16(resolveIndexPath(prevPath, preHookCwd ?? process.cwd()))) {
212135
+ clearCurlDownload(curlDl.url);
212136
+ } else if (prevPath !== null) {
211645
212137
  recordStat("session_hint", 0, 0);
211646
212138
  return denyOutput(
211647
212139
  "Already downloaded to " + prevPath + " earlier this session. Use `rg '<pattern>' " + prevPath + '` to search it, or `token-goat read "' + prevPath + '::SectionName"` to read a part of it.'
@@ -211677,6 +212169,20 @@ function preBashHandler(event) {
211677
212169
  );
211678
212170
  }
211679
212171
  }
212172
+ if (isScopedGitStatusOrDiffStatCommand(cmd)) {
212173
+ const gitScopedHash = shortFingerprint(stripOutputPipeline(cmd));
212174
+ const gitScopedOutputId = getBashOutputId(gitScopedHash);
212175
+ const gitScopedEntryRaw = gitScopedOutputId !== null ? getBashOutput(gitScopedOutputId) : null;
212176
+ const gitScopedEntry = gitScopedEntryRaw !== null && !isBashEntryStale(gitScopedEntryRaw, cmd, preHookCwd) ? gitScopedEntryRaw : null;
212177
+ if (gitScopedOutputId !== null && gitScopedEntry !== null) {
212178
+ const gitScopedBytes = gitScopedEntry.sizeBytes;
212179
+ recordStat("bash_compress:recall", gitScopedBytes, Math.round(gitScopedBytes / 4));
212180
+ const gitScopedPreview = cmd.length > 60 ? cmd.slice(0, 57) + "..." : cmd;
212181
+ return contextOutput(
212182
+ "Output from `" + gitScopedPreview + "`" + pipelineDivergenceNote(cmd, gitScopedEntry.command) + " is cached and unchanged (no edits to that path or HEAD since). Use `token-goat bash-output " + gitScopedOutputId + "` to recall it instead of re-running."
212183
+ );
212184
+ }
212185
+ }
211680
212186
  const tgRead = extractTgSurgicalRead(cmd, preHookCwd);
211681
212187
  if (tgRead !== null) {
211682
212188
  const cliKey = tgRead.sub + "::" + tgRead.spec;
@@ -211804,6 +212310,11 @@ async function postBashHandler(event) {
211804
212310
  recordStat("session_hint", 0, 0);
211805
212311
  return contextOutput(buildGhViewBatchAdvisory(ghView.sub, ghView.ref));
211806
212312
  }
212313
+ if (isScopedGitStatusOrDiffStatCommand(cmd) && (exitCode === null || exitCode === 0) && Buffer.byteLength(output, "utf-8") >= cacheMinBytes) {
212314
+ const gitScopedCacheHash = shortFingerprint(stripOutputPipeline(cmd));
212315
+ const gitScopedCacheId = await storeBashOutput(cmd, output, exitCode ?? 0, cwd);
212316
+ recordBashOutput(gitScopedCacheHash, gitScopedCacheId, Buffer.byteLength(output, "utf-8"));
212317
+ }
211807
212318
  const isMonitoring = getMonitoringRecallHint(cmd) !== null;
211808
212319
  if (!isMonitoring && !isBuildCommand(cmd) && !isCurlGetCommand(cmd)) return passOutput();
211809
212320
  if (Buffer.byteLength(output, "utf-8") < cacheMinBytes) return passOutput();
@@ -212026,9 +212537,14 @@ function buildEvent(eventName, payload) {
212026
212537
  const toolName = typeof rawToolName === "string" && rawToolName.trim() !== "" ? rawToolName : void 0;
212027
212538
  const rawInput = obj["tool_input"];
212028
212539
  const toolInput = typeof rawInput === "object" && rawInput !== null && !Array.isArray(rawInput) ? rawInput : {};
212029
- const rawSession = obj["session_id"];
212540
+ const rawSession = obj["session_id"] ?? obj["sessionId"];
212030
212541
  const sessionId = typeof rawSession === "string" ? rawSession : "";
212031
- return { eventName, toolName, toolInput, sessionId, raw: obj };
212542
+ const rawAgentId = obj["agent_id"] ?? obj["agentId"];
212543
+ const agentId = typeof rawAgentId === "string" && rawAgentId !== "" ? rawAgentId : void 0;
212544
+ return { eventName, toolName, toolInput, sessionId, agentId, raw: obj };
212545
+ }
212546
+ function sessionStateKey(event) {
212547
+ return event.agentId !== void 0 ? `${event.sessionId}:agent:${event.agentId}` : event.sessionId;
212032
212548
  }
212033
212549
  function harnessForNormalization() {
212034
212550
  const detected = detectHarness();
@@ -212046,13 +212562,17 @@ async function relay(eventName) {
212046
212562
  const rawPayload = await readStdinJson();
212047
212563
  const payload = eventName === "pre_tool_use" || eventName === "post_tool_use" ? normalizePayload(rawPayload, harnessForNormalization()) : rawPayload;
212048
212564
  const event = buildEvent(eventName, payload);
212565
+ if (!process.env["CLAUDE_CODE_SESSION_ID"] && event.sessionId) {
212566
+ process.env["CLAUDE_CODE_SESSION_ID"] = event.sessionId;
212567
+ }
212568
+ const stateKey = sessionStateKey(event);
212049
212569
  try {
212050
- loadSessionState(event.sessionId);
212570
+ loadSessionState(stateKey);
212051
212571
  } catch {
212052
212572
  }
212053
212573
  const output = await runHook(event);
212054
212574
  try {
212055
- saveSessionState(event.sessionId);
212575
+ saveSessionState(stateKey);
212056
212576
  } catch {
212057
212577
  }
212058
212578
  process.stdout.write(serializeOutput(output, event.eventName));
@@ -212063,7 +212583,7 @@ async function relay(eventName) {
212063
212583
 
212064
212584
  // src/bridges/gemini_install.ts
212065
212585
  init_define_import_meta_env();
212066
- import * as fs25 from "node:fs";
212586
+ import * as fs26 from "node:fs";
212067
212587
  import * as os8 from "node:os";
212068
212588
  import * as path29 from "node:path";
212069
212589
  var GEMINI_LEGACY_COMMAND_MARKER = "token-goat hook";
@@ -212083,7 +212603,7 @@ function geminiSettingsPath() {
212083
212603
  function readGeminiSettings(p, opts = {}) {
212084
212604
  let raw;
212085
212605
  try {
212086
- raw = fs25.readFileSync(p, "utf8");
212606
+ raw = fs26.readFileSync(p, "utf8");
212087
212607
  } catch {
212088
212608
  return {};
212089
212609
  }
@@ -212226,7 +212746,7 @@ function uninstallGemini() {
212226
212746
 
212227
212747
  // src/bridges/pi_install.ts
212228
212748
  init_define_import_meta_env();
212229
- import * as fs26 from "node:fs";
212749
+ import * as fs27 from "node:fs";
212230
212750
  import * as os9 from "node:os";
212231
212751
  import * as path30 from "node:path";
212232
212752
 
@@ -212505,7 +213025,7 @@ function installPi(opts = {}) {
212505
213025
  const extensionPath = piExtensionPath(opts);
212506
213026
  let existing;
212507
213027
  try {
212508
- existing = fs26.readFileSync(extensionPath, "utf8");
213028
+ existing = fs27.readFileSync(extensionPath, "utf8");
212509
213029
  } catch {
212510
213030
  existing = void 0;
212511
213031
  }
@@ -212524,11 +213044,11 @@ function installPi(opts = {}) {
212524
213044
  function uninstallPi(opts = {}) {
212525
213045
  const extensionPath = piExtensionPath(opts);
212526
213046
  try {
212527
- fs26.unlinkSync(piEntrySidecarPath(opts));
213047
+ fs27.unlinkSync(piEntrySidecarPath(opts));
212528
213048
  } catch {
212529
213049
  }
212530
213050
  try {
212531
- fs26.unlinkSync(extensionPath);
213051
+ fs27.unlinkSync(extensionPath);
212532
213052
  return true;
212533
213053
  } catch {
212534
213054
  return false;
@@ -212537,7 +213057,7 @@ function uninstallPi(opts = {}) {
212537
213057
 
212538
213058
  // src/bridges/opencode_install.ts
212539
213059
  init_define_import_meta_env();
212540
- import * as fs27 from "node:fs";
213060
+ import * as fs28 from "node:fs";
212541
213061
  import * as os10 from "node:os";
212542
213062
  import * as path31 from "node:path";
212543
213063
 
@@ -212776,7 +213296,7 @@ function installOpencode() {
212776
213296
  const pluginPath = opencodePluginPath();
212777
213297
  let existing;
212778
213298
  try {
212779
- existing = fs27.readFileSync(pluginPath, "utf8");
213299
+ existing = fs28.readFileSync(pluginPath, "utf8");
212780
213300
  } catch {
212781
213301
  existing = void 0;
212782
213302
  }
@@ -212795,11 +213315,11 @@ function installOpencode() {
212795
213315
  function uninstallOpencode() {
212796
213316
  const pluginPath = opencodePluginPath();
212797
213317
  try {
212798
- fs27.unlinkSync(opencodeEntrySidecarPath());
213318
+ fs28.unlinkSync(opencodeEntrySidecarPath());
212799
213319
  } catch {
212800
213320
  }
212801
213321
  try {
212802
- fs27.unlinkSync(pluginPath);
213322
+ fs28.unlinkSync(pluginPath);
212803
213323
  return true;
212804
213324
  } catch {
212805
213325
  return false;
@@ -212808,7 +213328,7 @@ function uninstallOpencode() {
212808
213328
 
212809
213329
  // src/bridges/openclaw_install.ts
212810
213330
  init_define_import_meta_env();
212811
- import * as fs28 from "node:fs";
213331
+ import * as fs29 from "node:fs";
212812
213332
  import * as os11 from "node:os";
212813
213333
  import * as path32 from "node:path";
212814
213334
 
@@ -213018,7 +213538,7 @@ function openclawEntrySidecarPath() {
213018
213538
  function readOpenclawConfig(p, opts = {}) {
213019
213539
  let raw;
213020
213540
  try {
213021
- raw = fs28.readFileSync(p, "utf8");
213541
+ raw = fs29.readFileSync(p, "utf8");
213022
213542
  } catch {
213023
213543
  return {};
213024
213544
  }
@@ -213048,7 +213568,7 @@ function installOpenclaw() {
213048
213568
  const pluginPath = openclawPluginPath();
213049
213569
  let existingPlugin;
213050
213570
  try {
213051
- existingPlugin = fs28.readFileSync(pluginPath, "utf8");
213571
+ existingPlugin = fs29.readFileSync(pluginPath, "utf8");
213052
213572
  } catch {
213053
213573
  existingPlugin = void 0;
213054
213574
  }
@@ -213092,12 +213612,12 @@ function uninstallOpenclaw() {
213092
213612
  const pluginPath = openclawPluginPath();
213093
213613
  let removed = false;
213094
213614
  try {
213095
- fs28.unlinkSync(pluginPath);
213615
+ fs29.unlinkSync(pluginPath);
213096
213616
  removed = true;
213097
213617
  } catch {
213098
213618
  }
213099
213619
  try {
213100
- fs28.unlinkSync(openclawEntrySidecarPath());
213620
+ fs29.unlinkSync(openclawEntrySidecarPath());
213101
213621
  } catch {
213102
213622
  }
213103
213623
  const settings = readOpenclawConfig(configPath2);
@@ -237311,7 +237831,7 @@ var EMPTY_COMPLETION_RESULT = {
237311
237831
 
237312
237832
  // src/read_commands.ts
237313
237833
  init_define_import_meta_env();
237314
- import * as fs36 from "node:fs";
237834
+ import * as fs37 from "node:fs";
237315
237835
  import * as path44 from "node:path";
237316
237836
 
237317
237837
  // src/section_reader.ts
@@ -237613,6 +238133,19 @@ function trimToBudget(text, budgetTokens, command2) {
237613
238133
  const marker = `[token-goat: output capped at ~${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
237614
238134
  return kept.join("\n") + "\n" + marker;
237615
238135
  }
238136
+ function capJsonRows(items, budgetTokens) {
238137
+ const totalCount = items.length;
238138
+ const charBudget = Math.max(1, budgetTokens * 3);
238139
+ const kept = [];
238140
+ let used = 0;
238141
+ for (const item of items) {
238142
+ const cost = JSON.stringify(item).length + 2;
238143
+ if (kept.length > 0 && used + cost > charBudget) break;
238144
+ kept.push(item);
238145
+ used += cost;
238146
+ }
238147
+ return { items: kept, truncated: kept.length < totalCount, totalCount };
238148
+ }
237616
238149
  function getHintFor(command2) {
237617
238150
  const cmd = (command2 || "").toLowerCase().trim();
237618
238151
  if (cmd === "symbol") {
@@ -237627,12 +238160,15 @@ function getHintFor(command2) {
237627
238160
  if (cmd === "bash-output" || cmd === "web-output") {
237628
238161
  return "Use --grep PATTERN, --section HEADING, or --tail N to narrow the cached output.";
237629
238162
  }
238163
+ if (cmd === "semantic") {
238164
+ return "Narrow your query text or pass --limit to reduce the number of matches returned.";
238165
+ }
237630
238166
  return "Narrow your query or raise overflow_guard max_tokens in config.";
237631
238167
  }
237632
238168
 
237633
238169
  // src/graph_commands.ts
237634
238170
  init_define_import_meta_env();
237635
- import * as fs29 from "node:fs";
238171
+ import * as fs30 from "node:fs";
237636
238172
  import * as os12 from "node:os";
237637
238173
  import * as path33 from "node:path";
237638
238174
  import { execFileSync, spawnSync as spawnSync2 } from "node:child_process";
@@ -237858,7 +238394,7 @@ var SOURCE_EXTENSIONS = [
237858
238394
  function runDeps(opts) {
237859
238395
  let text;
237860
238396
  try {
237861
- text = fs29.readFileSync(opts.file, "utf-8");
238397
+ text = fs30.readFileSync(opts.file, "utf-8");
237862
238398
  } catch {
237863
238399
  emitErr(`Could not read: ${opts.file}`);
237864
238400
  return 1;
@@ -237872,12 +238408,12 @@ function runDeps(opts) {
237872
238408
  if (imp.startsWith("./") || imp.startsWith("../")) {
237873
238409
  const base = path33.resolve(dir, imp);
237874
238410
  let resolved = imp;
237875
- if (fs29.existsSync(base) && fs29.statSync(base).isFile()) {
238411
+ if (fs30.existsSync(base) && fs30.statSync(base).isFile()) {
237876
238412
  resolved = base;
237877
238413
  } else {
237878
238414
  for (const srcExt of SOURCE_EXTENSIONS) {
237879
238415
  const candidate = base + srcExt;
237880
- if (fs29.existsSync(candidate)) {
238416
+ if (fs30.existsSync(candidate)) {
237881
238417
  resolved = candidate;
237882
238418
  break;
237883
238419
  }
@@ -238121,7 +238657,7 @@ function runArch(opts) {
238121
238657
  for (const file2 of files) {
238122
238658
  let text;
238123
238659
  try {
238124
- text = fs29.readFileSync(file2, "utf8");
238660
+ text = fs30.readFileSync(file2, "utf8");
238125
238661
  } catch {
238126
238662
  continue;
238127
238663
  }
@@ -238247,7 +238783,7 @@ ANSWER:`;
238247
238783
  if (result.status === 0) {
238248
238784
  if (codexOutPath) {
238249
238785
  try {
238250
- answer = fs29.readFileSync(codexOutPath, "utf8").trim();
238786
+ answer = fs30.readFileSync(codexOutPath, "utf8").trim();
238251
238787
  } catch {
238252
238788
  }
238253
238789
  } else {
@@ -238266,7 +238802,7 @@ ANSWER:`;
238266
238802
  } finally {
238267
238803
  if (codexOutPath) {
238268
238804
  try {
238269
- fs29.unlinkSync(codexOutPath);
238805
+ fs30.unlinkSync(codexOutPath);
238270
238806
  } catch {
238271
238807
  }
238272
238808
  }
@@ -240264,7 +240800,7 @@ async function extractPdfMeta(data) {
240264
240800
 
240265
240801
  // src/screenshot.ts
240266
240802
  init_define_import_meta_env();
240267
- import fs35 from "node:fs";
240803
+ import fs36 from "node:fs";
240268
240804
  import path43 from "node:path";
240269
240805
  var _puppeteerCache;
240270
240806
  async function loadPuppeteer() {
@@ -240283,7 +240819,7 @@ var PLAYWRIGHT_CHROME_SUBDIRS = ["chrome-win64", "chrome-win"];
240283
240819
  function findPlaywrightChromium(msPlaywrightDir) {
240284
240820
  let entries;
240285
240821
  try {
240286
- entries = fs35.readdirSync(msPlaywrightDir);
240822
+ entries = fs36.readdirSync(msPlaywrightDir);
240287
240823
  } catch {
240288
240824
  return [];
240289
240825
  }
@@ -240322,13 +240858,13 @@ function platformCandidatePaths() {
240322
240858
  return candidates;
240323
240859
  }
240324
240860
  function resolveBrowserExecutablePath(explicit) {
240325
- if (explicit && fs35.existsSync(explicit)) return explicit;
240861
+ if (explicit && fs36.existsSync(explicit)) return explicit;
240326
240862
  const cfgPath = loadConfig().screenshot.chrome_path;
240327
- if (cfgPath && fs35.existsSync(cfgPath)) return cfgPath;
240863
+ if (cfgPath && fs36.existsSync(cfgPath)) return cfgPath;
240328
240864
  const envPath = process.env["TOKEN_GOAT_CHROME_PATH"];
240329
- if (envPath && fs35.existsSync(envPath)) return envPath;
240865
+ if (envPath && fs36.existsSync(envPath)) return envPath;
240330
240866
  for (const candidate of platformCandidatePaths()) {
240331
- if (fs35.existsSync(candidate)) return candidate;
240867
+ if (fs36.existsSync(candidate)) return candidate;
240332
240868
  }
240333
240869
  return null;
240334
240870
  }
@@ -240364,7 +240900,7 @@ var GREP_MAX_LINES = 200;
240364
240900
  var FIND_SCAN_LIMIT = 2e4;
240365
240901
  function fileExists(p) {
240366
240902
  try {
240367
- fs36.statSync(p);
240903
+ fs37.statSync(p);
240368
240904
  return true;
240369
240905
  } catch {
240370
240906
  return false;
@@ -240372,7 +240908,7 @@ function fileExists(p) {
240372
240908
  }
240373
240909
  function readFileText(p) {
240374
240910
  try {
240375
- return fs36.readFileSync(p, "utf-8");
240911
+ return fs37.readFileSync(p, "utf-8");
240376
240912
  } catch {
240377
240913
  return null;
240378
240914
  }
@@ -240390,6 +240926,11 @@ function guardText(text, command2) {
240390
240926
  const cfg = loadConfig();
240391
240927
  return cfg.overflow_guard.enabled ? trimToBudget(text, cfg.overflow_guard.max_tokens, command2) : text;
240392
240928
  }
240929
+ function guardJsonRows(items) {
240930
+ const cfg = loadConfig();
240931
+ if (!cfg.overflow_guard.enabled) return { items: [...items], truncated: false, totalCount: items.length };
240932
+ return capJsonRows(items, cfg.overflow_guard.max_tokens);
240933
+ }
240393
240934
  function findSpecSeparator(spec) {
240394
240935
  return spec.lastIndexOf("::");
240395
240936
  }
@@ -240428,7 +240969,9 @@ function runSymbol(opts) {
240428
240969
  return { text: `No matches for '${opts.name ?? "*"}'`, code: 1 };
240429
240970
  }
240430
240971
  if (opts.json === true) {
240431
- return { text: JSON.stringify(results, null, 2), code: 0 };
240972
+ const capped = guardJsonRows(results);
240973
+ const payload = capped.truncated ? { results: capped.items, truncated: true, totalCount: capped.totalCount } : results;
240974
+ return { text: JSON.stringify(payload, null, 2), code: 0 };
240432
240975
  }
240433
240976
  const blocks = results.map((sym) => {
240434
240977
  const header = `# ${sym.name} (${sym.kind}) \u2014 ${sym.filePath}:${sym.lineStart}-${sym.lineEnd}`;
@@ -240443,7 +240986,7 @@ function runSymbol(opts) {
240443
240986
  return preview.trim() !== "" ? `${header}
240444
240987
  ${preview}` : header;
240445
240988
  });
240446
- return { text: blocks.join("\n\n"), code: 0 };
240989
+ return { text: guardText(blocks.join("\n\n"), "symbol"), code: 0 };
240447
240990
  }
240448
240991
  function parseReadSpec(spec) {
240449
240992
  const colonIdx = findSpecSeparator(spec);
@@ -240662,6 +241205,7 @@ function runRefs(opts) {
240662
241205
  if (symbols.length <= 1) return runRefsSingle(opts);
240663
241206
  const jsonOut = {};
240664
241207
  let anyFound = false;
241208
+ const lines = [];
240665
241209
  for (const sym of symbols) {
240666
241210
  const queryOpts = { name: sym };
240667
241211
  if (file2 !== void 0 && opts.callers !== true) queryOpts.filePath = resolveIndexPath(file2);
@@ -240669,21 +241213,26 @@ function runRefs(opts) {
240669
241213
  const results = queryRefs(queryOpts);
240670
241214
  if (results.length > 0) anyFound = true;
240671
241215
  if (opts.json === true) {
240672
- jsonOut[sym] = results;
241216
+ const capped = guardJsonRows(results);
241217
+ jsonOut[sym] = capped.truncated ? { references: capped.items, truncated: true, totalCount: capped.totalCount } : capped.items;
240673
241218
  continue;
240674
241219
  }
240675
241220
  if (results.length === 0) {
240676
- emit3(`${sym}: (no references found)`);
241221
+ lines.push(`${sym}: (no references found)`);
240677
241222
  continue;
240678
241223
  }
240679
- emit3(`${sym}:`);
241224
+ lines.push(`${sym}:`);
240680
241225
  if (opts.callers === true) {
240681
- emitCallerGroups(results);
241226
+ lines.push(...renderCallerGroups(results));
240682
241227
  } else {
240683
- for (const ref of results) emit3(` ${ref.filePath}:${ref.line}: ${ref.context}`);
241228
+ for (const ref of results) lines.push(` ${ref.filePath}:${ref.line}: ${ref.context}`);
240684
241229
  }
240685
241230
  }
240686
- if (opts.json === true) emit3(JSON.stringify(jsonOut, null, 2));
241231
+ if (opts.json === true) {
241232
+ emit3(JSON.stringify(jsonOut, null, 2));
241233
+ return anyFound ? 0 : 1;
241234
+ }
241235
+ emitGuarded(lines.join("\n"), "symbol");
240687
241236
  return anyFound ? 0 : 1;
240688
241237
  }
240689
241238
  function runRefsSingle(opts) {
@@ -240698,19 +241247,16 @@ function runRefsSingle(opts) {
240698
241247
  return 1;
240699
241248
  }
240700
241249
  if (opts.json === true) {
240701
- emit3(JSON.stringify(results, null, 2));
241250
+ const capped = guardJsonRows(results);
241251
+ const payload = capped.truncated ? { references: capped.items, truncated: true, totalCount: capped.totalCount } : results;
241252
+ emit3(JSON.stringify(payload, null, 2));
240702
241253
  return 0;
240703
241254
  }
240704
- if (opts.callers === true) {
240705
- emitCallerGroups(results);
240706
- } else {
240707
- for (const ref of results) {
240708
- emit3(`${ref.filePath}:${ref.line}: ${ref.context}`);
240709
- }
240710
- }
241255
+ const lines = opts.callers === true ? renderCallerGroups(results) : results.map((ref) => `${ref.filePath}:${ref.line}: ${ref.context}`);
241256
+ emitGuarded(lines.join("\n"), "symbol");
240711
241257
  return 0;
240712
241258
  }
240713
- function emitCallerGroups(refs) {
241259
+ function renderCallerGroups(refs) {
240714
241260
  const byFile = /* @__PURE__ */ new Map();
240715
241261
  for (const ref of refs) {
240716
241262
  const bucket = byFile.get(ref.filePath);
@@ -240720,12 +241266,14 @@ function emitCallerGroups(refs) {
240720
241266
  byFile.set(ref.filePath, [ref]);
240721
241267
  }
240722
241268
  }
241269
+ const lines = [];
240723
241270
  for (const [file2, fileRefs] of byFile) {
240724
- emit3(`${file2}:`);
241271
+ lines.push(`${file2}:`);
240725
241272
  for (const ref of fileRefs) {
240726
- emit3(` :${ref.line} ${ref.context !== "" ? ref.context : "(module scope)"}`);
241273
+ lines.push(` :${ref.line} ${ref.context !== "" ? ref.context : "(module scope)"}`);
240727
241274
  }
240728
241275
  }
241276
+ return lines;
240729
241277
  }
240730
241278
  function runSkeleton(opts) {
240731
241279
  const resolved = resolveIndexPath(opts.file);
@@ -240739,20 +241287,16 @@ function runSkeleton(opts) {
240739
241287
  const filtered = opts.minLines !== void 0 ? symbols.filter((s) => s.lineEnd - s.lineStart + 1 >= (opts.minLines ?? 0)) : symbols;
240740
241288
  const refCounts = opts.stats === true ? queryRefCounts(filtered.map((s) => s.name)) : void 0;
240741
241289
  if (opts.json === true) {
240742
- return {
240743
- text: JSON.stringify(
240744
- filtered.map((s) => ({
240745
- name: s.name,
240746
- kind: s.kind,
240747
- lineStart: s.lineStart,
240748
- lineEnd: s.lineEnd,
240749
- ...refCounts !== void 0 ? { refCount: refCounts.get(s.name) ?? 0, hasDoc: s.docstring.trim().length > 0 } : {}
240750
- })),
240751
- null,
240752
- 2
240753
- ),
240754
- code: 0
240755
- };
241290
+ const rows = filtered.map((s) => ({
241291
+ name: s.name,
241292
+ kind: s.kind,
241293
+ lineStart: s.lineStart,
241294
+ lineEnd: s.lineEnd,
241295
+ ...refCounts !== void 0 ? { refCount: refCounts.get(s.name) ?? 0, hasDoc: s.docstring.trim().length > 0 } : {}
241296
+ }));
241297
+ const capped = guardJsonRows(rows);
241298
+ const payload = capped.truncated ? { symbols: capped.items, truncated: true, totalCount: capped.totalCount } : rows;
241299
+ return { text: JSON.stringify(payload, null, 2), code: 0 };
240756
241300
  }
240757
241301
  const totalLines = filtered.length > 0 ? Math.max(...filtered.map((s) => s.lineEnd)) : 0;
240758
241302
  const lines = [`# Skeleton: ${opts.file} (${filtered.length} symbols, ${totalLines} lines)`];
@@ -240761,7 +241305,7 @@ function runSkeleton(opts) {
240761
241305
  const statsStr = refCounts !== void 0 ? ` [${refCounts.get(sym.name) ?? 0} refs, ${sym.docstring.trim().length > 0 ? "documented" : "undocumented"}]` : "";
240762
241306
  lines.push(` ${lineStr} ${sym.kind.padEnd(10)} ${sym.name} ${firstBodyLine(sym.body)}${statsStr}`);
240763
241307
  }
240764
- return { text: lines.join("\n"), code: 0 };
241308
+ return { text: guardText(lines.join("\n"), "symbol"), code: 0 };
240765
241309
  }
240766
241310
  function runOutline(opts) {
240767
241311
  const resolved = resolveIndexPath(opts.file);
@@ -240775,18 +241319,14 @@ function runOutline(opts) {
240775
241319
  const filtered = opts.minLines !== void 0 ? symbols.filter((s) => s.lineEnd - s.lineStart + 1 >= (opts.minLines ?? 0)) : symbols;
240776
241320
  const refCounts = opts.stats === true ? queryRefCounts(filtered.map((s) => s.name)) : void 0;
240777
241321
  if (opts.json === true) {
240778
- return {
240779
- text: JSON.stringify(
240780
- refCounts !== void 0 ? filtered.map((s) => ({
240781
- ...s,
240782
- refCount: refCounts.get(s.name) ?? 0,
240783
- hasDoc: s.docstring.trim().length > 0
240784
- })) : filtered,
240785
- null,
240786
- 2
240787
- ),
240788
- code: 0
240789
- };
241322
+ const rows = refCounts !== void 0 ? filtered.map((s) => ({
241323
+ ...s,
241324
+ refCount: refCounts.get(s.name) ?? 0,
241325
+ hasDoc: s.docstring.trim().length > 0
241326
+ })) : filtered;
241327
+ const capped = guardJsonRows(rows);
241328
+ const payload = capped.truncated ? { symbols: capped.items, truncated: true, totalCount: capped.totalCount } : rows;
241329
+ return { text: JSON.stringify(payload, null, 2), code: 0 };
240790
241330
  }
240791
241331
  const lines = [`# Outline: ${opts.file} (${filtered.length} symbols)`];
240792
241332
  for (const sym of filtered) {
@@ -240797,7 +241337,7 @@ function runOutline(opts) {
240797
241337
  const statsStr = refCounts !== void 0 ? ` [${refCounts.get(sym.name) ?? 0} refs, ${sym.docstring.trim().length > 0 ? "documented" : "undocumented"}]` : "";
240798
241338
  lines.push(` ${rangeStr} ${kindStr} ${sym.name} (${bodyLen}\u2113)${docFirst}${statsStr}`);
240799
241339
  }
240800
- return { text: lines.join("\n"), code: 0 };
241340
+ return { text: guardText(lines.join("\n"), "symbol"), code: 0 };
240801
241341
  }
240802
241342
  function runCsvQuery(opts) {
240803
241343
  const text = readFileText(opts.file);
@@ -240849,7 +241389,7 @@ async function runPdfExtractText(file2, pagesSpec, layout = false) {
240849
241389
  if (!fileExists(file2)) {
240850
241390
  throw new Error(`Could not read: ${file2}`);
240851
241391
  }
240852
- const data = fs36.readFileSync(file2);
241392
+ const data = fs37.readFileSync(file2);
240853
241393
  const result = await extractPdfText(new Uint8Array(data), pagesSpec, layout);
240854
241394
  return result.text;
240855
241395
  }
@@ -240857,14 +241397,14 @@ async function runPdfOutline(file2) {
240857
241397
  if (!fileExists(file2)) {
240858
241398
  throw new Error(`Could not read: ${file2}`);
240859
241399
  }
240860
- const data = fs36.readFileSync(file2);
241400
+ const data = fs37.readFileSync(file2);
240861
241401
  return extractPdfOutline(new Uint8Array(data));
240862
241402
  }
240863
241403
  async function runPdfMeta(file2) {
240864
241404
  if (!fileExists(file2)) {
240865
241405
  throw new Error(`Could not read: ${file2}`);
240866
241406
  }
240867
- const data = fs36.readFileSync(file2);
241407
+ const data = fs37.readFileSync(file2);
240868
241408
  return extractPdfMeta(new Uint8Array(data));
240869
241409
  }
240870
241410
  async function runScreenshot(url2, destPath, opts) {
@@ -241064,7 +241604,7 @@ function runGrep(opts) {
241064
241604
  const hits = [];
241065
241605
  function searchFile(filePath) {
241066
241606
  try {
241067
- const text = fs36.readFileSync(filePath, "utf-8");
241607
+ const text = fs37.readFileSync(filePath, "utf-8");
241068
241608
  const lines = text.split(/\r?\n/);
241069
241609
  lines.forEach((lineText, idx) => {
241070
241610
  if (regex.test(lineText)) {
@@ -241085,10 +241625,10 @@ function runGrep(opts) {
241085
241625
  }
241086
241626
  function searchDir(dir) {
241087
241627
  try {
241088
- for (const entry of fs36.readdirSync(dir)) {
241628
+ for (const entry of fs37.readdirSync(dir)) {
241089
241629
  if (entry.startsWith(".")) continue;
241090
241630
  const full = path44.join(dir, entry);
241091
- const stat2 = fs36.statSync(full);
241631
+ const stat2 = fs37.statSync(full);
241092
241632
  if (stat2.isDirectory()) {
241093
241633
  if (SKIP_DIRS.has(entry)) continue;
241094
241634
  if (opts.recursive !== false) searchDir(full);
@@ -241104,7 +241644,7 @@ function runGrep(opts) {
241104
241644
  emitErr2(`Path not found: ${searchPath}`);
241105
241645
  return 1;
241106
241646
  }
241107
- const stat2 = fs36.statSync(searchPath);
241647
+ const stat2 = fs37.statSync(searchPath);
241108
241648
  if (stat2.isDirectory()) {
241109
241649
  searchDir(searchPath);
241110
241650
  } else {
@@ -241138,7 +241678,7 @@ function runGrep(opts) {
241138
241678
  }
241139
241679
  return 0;
241140
241680
  }
241141
- function escapeRegExp2(s) {
241681
+ function escapeRegExp3(s) {
241142
241682
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
241143
241683
  }
241144
241684
  function lookupYaml(lines, key) {
@@ -241237,7 +241777,7 @@ function runConfigGet(opts) {
241237
241777
  if (currentSection !== (sectionPath ?? "")) {
241238
241778
  continue;
241239
241779
  }
241240
- if (new RegExp(`^${escapeRegExp2(leafKey)}\\s*=`).test(trimmed)) {
241780
+ if (new RegExp(`^${escapeRegExp3(leafKey)}\\s*=`).test(trimmed)) {
241241
241781
  const eqIdx = trimmed.indexOf("=");
241242
241782
  emit3(trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, ""));
241243
241783
  return 0;
@@ -241459,7 +241999,7 @@ async function runSemantic(query, opts) {
241459
241999
  (h) => `# ${h.filePath}:${h.startLine}-${h.endLine} (distance ${h.distance.toFixed(3)})
241460
242000
  ${previewLines(h.text, 3)}`
241461
242001
  );
241462
- return { text: blocks2.join("\n\n"), code: 0 };
242002
+ return { text: guardText(blocks2.join("\n\n"), "semantic"), code: 0 };
241463
242003
  }
241464
242004
  const results = searchSymbolsFts(query, n);
241465
242005
  if (results.length === 0) {
@@ -241467,7 +242007,7 @@ ${previewLines(h.text, 3)}`
241467
242007
  }
241468
242008
  const blocks = results.map((s) => `${symbolHeader(s)}
241469
242009
  ${previewLines(s.body, 3)}`);
241470
- return { text: blocks.join("\n\n"), code: 0 };
242010
+ return { text: guardText(blocks.join("\n\n"), "semantic"), code: 0 };
241471
242011
  }
241472
242012
 
241473
242013
  // src/mcp_server.ts
@@ -241923,7 +242463,7 @@ init_define_import_meta_env();
241923
242463
 
241924
242464
  // src/ooxml_extract.ts
241925
242465
  init_define_import_meta_env();
241926
- import * as fs37 from "node:fs";
242466
+ import * as fs38 from "node:fs";
241927
242467
  var _fflateCache;
241928
242468
  var _fxpCache;
241929
242469
  async function loadFflate() {
@@ -241952,11 +242492,11 @@ var MAX_OOXML_INPUT_BYTES = 50 * 1024 * 1024;
241952
242492
  async function readOoxmlZip(filePath) {
241953
242493
  const fflate = await loadFflate();
241954
242494
  if (!fflate) throw new Error("fflate is not installed; run `npm install fflate` to enable this command");
241955
- const size = fs37.statSync(filePath).size;
242495
+ const size = fs38.statSync(filePath).size;
241956
242496
  if (size > MAX_OOXML_INPUT_BYTES) {
241957
242497
  throw new Error(`${filePath} is ${Math.round(size / (1024 * 1024))}MB, over the ${MAX_OOXML_INPUT_BYTES / (1024 * 1024)}MB limit for OOXML files`);
241958
242498
  }
241959
- const data = fs37.readFileSync(filePath);
242499
+ const data = fs38.readFileSync(filePath);
241960
242500
  return fflate.unzipSync(new Uint8Array(data));
241961
242501
  }
241962
242502
  function decodeZipEntry(entries, path56) {
@@ -242216,7 +242756,7 @@ async function docxText(filePath) {
242216
242756
 
242217
242757
  // src/sharepoint_resolve.ts
242218
242758
  init_define_import_meta_env();
242219
- import * as fs38 from "node:fs";
242759
+ import * as fs39 from "node:fs";
242220
242760
  import * as os20 from "node:os";
242221
242761
  import * as path45 from "node:path";
242222
242762
  var TENANT_HOST_RE = /^([a-z0-9-]+?)(-my)?\.sharepoint\.com$/i;
@@ -242265,7 +242805,7 @@ function candidateRoots(env2, home) {
242265
242805
  if (commercial !== void 0) roots.push(commercial);
242266
242806
  if (personal !== void 0 && personal !== commercial) roots.push(personal);
242267
242807
  try {
242268
- for (const entry of fs38.readdirSync(home, { withFileTypes: true })) {
242808
+ for (const entry of fs39.readdirSync(home, { withFileTypes: true })) {
242269
242809
  if (entry.isDirectory() && /onedrive/i.test(entry.name)) {
242270
242810
  const full = path45.join(home, entry.name);
242271
242811
  if (!roots.includes(full)) roots.push(full);
@@ -242282,29 +242822,29 @@ function resolveLocalPath(parsed, env2 = process.env, home = os20.homedir()) {
242282
242822
  for (const root of roots) {
242283
242823
  const rawJoined = path45.join(root, ...libSegments);
242284
242824
  triedPaths.push(rawJoined);
242285
- if (fs38.existsSync(rawJoined)) return { resolvedPath: rawJoined, triedPaths };
242825
+ if (fs39.existsSync(rawJoined)) return { resolvedPath: rawJoined, triedPaths };
242286
242826
  if (libSegments.length > 0) {
242287
242827
  const aliasedFirst = normalizeLibrarySegment(libSegments[0]);
242288
242828
  if (aliasedFirst !== libSegments[0]) {
242289
242829
  const aliasedJoined = path45.join(root, aliasedFirst, ...libSegments.slice(1));
242290
242830
  triedPaths.push(aliasedJoined);
242291
- if (fs38.existsSync(aliasedJoined)) return { resolvedPath: aliasedJoined, triedPaths };
242831
+ if (fs39.existsSync(aliasedJoined)) return { resolvedPath: aliasedJoined, triedPaths };
242292
242832
  }
242293
242833
  }
242294
242834
  if (parsed.siteType === "site" && parsed.siteName.length > 0) {
242295
242835
  try {
242296
- for (const entry of fs38.readdirSync(root, { withFileTypes: true })) {
242836
+ for (const entry of fs39.readdirSync(root, { withFileTypes: true })) {
242297
242837
  if (!entry.isDirectory() || !entry.name.toLowerCase().includes(parsed.siteName.toLowerCase())) continue;
242298
242838
  const siteRoot = path45.join(root, entry.name);
242299
242839
  const siteJoined = path45.join(siteRoot, ...libSegments);
242300
242840
  triedPaths.push(siteJoined);
242301
- if (fs38.existsSync(siteJoined)) return { resolvedPath: siteJoined, triedPaths };
242841
+ if (fs39.existsSync(siteJoined)) return { resolvedPath: siteJoined, triedPaths };
242302
242842
  if (libSegments.length > 0) {
242303
242843
  const aliasedFirst = normalizeLibrarySegment(libSegments[0]);
242304
242844
  if (aliasedFirst !== libSegments[0]) {
242305
242845
  const siteAliasedJoined = path45.join(siteRoot, aliasedFirst, ...libSegments.slice(1));
242306
242846
  triedPaths.push(siteAliasedJoined);
242307
- if (fs38.existsSync(siteAliasedJoined)) return { resolvedPath: siteAliasedJoined, triedPaths };
242847
+ if (fs39.existsSync(siteAliasedJoined)) return { resolvedPath: siteAliasedJoined, triedPaths };
242308
242848
  }
242309
242849
  }
242310
242850
  }
@@ -242365,7 +242905,7 @@ function extractVideoChapters(file2) {
242365
242905
 
242366
242906
  // src/transcript_extract.ts
242367
242907
  init_define_import_meta_env();
242368
- import * as fs39 from "node:fs";
242908
+ import * as fs40 from "node:fs";
242369
242909
  var TIMESTAMP_RE = /(\d{1,2}:)?(\d{2}):(\d{2})[.,](\d{1,3})/;
242370
242910
  var CUE_LINE_RE = new RegExp(`^\\s*${TIMESTAMP_RE.source}\\s*-->\\s*${TIMESTAMP_RE.source}`);
242371
242911
  var V_TAG_RE = /^<v(?:\.\w+)?\s+([^>]+)>\s*(.*)$/;
@@ -242417,7 +242957,7 @@ function parseTranscript(content) {
242417
242957
  return cues;
242418
242958
  }
242419
242959
  function readTranscript(filePath) {
242420
- const content = fs39.readFileSync(filePath, "utf8");
242960
+ const content = fs40.readFileSync(filePath, "utf8");
242421
242961
  return parseTranscript(content);
242422
242962
  }
242423
242963
  function formatTimestamp(seconds) {
@@ -242477,7 +243017,7 @@ function formatCues(cues) {
242477
243017
 
242478
243018
  // src/cli_stats.ts
242479
243019
  init_define_import_meta_env();
242480
- import * as fs40 from "node:fs";
243020
+ import * as fs41 from "node:fs";
242481
243021
  import * as path46 from "node:path";
242482
243022
  function writeRaw(text) {
242483
243023
  process.stdout.write(ensureNewline(text));
@@ -242501,11 +243041,11 @@ function renderTopSessionFiles(topN = 5) {
242501
243041
  function renderTopSessionFilesFromDisk(topN = 5, overrideSessionsDir) {
242502
243042
  try {
242503
243043
  const sessionsDir = overrideSessionsDir ?? path46.join(dataDir(), "sessions");
242504
- if (!fs40.existsSync(sessionsDir)) return "";
242505
- const files = fs40.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs40.statSync(path46.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
243044
+ if (!fs41.existsSync(sessionsDir)) return "";
243045
+ const files = fs41.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs41.statSync(path46.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
242506
243046
  for (const { name: name2 } of files) {
242507
243047
  try {
242508
- const raw = fs40.readFileSync(path46.join(sessionsDir, name2), "utf-8");
243048
+ const raw = fs41.readFileSync(path46.join(sessionsDir, name2), "utf-8");
242509
243049
  const data = JSON.parse(raw);
242510
243050
  const filesList = data["files"];
242511
243051
  if (!Array.isArray(filesList)) continue;
@@ -242560,19 +243100,19 @@ function runStats(opts = {}) {
242560
243100
 
242561
243101
  // src/cli_doctor.ts
242562
243102
  init_define_import_meta_env();
242563
- import * as fs43 from "fs";
243103
+ import * as fs44 from "fs";
242564
243104
  import * as path49 from "path";
242565
243105
  import { execSync, spawnSync as spawnSync6 } from "child_process";
242566
243106
 
242567
243107
  // src/cli_context_stats.ts
242568
243108
  init_define_import_meta_env();
242569
- import * as fs42 from "node:fs";
243109
+ import * as fs43 from "node:fs";
242570
243110
  import * as os21 from "node:os";
242571
243111
  import * as path48 from "node:path";
242572
243112
 
242573
243113
  // src/memory_prune.ts
242574
243114
  init_define_import_meta_env();
242575
- import * as fs41 from "node:fs";
243115
+ import * as fs42 from "node:fs";
242576
243116
  import * as path47 from "node:path";
242577
243117
  var ENTRY_RE = /^\s*-\s*\[(?<title>[^\]]+)\]\((?<target>[^)]+?\.md)\)/;
242578
243118
  function parseIndex(text) {
@@ -242620,7 +243160,7 @@ function pruneIndex(memoryDir, opts) {
242620
243160
  const memoryMd = path47.join(memoryDir, "MEMORY.md");
242621
243161
  let text;
242622
243162
  try {
242623
- text = fs41.readFileSync(memoryMd, "utf-8");
243163
+ text = fs42.readFileSync(memoryMd, "utf-8");
242624
243164
  } catch {
242625
243165
  return result;
242626
243166
  }
@@ -242632,7 +243172,7 @@ function pruneIndex(memoryDir, opts) {
242632
243172
  for (const entry of entries) {
242633
243173
  const targetPath = path47.join(memoryDir, entry.target);
242634
243174
  const foldedTarget = foldPath(entry.target);
242635
- if (!fs41.existsSync(targetPath)) {
243175
+ if (!fs42.existsSync(targetPath)) {
242636
243176
  dead.push(entry);
242637
243177
  } else if (seenTargets.has(foldedTarget)) {
242638
243178
  dups.push(entry);
@@ -242672,7 +243212,7 @@ function pruneIndex(memoryDir, opts) {
242672
243212
  // src/cli_context_stats.ts
242673
243213
  function tok(filePath) {
242674
243214
  try {
242675
- const size = fs42.statSync(filePath).size;
243215
+ const size = fs43.statSync(filePath).size;
242676
243216
  return Math.floor(size / 4);
242677
243217
  } catch {
242678
243218
  return 0;
@@ -242684,7 +243224,7 @@ function findClaudeMdFiles(projectRoot) {
242684
243224
  let current = path48.resolve(projectRoot);
242685
243225
  while (true) {
242686
243226
  const candidate = path48.join(current, "CLAUDE.md");
242687
- if (!seen.has(candidate) && fs42.existsSync(candidate)) {
243227
+ if (!seen.has(candidate) && fs43.existsSync(candidate)) {
242688
243228
  found.push(candidate);
242689
243229
  seen.add(candidate);
242690
243230
  }
@@ -242693,7 +243233,7 @@ function findClaudeMdFiles(projectRoot) {
242693
243233
  current = parent;
242694
243234
  }
242695
243235
  const globalMd = path48.join(os21.homedir(), ".claude", "CLAUDE.md");
242696
- if (!seen.has(globalMd) && fs42.existsSync(globalMd)) {
243236
+ if (!seen.has(globalMd) && fs43.existsSync(globalMd)) {
242697
243237
  found.push(globalMd);
242698
243238
  }
242699
243239
  return found;
@@ -242701,11 +243241,11 @@ function findClaudeMdFiles(projectRoot) {
242701
243241
  function findMemoryMd(projectRoot) {
242702
243242
  try {
242703
243243
  const projectsDir = path48.join(os21.homedir(), ".claude", "projects");
242704
- if (!fs42.existsSync(projectsDir)) return null;
243244
+ if (!fs43.existsSync(projectsDir)) return null;
242705
243245
  const rootStr = path48.resolve(projectRoot);
242706
243246
  const expectedSlug = rootStr.replace(/[^A-Za-z0-9]/g, "-");
242707
243247
  const candidate = path48.join(projectsDir, expectedSlug, "memory", "MEMORY.md");
242708
- if (fs42.existsSync(candidate)) return candidate;
243248
+ if (fs43.existsSync(candidate)) return candidate;
242709
243249
  return null;
242710
243250
  } catch {
242711
243251
  return null;
@@ -242804,24 +243344,24 @@ function checkWorkerRunning() {
242804
243344
  }
242805
243345
  function checkDbExists(dataDir2) {
242806
243346
  const dbPath = path49.join(dataDir2, "global.db");
242807
- if (!fs43.existsSync(dbPath)) {
243347
+ if (!fs44.existsSync(dbPath)) {
242808
243348
  return {
242809
243349
  name: "Database",
242810
243350
  status: "warn",
242811
243351
  message: `global.db not found at ${dbPath}`
242812
243352
  };
242813
243353
  }
242814
- const sizeBytes = fs43.statSync(dbPath).size;
243354
+ const sizeBytes = fs44.statSync(dbPath).size;
242815
243355
  const SQLITE_HEADER = "SQLite format 3\0";
242816
243356
  let header = "";
242817
243357
  try {
242818
- const fd2 = fs43.openSync(dbPath, "r");
243358
+ const fd2 = fs44.openSync(dbPath, "r");
242819
243359
  try {
242820
243360
  const buf = Buffer.alloc(SQLITE_HEADER.length);
242821
- const bytesRead = fs43.readSync(fd2, buf, 0, buf.length, 0);
243361
+ const bytesRead = fs44.readSync(fd2, buf, 0, buf.length, 0);
242822
243362
  header = buf.toString("latin1", 0, bytesRead);
242823
243363
  } finally {
242824
- fs43.closeSync(fd2);
243364
+ fs44.closeSync(fd2);
242825
243365
  }
242826
243366
  } catch {
242827
243367
  }
@@ -242855,7 +243395,7 @@ function checkInstall() {
242855
243395
  }
242856
243396
  }
242857
243397
  function checkConfigValid(configPath2) {
242858
- if (!fs43.existsSync(configPath2)) {
243398
+ if (!fs44.existsSync(configPath2)) {
242859
243399
  return {
242860
243400
  name: "Config",
242861
243401
  status: "warn",
@@ -242863,7 +243403,7 @@ function checkConfigValid(configPath2) {
242863
243403
  };
242864
243404
  }
242865
243405
  try {
242866
- const content = fs43.readFileSync(configPath2, "utf-8");
243406
+ const content = fs44.readFileSync(configPath2, "utf-8");
242867
243407
  parse(content);
242868
243408
  return {
242869
243409
  name: "Config",
@@ -242889,9 +243429,9 @@ function formatDiskSpace(bytes) {
242889
243429
  return `${value.toFixed(1)} ${units[unitIndex]}`;
242890
243430
  }
242891
243431
  function checkDiskSpace(dataDir2) {
242892
- if (typeof fs43.statfsSync === "function") {
243432
+ if (typeof fs44.statfsSync === "function") {
242893
243433
  try {
242894
- const stats = fs43.statfsSync(dataDir2);
243434
+ const stats = fs44.statfsSync(dataDir2);
242895
243435
  const availableBytes = stats.bavail * stats.bsize;
242896
243436
  return { name: "Disk Space", status: "ok", message: `${formatDiskSpace(availableBytes)} available` };
242897
243437
  } catch {
@@ -242915,12 +243455,12 @@ function checkDiskSpace(dataDir2) {
242915
243455
  return { name: "Disk Space", status: "warn", message: "disk space check unavailable on this platform" };
242916
243456
  }
242917
243457
  function checkCopilotCli(configPath2, scriptPath) {
242918
- if (!fs43.existsSync(configPath2) || !fs43.existsSync(scriptPath)) {
243458
+ if (!fs44.existsSync(configPath2) || !fs44.existsSync(scriptPath)) {
242919
243459
  return null;
242920
243460
  }
242921
243461
  let config3;
242922
243462
  try {
242923
- config3 = JSON.parse(fs43.readFileSync(configPath2, "utf-8"));
243463
+ config3 = JSON.parse(fs44.readFileSync(configPath2, "utf-8"));
242924
243464
  } catch (err3) {
242925
243465
  return {
242926
243466
  name: "Copilot CLI",
@@ -242937,7 +243477,7 @@ function checkCopilotCli(configPath2, scriptPath) {
242937
243477
  };
242938
243478
  }
242939
243479
  const bakedExecPath = /^"([^"]+)"/.exec(preToolUseCommand)?.[1];
242940
- if (bakedExecPath !== void 0 && !fs43.existsSync(bakedExecPath)) {
243480
+ if (bakedExecPath !== void 0 && !fs44.existsSync(bakedExecPath)) {
242941
243481
  return {
242942
243482
  name: "Copilot CLI",
242943
243483
  status: "fail",
@@ -243025,16 +243565,16 @@ function runDoctorAndExit(opts) {
243025
243565
  try {
243026
243566
  const dir = skillOutputsDir();
243027
243567
  const pregenPath = path49.join(dir, "pregen.json");
243028
- if (fs43.existsSync(pregenPath)) {
243029
- const content = JSON.parse(fs43.readFileSync(pregenPath, "utf-8"));
243568
+ if (fs44.existsSync(pregenPath)) {
243569
+ const content = JSON.parse(fs44.readFileSync(pregenPath, "utf-8"));
243030
243570
  const pregenNames = new Set(content.names || []);
243031
243571
  const skills = [];
243032
243572
  try {
243033
- const entries = fs43.readdirSync(dir, { withFileTypes: true });
243573
+ const entries = fs44.readdirSync(dir, { withFileTypes: true });
243034
243574
  for (const entry of entries) {
243035
243575
  if (!entry.isFile() || !entry.name.endsWith(".meta")) continue;
243036
243576
  try {
243037
- const meta3 = JSON.parse(fs43.readFileSync(path49.join(dir, entry.name), "utf-8"));
243577
+ const meta3 = JSON.parse(fs44.readFileSync(path49.join(dir, entry.name), "utf-8"));
243038
243578
  if (meta3.skillName && !pregenNames.has(meta3.skillName)) {
243039
243579
  skills.push(meta3.skillName);
243040
243580
  }
@@ -243154,7 +243694,7 @@ async function getSectionContent(fileId, heading) {
243154
243694
 
243155
243695
  // src/pack.ts
243156
243696
  init_define_import_meta_env();
243157
- import * as fs44 from "node:fs";
243697
+ import * as fs45 from "node:fs";
243158
243698
  import * as path51 from "node:path";
243159
243699
 
243160
243700
  // node_modules/minimatch/dist/esm/index.js
@@ -245046,24 +245586,24 @@ function isPathWithinRoot(rootReal, resolvedPath) {
245046
245586
  function openWithinRoot(rootReal, p) {
245047
245587
  let fd2;
245048
245588
  try {
245049
- fd2 = fs44.openSync(p, "r");
245589
+ fd2 = fs45.openSync(p, "r");
245050
245590
  } catch {
245051
245591
  return null;
245052
245592
  }
245053
245593
  let ownershipTransferred = false;
245054
245594
  try {
245055
- const stat2 = fs44.fstatSync(fd2);
245595
+ const stat2 = fs45.fstatSync(fd2);
245056
245596
  if (!stat2.isFile()) return null;
245057
245597
  let realPath;
245058
245598
  try {
245059
- realPath = fs44.realpathSync(p);
245599
+ realPath = fs45.realpathSync(p);
245060
245600
  } catch {
245061
245601
  return "outside-root";
245062
245602
  }
245063
245603
  if (!isPathWithinRoot(rootReal, realPath)) return "outside-root";
245064
245604
  let realStat;
245065
245605
  try {
245066
- realStat = fs44.statSync(realPath);
245606
+ realStat = fs45.statSync(realPath);
245067
245607
  } catch {
245068
245608
  return "outside-root";
245069
245609
  }
@@ -245073,7 +245613,7 @@ function openWithinRoot(rootReal, p) {
245073
245613
  } finally {
245074
245614
  if (!ownershipTransferred) {
245075
245615
  try {
245076
- fs44.closeSync(fd2);
245616
+ fs45.closeSync(fd2);
245077
245617
  } catch {
245078
245618
  }
245079
245619
  }
@@ -245180,7 +245720,7 @@ function collectFiles(projectRoot, patterns, opts = {}) {
245180
245720
  const rootResolved = path51.resolve(projectRoot);
245181
245721
  let rootReal;
245182
245722
  try {
245183
- rootReal = fs44.realpathSync(rootResolved);
245723
+ rootReal = fs45.realpathSync(rootResolved);
245184
245724
  } catch {
245185
245725
  rootReal = rootResolved;
245186
245726
  }
@@ -245219,7 +245759,7 @@ function collectFiles(projectRoot, patterns, opts = {}) {
245219
245759
  }
245220
245760
  let content;
245221
245761
  try {
245222
- content = fs44.readFileSync(fd2, "utf8");
245762
+ content = fs45.readFileSync(fd2, "utf8");
245223
245763
  } catch {
245224
245764
  result.skipped.push(`${rel} (unreadable)`);
245225
245765
  continue;
@@ -245241,14 +245781,14 @@ function collectFiles(projectRoot, patterns, opts = {}) {
245241
245781
  result.total_lines += lines;
245242
245782
  result.total_tokens += tokens;
245243
245783
  } finally {
245244
- fs44.closeSync(fd2);
245784
+ fs45.closeSync(fd2);
245245
245785
  }
245246
245786
  }
245247
245787
  }
245248
245788
  return result;
245249
245789
  }
245250
245790
  function collectFromStdin(projectRoot, opts = {}) {
245251
- const input = fs44.readFileSync(0, "utf8");
245791
+ const input = fs45.readFileSync(0, "utf8");
245252
245792
  const paths = input.split("\n").map((ln2) => ln2.trim()).filter((ln2) => ln2.length > 0);
245253
245793
  return collectFiles(projectRoot, paths, opts);
245254
245794
  }
@@ -245378,7 +245918,7 @@ function estimateBudget(projectRoot, patterns, opts = {}) {
245378
245918
  const rootResolved = path51.resolve(projectRoot);
245379
245919
  let rootReal;
245380
245920
  try {
245381
- rootReal = fs44.realpathSync(rootResolved);
245921
+ rootReal = fs45.realpathSync(rootResolved);
245382
245922
  } catch {
245383
245923
  rootReal = rootResolved;
245384
245924
  }
@@ -245418,7 +245958,7 @@ function estimateBudget(projectRoot, patterns, opts = {}) {
245418
245958
  let lines;
245419
245959
  let tokens;
245420
245960
  try {
245421
- const data = fs44.readFileSync(fd2);
245961
+ const data = fs45.readFileSync(fd2);
245422
245962
  const sampleSize = Math.min(1e3, data.length);
245423
245963
  const sampleLines = (data.toString("utf8", 0, sampleSize).match(/\n/g) || []).length;
245424
245964
  lines = data.length > sampleSize ? Math.ceil(sampleLines * (data.length / sampleSize)) : sampleLines + 1;
@@ -245434,7 +245974,7 @@ function estimateBudget(projectRoot, patterns, opts = {}) {
245434
245974
  result.total_lines += lines;
245435
245975
  result.total_tokens += tokens;
245436
245976
  } finally {
245437
- fs44.closeSync(fd2);
245977
+ fs45.closeSync(fd2);
245438
245978
  }
245439
245979
  }
245440
245980
  }
@@ -245713,12 +246253,12 @@ function formatFailuresJson(result) {
245713
246253
 
245714
246254
  // src/text_commands.ts
245715
246255
  init_define_import_meta_env();
245716
- import * as fs46 from "fs";
246256
+ import * as fs47 from "fs";
245717
246257
  import * as path53 from "path";
245718
246258
 
245719
246259
  // src/project_memory.ts
245720
246260
  init_define_import_meta_env();
245721
- import * as fs45 from "node:fs";
246261
+ import * as fs46 from "node:fs";
245722
246262
  import * as os22 from "node:os";
245723
246263
  import * as path52 from "node:path";
245724
246264
  var MAX_ENTRIES = 30;
@@ -245767,10 +246307,10 @@ function parseTOML(content) {
245767
246307
  }
245768
246308
  function loadRaw(filePath) {
245769
246309
  try {
245770
- if (!fs45.existsSync(filePath)) {
246310
+ if (!fs46.existsSync(filePath)) {
245771
246311
  return {};
245772
246312
  }
245773
- const content = fs45.readFileSync(filePath, "utf-8");
246313
+ const content = fs46.readFileSync(filePath, "utf-8");
245774
246314
  return parseTOML(content);
245775
246315
  } catch {
245776
246316
  return {};
@@ -245820,15 +246360,15 @@ function unsetEntry(projectHash2, key) {
245820
246360
  }
245821
246361
  function clearAll(projectHash2) {
245822
246362
  const p = memoryPath(projectHash2);
245823
- if (fs45.existsSync(p)) {
246363
+ if (fs46.existsSync(p)) {
245824
246364
  save(p, {});
245825
246365
  }
245826
246366
  }
245827
246367
 
245828
246368
  // src/text_commands.ts
245829
246369
  function readInput(src) {
245830
- if (src !== void 0) return fs46.readFileSync(src, "utf8");
245831
- return fs46.readFileSync(0, "utf8");
246370
+ if (src !== void 0) return fs47.readFileSync(src, "utf8");
246371
+ return fs47.readFileSync(0, "utf8");
245832
246372
  }
245833
246373
  function splitLines(text) {
245834
246374
  return text.split(/\r?\n/);
@@ -245853,17 +246393,17 @@ function isInsideStringLiteral3(line, markerIndex) {
245853
246393
  const sqCount = countUnescapedQuotes2(before, "'");
245854
246394
  return dqCount % 2 !== 0 || sqCount % 2 !== 0;
245855
246395
  }
245856
- function escapeRegExp3(s) {
246396
+ function escapeRegExp4(s) {
245857
246397
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
245858
246398
  }
245859
246399
  function scanFileForTodos(filePath, kindSet) {
245860
246400
  let text;
245861
246401
  try {
245862
- text = fs46.readFileSync(filePath, "utf8");
246402
+ text = fs47.readFileSync(filePath, "utf8");
245863
246403
  } catch {
245864
246404
  return [];
245865
246405
  }
245866
- const kindPattern = [...kindSet].map(escapeRegExp3).join("|");
246406
+ const kindPattern = [...kindSet].map(escapeRegExp4).join("|");
245867
246407
  const re = new RegExp(`\\b(${kindPattern})\\s*:?\\s*(.*)`, "i");
245868
246408
  const items = [];
245869
246409
  const lines = splitLines(text);
@@ -245883,7 +246423,7 @@ function collectTodoFiles(patterns) {
245883
246423
  for (const p of patterns) {
245884
246424
  const abs = path53.resolve(p);
245885
246425
  try {
245886
- const stat2 = fs46.statSync(abs);
246426
+ const stat2 = fs47.statSync(abs);
245887
246427
  if (stat2.isDirectory()) {
245888
246428
  results.push(...walkProject(abs).files);
245889
246429
  } else {
@@ -246101,15 +246641,15 @@ var LOCK_PRIORITY = [
246101
246641
  "Cargo.lock"
246102
246642
  ];
246103
246643
  function findLockfile(startPath) {
246104
- const stat2 = fs46.statSync(startPath, { throwIfNoEntry: false });
246105
- const dir = stat2?.isDirectory() !== false && fs46.existsSync(startPath) && fs46.statSync(startPath).isDirectory() ? startPath : path53.dirname(startPath);
246644
+ const stat2 = fs47.statSync(startPath, { throwIfNoEntry: false });
246645
+ const dir = stat2?.isDirectory() !== false && fs47.existsSync(startPath) && fs47.statSync(startPath).isDirectory() ? startPath : path53.dirname(startPath);
246106
246646
  const found = [];
246107
246647
  for (const name2 of LOCK_PRIORITY) {
246108
246648
  const candidate = path53.join(dir, name2);
246109
- if (fs46.existsSync(candidate)) found.push(candidate);
246649
+ if (fs47.existsSync(candidate)) found.push(candidate);
246110
246650
  }
246111
246651
  try {
246112
- const entries = fs46.readdirSync(dir);
246652
+ const entries = fs47.readdirSync(dir);
246113
246653
  for (const e of entries) {
246114
246654
  if (/^requirements.*\.txt$/.test(e)) {
246115
246655
  const p = path53.join(dir, e);
@@ -246227,7 +246767,7 @@ function parseRequirementsTxt(content) {
246227
246767
  }
246228
246768
  function parseLockFile(filePath) {
246229
246769
  const base = path53.basename(filePath);
246230
- const content = fs46.readFileSync(filePath, "utf8");
246770
+ const content = fs47.readFileSync(filePath, "utf8");
246231
246771
  if (base === "package-lock.json") return { format: "npm", deps: parsePackageLockJson(content) };
246232
246772
  if (base === "yarn.lock") return { format: "yarn", deps: parseYarnLock(content) };
246233
246773
  if (base === "poetry.lock") return { format: "poetry", deps: parseTomlPackages(content) };
@@ -246325,7 +246865,7 @@ function loadAllSessionReadCounts() {
246325
246865
  const totals = /* @__PURE__ */ new Map();
246326
246866
  let entries;
246327
246867
  try {
246328
- entries = fs46.readdirSync(sessionsDir, { withFileTypes: true });
246868
+ entries = fs47.readdirSync(sessionsDir, { withFileTypes: true });
246329
246869
  } catch {
246330
246870
  return totals;
246331
246871
  }
@@ -246334,7 +246874,7 @@ function loadAllSessionReadCounts() {
246334
246874
  const filePath = path53.join(sessionsDir, entry.name);
246335
246875
  let raw;
246336
246876
  try {
246337
- raw = JSON.parse(fs46.readFileSync(filePath, "utf8"));
246877
+ raw = JSON.parse(fs47.readFileSync(filePath, "utf8"));
246338
246878
  } catch {
246339
246879
  continue;
246340
246880
  }
@@ -246408,7 +246948,7 @@ function detectWalkMode(cwd) {
246408
246948
  if (project?.marker === ".git") return "git";
246409
246949
  let cur = cwd;
246410
246950
  while (true) {
246411
- if (fs46.existsSync(path53.join(cur, ".git"))) return "git";
246951
+ if (fs47.existsSync(path53.join(cur, ".git"))) return "git";
246412
246952
  const parent = path53.dirname(cur);
246413
246953
  if (parent === cur) break;
246414
246954
  cur = parent;
@@ -246516,6 +247056,9 @@ var CACHE_ENV_GATES = [
246516
247056
  function pad(s, n) {
246517
247057
  return s.length >= n ? s : s + " ".repeat(n - s.length);
246518
247058
  }
247059
+ function listParentSessionBlobs() {
247060
+ return listBlobs(SESSIONS_SUBDIR).filter((b) => !b.id.includes(AGENT_SALT_MARKER)).sort((a, b) => b.mtime - a.mtime);
247061
+ }
246519
247062
  function cmdBashHistory(opts) {
246520
247063
  let limit = 30;
246521
247064
  if (opts.limit !== void 0) {
@@ -246718,7 +247261,7 @@ function cmdCompactHint(opts) {
246718
247261
  }
246719
247262
  }
246720
247263
  function cmdSessionSummary(opts) {
246721
- const blobs = listBlobs(SESSIONS_SUBDIR).sort((a, b) => b.mtime - a.mtime);
247264
+ const blobs = listParentSessionBlobs();
246722
247265
  if (blobs.length === 0) {
246723
247266
  if (opts.json === true) {
246724
247267
  process.stdout.write(JSON.stringify({ sessionCount: 0, message: "no session blobs found" }, null, 2) + "\n");
@@ -246751,7 +247294,7 @@ function cmdSessionSummary(opts) {
246751
247294
  }
246752
247295
  function cmdCost(opts) {
246753
247296
  if (opts.session === true) {
246754
- const blobs = listBlobs(SESSIONS_SUBDIR).sort((a, b) => b.mtime - a.mtime);
247297
+ const blobs = listParentSessionBlobs();
246755
247298
  if (blobs.length === 0) {
246756
247299
  if (opts.json === true) {
246757
247300
  process.stdout.write(JSON.stringify({ session: true, message: "no session blobs found" }, null, 2) + "\n");
@@ -246790,7 +247333,7 @@ function cmdBaseline(opts) {
246790
247333
 
246791
247334
  // src/config_commands.ts
246792
247335
  init_define_import_meta_env();
246793
- import * as fs47 from "node:fs";
247336
+ import * as fs48 from "node:fs";
246794
247337
  import * as os23 from "node:os";
246795
247338
  import * as path54 from "node:path";
246796
247339
 
@@ -247088,6 +247631,11 @@ function levenshtein2(a, b, cap = 3) {
247088
247631
  function closestKeys(unknown2, known) {
247089
247632
  return known.map((k) => ({ k, d: levenshtein2(unknown2, k) })).filter((x) => x.d <= 3).sort((a, b) => a.d - b.d).slice(0, 3).map((x) => x.k);
247090
247633
  }
247634
+ function didYouMeanKeySuffix(unknownKey) {
247635
+ const knownKeys = flattenConfig(defaultConfig()).map(([k]) => k);
247636
+ const suggestions = closestKeys(unknownKey, knownKeys);
247637
+ return suggestions.length > 0 ? ` (did you mean: ${suggestions.join(", ")}?)` : "";
247638
+ }
247091
247639
  function walkGet(obj, parts) {
247092
247640
  let cur = obj;
247093
247641
  for (const part of parts) {
@@ -247164,15 +247712,13 @@ function cmdConfig(opts) {
247164
247712
  }
247165
247713
  if (action === "get") {
247166
247714
  if (!opts.key) {
247167
- emitErr4("config get requires a key (e.g. compact_assist.enabled)");
247168
- throw new Error("missing key");
247715
+ throw new Error("config get requires a key (e.g. compact_assist.enabled)");
247169
247716
  }
247170
247717
  const parts = opts.key.split(".");
247171
247718
  const cfg = loadConfig();
247172
247719
  const result = walkGet(cfg, parts);
247173
247720
  if (!result.found) {
247174
- emitErr4(`key not found: ${opts.key}`);
247175
- throw new Error(`key not found: ${opts.key}`);
247721
+ throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
247176
247722
  }
247177
247723
  if (opts.json === true) {
247178
247724
  emit4(JSON.stringify({ key: opts.key, value: result.value }, null, 2));
@@ -247183,28 +247729,23 @@ function cmdConfig(opts) {
247183
247729
  }
247184
247730
  if (action === "set") {
247185
247731
  if (!opts.key) {
247186
- emitErr4("config set requires a key (e.g. compact_assist.enabled)");
247187
- throw new Error("missing key");
247732
+ throw new Error("config set requires a key (e.g. compact_assist.enabled)");
247188
247733
  }
247189
247734
  if (opts.value === void 0) {
247190
- emitErr4("config set requires a value");
247191
- throw new Error("missing value");
247735
+ throw new Error("config set requires a value");
247192
247736
  }
247193
247737
  const parts = opts.key.split(".");
247194
247738
  const cfg = loadPersistedConfig();
247195
247739
  const ref = walkParent(cfg, parts);
247196
247740
  if (!ref) {
247197
- emitErr4(`key not found: ${opts.key}`);
247198
- throw new Error(`key not found: ${opts.key}`);
247741
+ throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
247199
247742
  }
247200
247743
  const existing = ref.parent[ref.leaf];
247201
247744
  if (existing === void 0) {
247202
- emitErr4(`key not found: ${opts.key}`);
247203
- throw new Error(`key not found: ${opts.key}`);
247745
+ throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
247204
247746
  }
247205
247747
  if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
247206
- emitErr4(`config set: '${opts.key}' is a section, not a settable field \u2014 set an individual key within it instead (e.g. ${opts.key}.<field>)`);
247207
- throw new Error(`cannot set a whole config section: ${opts.key}`);
247748
+ throw new Error(`config set: '${opts.key}' is a section, not a settable field \u2014 set an individual key within it instead (e.g. ${opts.key}.<field>)`);
247208
247749
  }
247209
247750
  const defaultAtKey = walkGet(defaultConfig(), parts);
247210
247751
  const coerced = coerce2(opts.value, existing, defaultAtKey.found ? defaultAtKey.value : void 0);
@@ -247213,8 +247754,7 @@ function cmdConfig(opts) {
247213
247754
  const revalidated = buildPersistedConfig(cfg);
247214
247755
  const revalidatedResult = walkGet(revalidated, parts);
247215
247756
  if (revalidatedResult.found && revalidatedResult.value !== coerced) {
247216
- emitErr4(`config set: ${opts.key} = ${coerced} is outside the allowed range (would be clamped to ${String(revalidatedResult.value)}); rejected`);
247217
- throw new Error(`value out of range for ${opts.key}: ${coerced}`);
247757
+ throw new Error(`config set: ${opts.key} = ${coerced} is outside the allowed range (would be clamped to ${String(revalidatedResult.value)}); rejected`);
247218
247758
  }
247219
247759
  }
247220
247760
  saveConfigSafe(cfg);
@@ -247243,7 +247783,7 @@ function cmdConfig(opts) {
247243
247783
  let raw = {};
247244
247784
  let parseErr = null;
247245
247785
  try {
247246
- const text = fs47.readFileSync(cfgFile, "utf8");
247786
+ const text = fs48.readFileSync(cfgFile, "utf8");
247247
247787
  raw = parse(text);
247248
247788
  } catch (e) {
247249
247789
  const code = e.code;
@@ -247294,8 +247834,7 @@ function cmdConfig(opts) {
247294
247834
  emit4(`config validate: ${findings.length} issue(s) found`);
247295
247835
  return;
247296
247836
  }
247297
- emitErr4(`config: unknown action '${action}'. Use list, get, set, or validate.`);
247298
- throw new Error(`unknown config action: ${action}`);
247837
+ throw new Error(`config: unknown action '${action}'. Use list, get, set, or validate.`);
247299
247838
  }
247300
247839
  function cmdProject(opts) {
247301
247840
  const { action } = opts;
@@ -247347,7 +247886,7 @@ function cmdProject(opts) {
247347
247886
  const before = cfg.worker.blocked_roots;
247348
247887
  const after = before.filter((r) => {
247349
247888
  try {
247350
- return fs47.existsSync(r);
247889
+ return fs48.existsSync(r);
247351
247890
  } catch {
247352
247891
  return false;
247353
247892
  }
@@ -247397,7 +247936,7 @@ function cmdCompactDoc(opts) {
247397
247936
  if (opts.force === true || !fresh) {
247398
247937
  let sourceText;
247399
247938
  try {
247400
- sourceText = fs47.readFileSync(resolved, "utf-8");
247939
+ sourceText = fs48.readFileSync(resolved, "utf-8");
247401
247940
  } catch {
247402
247941
  emitErr4(`compact-doc: could not read or compact '${resolved}'`);
247403
247942
  throw new Error(`could not compact: ${resolved}`);
@@ -247468,7 +248007,7 @@ async function cmdFetchImage(opts) {
247468
248007
  outData = buf;
247469
248008
  shrunkBytes = originalBytes;
247470
248009
  }
247471
- fs47.writeFileSync(outPath, outData);
248010
+ fs48.writeFileSync(outPath, outData);
247472
248011
  if (opts.json === true) {
247473
248012
  emit4(JSON.stringify({ url: opts.url, out: outPath, originalBytes, shrunkBytes, wasShrunk }, null, 2));
247474
248013
  return;
@@ -247577,24 +248116,41 @@ async function cmdIndex(pathArg, opts = {}) {
247577
248116
  const blockedRoots = loadConfig().worker.blocked_roots;
247578
248117
  let indexed = 0;
247579
248118
  let failed = 0;
248119
+ let skipped = 0;
247580
248120
  for (const f of files) {
247581
248121
  const key = resolveIndexPath(f);
247582
248122
  if (isUnderBlockedRoot(key, blockedRoots)) continue;
247583
248123
  if (detectLanguage(key) === "unknown") continue;
247584
- try {
247585
- indexFileSync(key, dbPath);
247586
- } catch (e) {
247587
- failed += 1;
247588
- err2(`token-goat: index: failed to index '${key}': ${extractErrorMessage(e)}`);
248124
+ const sha = fingerprintFile(key);
248125
+ const entry = sha !== null ? getFileEntry(key, dbPath) : null;
248126
+ const parseUnchanged = sha !== null && entry?.sha === sha;
248127
+ const embeddingsEnabled = loadConfig().indexing?.embeddings_enabled ?? true;
248128
+ const embedUnchanged = parseUnchanged && sha !== null && entry?.embedSha === (embeddingsEnabled ? sha : disabledEmbedSha(sha));
248129
+ if (parseUnchanged && embedUnchanged) {
248130
+ skipped += 1;
247589
248131
  continue;
247590
248132
  }
247591
- await indexFileEmbeddings(key, dbPath);
248133
+ if (!parseUnchanged) {
248134
+ try {
248135
+ indexFileSync(key, dbPath);
248136
+ } catch (e) {
248137
+ failed += 1;
248138
+ err2(`token-goat: index: failed to index '${key}': ${extractErrorMessage(e)}`);
248139
+ continue;
248140
+ }
248141
+ }
248142
+ if (!embedUnchanged) {
248143
+ await indexFileEmbeddings(key, dbPath, sha ?? void 0);
248144
+ }
247592
248145
  indexed += 1;
247593
248146
  }
247594
248147
  const pruned = pruneDeletedFiles(resolveIndexPath(root), dbPath);
247595
248148
  out(
247596
- `Indexed ${indexed} files into the symbol index.${pruned > 0 ? ` Pruned ${pruned} deleted file(s).` : ""}${failed > 0 ? ` Failed to index ${failed} file(s) (see stderr).` : ""}`
248149
+ `Indexed ${indexed} files into the symbol index.${skipped > 0 ? ` Skipped ${skipped} unchanged file(s).` : ""}${pruned > 0 ? ` Pruned ${pruned} deleted file(s).` : ""}${failed > 0 ? ` Failed to index ${failed} file(s) (see stderr).` : ""}`
247597
248150
  );
248151
+ if (indexed === 0 && failed > 0) {
248152
+ process.exitCode = 1;
248153
+ }
247598
248154
  }
247599
248155
  function cmdMap(opts) {
247600
248156
  const compact = opts.compact === true;
@@ -247684,15 +248240,15 @@ async function cmdInstall(opts) {
247684
248240
  }
247685
248241
  try {
247686
248242
  const skillDir2 = path55.join(homedir15(), ".claude", "skills");
247687
- if (fs48.existsSync(skillDir2)) {
247688
- const entries = fs48.readdirSync(skillDir2, { withFileTypes: true });
248243
+ if (fs49.existsSync(skillDir2)) {
248244
+ const entries = fs49.readdirSync(skillDir2, { withFileTypes: true });
247689
248245
  const skillNames = [];
247690
248246
  const sessionId = getSessionId();
247691
248247
  for (const entry of entries) {
247692
248248
  if (!entry.isDirectory()) continue;
247693
248249
  const skillFile = path55.join(skillDir2, entry.name, "SKILL.md");
247694
- if (fs48.existsSync(skillFile)) {
247695
- const body = fs48.readFileSync(skillFile, "utf-8");
248250
+ if (fs49.existsSync(skillFile)) {
248251
+ const body = fs49.readFileSync(skillFile, "utf-8");
247696
248252
  const compact = extractCompactFromMarker(body);
247697
248253
  if (compact === null) continue;
247698
248254
  const sourceSha = contentHash(body);
@@ -247702,10 +248258,10 @@ async function cmdInstall(opts) {
247702
248258
  }
247703
248259
  if (skillNames.length > 0) {
247704
248260
  const dir = skillOutputsDir();
247705
- await fs48.promises.mkdir(dir, { recursive: true });
248261
+ await fs49.promises.mkdir(dir, { recursive: true });
247706
248262
  const pregenPath = path55.join(dir, "pregen.json");
247707
248263
  const pregenData = { ts: Date.now(), names: skillNames };
247708
- await fs48.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
248264
+ await fs49.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
247709
248265
  out(`Pre-generated ${skillNames.length} skill compacts.`);
247710
248266
  }
247711
248267
  }
@@ -247870,11 +248426,11 @@ function cmdBashOutput(id, opts) {
247870
248426
  }
247871
248427
  let content;
247872
248428
  try {
247873
- const st = fs48.statSync(opts.file);
248429
+ const st = fs49.statSync(opts.file);
247874
248430
  if (st.isFIFO() || st.isSocket()) {
247875
248431
  throw new CliError(`--file '${opts.file}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
247876
248432
  }
247877
- content = fs48.readFileSync(opts.file, "utf-8");
248433
+ content = fs49.readFileSync(opts.file, "utf-8");
247878
248434
  } catch (e) {
247879
248435
  if (e instanceof CliError) throw e;
247880
248436
  throw new CliError(`cannot read file: ${opts.file}`);
@@ -248106,7 +248662,7 @@ async function cmdSkillBody(name2, opts) {
248106
248662
  if (filePath === null) {
248107
248663
  throw new CliError(`skill '${name2}' not found`);
248108
248664
  }
248109
- const body = fs48.readFileSync(filePath, "utf-8");
248665
+ const body = fs49.readFileSync(filePath, "utf-8");
248110
248666
  if (opts.compact === true) {
248111
248667
  out(extractCompactFromMarker(body) ?? body);
248112
248668
  } else {
@@ -248123,7 +248679,7 @@ async function cmdSkillCompact(name2, opts) {
248123
248679
  for (const skill of skills) {
248124
248680
  const filePath = await getSkillFilePath(skill.name);
248125
248681
  if (!filePath) continue;
248126
- const body2 = fs48.readFileSync(filePath, "utf-8");
248682
+ const body2 = fs49.readFileSync(filePath, "utf-8");
248127
248683
  const compact2 = extractCompactFromMarker(body2);
248128
248684
  if (compact2 === null) continue;
248129
248685
  const sourceSha2 = contentHash(body2);
@@ -248141,10 +248697,10 @@ async function cmdSkillCompact(name2, opts) {
248141
248697
  let cacheName;
248142
248698
  let sourcePath;
248143
248699
  if (opts.path !== void 0 && opts.path !== "") {
248144
- if (!fs48.existsSync(opts.path)) {
248700
+ if (!fs49.existsSync(opts.path)) {
248145
248701
  throw new CliError(`skill file not found: ${opts.path}`);
248146
248702
  }
248147
- body = fs48.readFileSync(opts.path, "utf-8");
248703
+ body = fs49.readFileSync(opts.path, "utf-8");
248148
248704
  cacheName = name2 ?? path55.basename(path55.dirname(path55.resolve(opts.path)));
248149
248705
  sourcePath = path55.resolve(opts.path);
248150
248706
  } else {
@@ -248155,7 +248711,7 @@ async function cmdSkillCompact(name2, opts) {
248155
248711
  if (filePath === null) {
248156
248712
  throw new CliError(`skill '${name2}' not found`);
248157
248713
  }
248158
- body = fs48.readFileSync(filePath, "utf-8");
248714
+ body = fs49.readFileSync(filePath, "utf-8");
248159
248715
  cacheName = name2;
248160
248716
  sourcePath = filePath;
248161
248717
  }
@@ -248264,8 +248820,8 @@ async function cmdSkillDiff(name2) {
248264
248820
  }
248265
248821
  const newer = versions[0];
248266
248822
  const older = versions[1];
248267
- const newerBody = await fs48.promises.readFile(path55.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
248268
- const olderBody = await fs48.promises.readFile(path55.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
248823
+ const newerBody = await fs49.promises.readFile(path55.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
248824
+ const olderBody = await fs49.promises.readFile(path55.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
248269
248825
  if (newerBody === null || olderBody === null) {
248270
248826
  out(`only one cached version of '${name2}'`);
248271
248827
  return;
@@ -248294,7 +248850,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
248294
248850
  if (!filePath) {
248295
248851
  throw new CliError(`skill '${skillName}' not found`);
248296
248852
  }
248297
- const body = fs48.readFileSync(filePath, "utf-8");
248853
+ const body = fs49.readFileSync(filePath, "utf-8");
248298
248854
  const extracted = extractNamedSection(body, heading);
248299
248855
  if (!extracted) {
248300
248856
  process.exitCode = 1;
@@ -248304,7 +248860,7 @@ async function cmdSkillSection(nameHeading, headingArg) {
248304
248860
  }
248305
248861
  function atomicWriteBuffer(dest, data) {
248306
248862
  try {
248307
- if (fs48.statSync(dest).isDirectory()) {
248863
+ if (fs49.statSync(dest).isDirectory()) {
248308
248864
  const e = Object.assign(new Error(`EISDIR: illegal operation on a directory, open '${dest}'`), { code: "EISDIR", path: dest });
248309
248865
  throw e;
248310
248866
  }
@@ -248314,15 +248870,15 @@ function atomicWriteBuffer(dest, data) {
248314
248870
  const rnd = Math.random().toString(36).slice(2, 8);
248315
248871
  const tmp = path55.join(path55.dirname(path55.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
248316
248872
  try {
248317
- fs48.writeFileSync(tmp, data, { mode: 384 });
248873
+ fs49.writeFileSync(tmp, data, { mode: 384 });
248318
248874
  withRetryOnLock(() => {
248319
248875
  try {
248320
- fs48.renameSync(tmp, dest);
248876
+ fs49.renameSync(tmp, dest);
248321
248877
  } catch (e) {
248322
248878
  if (e.code === "EXDEV") {
248323
- fs48.copyFileSync(tmp, dest);
248879
+ fs49.copyFileSync(tmp, dest);
248324
248880
  try {
248325
- fs48.unlinkSync(tmp);
248881
+ fs49.unlinkSync(tmp);
248326
248882
  } catch (ue) {
248327
248883
  process.stderr.write(`token-goat write-file: warning: could not remove temp file ${tmp}: ${ue.message}
248328
248884
  `);
@@ -248334,7 +248890,7 @@ function atomicWriteBuffer(dest, data) {
248334
248890
  });
248335
248891
  } catch (e) {
248336
248892
  try {
248337
- fs48.unlinkSync(tmp);
248893
+ fs49.unlinkSync(tmp);
248338
248894
  } catch {
248339
248895
  }
248340
248896
  throw e;
@@ -248462,7 +249018,7 @@ function readFileBoundedRaw(filePath, label, allowStdIn = false) {
248462
249018
  throw new CliError(`${label} ${filePath} requires piped input; use ${altLabel} for interactive use`);
248463
249019
  }
248464
249020
  try {
248465
- const st = fs48.statSync(filePath);
249021
+ const st = fs49.statSync(filePath);
248466
249022
  if (st.isFIFO() || st.isSocket()) {
248467
249023
  throw new CliError(`${label} '${filePath}' is a special file (FIFO or socket) \u2014 only regular files are supported`);
248468
249024
  }
@@ -248470,7 +249026,7 @@ function readFileBoundedRaw(filePath, label, allowStdIn = false) {
248470
249026
  if (st.size > maxBytes) {
248471
249027
  throw new CliError(`${label} '${filePath}' exceeds size limit (${Math.round(st.size / 1024 / 1024)} MB); set TOKEN_GOAT_MAX_STDIN_MB to override`);
248472
249028
  }
248473
- return fs48.readFileSync(filePath);
249029
+ return fs49.readFileSync(filePath);
248474
249030
  } catch (e) {
248475
249031
  if (e instanceof CliError) throw e;
248476
249032
  mapFsError(e, filePath);
@@ -248671,7 +249227,7 @@ ${content}`);
248671
249227
  }
248672
249228
  function expandGlobs(root, patterns) {
248673
249229
  const out2 = [];
248674
- const globFn = fs48["globSync"];
249230
+ const globFn = fs49["globSync"];
248675
249231
  for (const p of patterns) {
248676
249232
  if (globFn !== void 0 && (p.includes("*") || p.includes("?") || p.includes("{"))) {
248677
249233
  try {
@@ -248718,14 +249274,14 @@ function cmdPack(patterns, opts) {
248718
249274
  }
248719
249275
  let instruction;
248720
249276
  if (opts.instructionFile !== void 0) {
248721
- instruction = fs48.readFileSync(opts.instructionFile, "utf8");
249277
+ instruction = fs49.readFileSync(opts.instructionFile, "utf8");
248722
249278
  }
248723
249279
  const formatted = formatPack(result, style, {
248724
249280
  ...opts.lineNumbers === true ? { line_numbers: true } : {},
248725
249281
  ...instruction !== void 0 ? { instruction } : {}
248726
249282
  });
248727
249283
  if (opts.output !== void 0) {
248728
- fs48.writeFileSync(opts.output, formatted, "utf8");
249284
+ fs49.writeFileSync(opts.output, formatted, "utf8");
248729
249285
  } else {
248730
249286
  out(formatted);
248731
249287
  }
@@ -248805,7 +249361,7 @@ function cmdBudget(patterns, opts) {
248805
249361
  }
248806
249362
  function cmdFailures(src, opts) {
248807
249363
  try {
248808
- const text = src !== void 0 ? fs48.readFileSync(src, "utf8") : fs48.readFileSync(0, "utf8");
249364
+ const text = src !== void 0 ? fs49.readFileSync(src, "utf8") : fs49.readFileSync(0, "utf8");
248809
249365
  const result = extractFailures(text, opts.runner !== void 0 ? { runner: opts.runner } : {});
248810
249366
  out(opts.json === true ? formatFailuresJson(result) : formatFailuresText(result));
248811
249367
  process.exitCode = 0;