token-goat 2.6.28 → 2.6.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49,7 +49,7 @@ var init_define_import_meta_env = __esm({
49
49
  import { createRequire } from "node:module";
50
50
  function resolveVersion() {
51
51
  if (true) {
52
- return "2.6.28";
52
+ return "2.6.29";
53
53
  }
54
54
  const require2 = createRequire(import.meta.url);
55
55
  const pkg = require2("../package.json");
@@ -2141,8 +2141,9 @@ function buildGuidanceBody(fallbackToolClause) {
2141
2141
  "- pulling one value or subtree out of a JSON/YAML file (manifest, lockfile, spec, config) \u2192 `json-query file 'a.b.c'` / `yaml-query file 'a.b.c'`",
2142
2142
  "- opening an image to check its dimensions, format, or size \u2192 `image-meta file`",
2143
2143
  "- opening a screenshot, diagram, or scan to read the text in it \u2192 `image-text file`",
2144
+ "- opening a PDF or Office document \u2192 inspect its format first, then read a narrow slice: PDF `pdf-meta`/`pdf-outline` then `pdf-extract`; Word `docx-outline` then `docx-text`; PowerPoint `pptx-outline` then `pptx-slide`/`pptx-notes`; Excel `xlsx-sheets` then `xlsx-head`/`xlsx-range`/`xlsx-query`",
2144
2145
  "",
2145
- 'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`, `json-outline file`/`yaml-outline`, `bash-output`/`web-output`/`mcp-output`, `gdrive-sections <file-id>`, `image-meta file`/`image-text file`.',
2146
+ 'Commands: `symbol NAME`, `read "file::symbol"`, `brief "file::symbol"`, `section "file::Heading"`, `semantic "description"`, `outline file`/`skeleton file`, `map --compact`, `refs file::symbol --callers`, `changed --symbol`, `config-get file KEY`, `json-query file \'a.b.c\'`/`yaml-query`, `json-outline file`/`yaml-outline`, `bash-output`/`web-output`/`mcp-output`, `gdrive-sections <file-id>`, `image-meta file`/`image-text file`, `pdf-meta`/`pdf-outline`/`pdf-extract`, `docx-outline`/`docx-text`, `pptx-outline`/`pptx-slide`/`pptx-notes`/`pptx-text`, `xlsx-sheets`/`xlsx-head`/`xlsx-range`/`xlsx-query`.',
2146
2147
  "",
2147
2148
  "Sub-agent briefs must carry this gate verbatim: a sub-agent inherits none of this context and its reads spend the same token budget.",
2148
2149
  "",
@@ -3643,6 +3644,12 @@ function envInt(key, defaultVal, min, max) {
3643
3644
  if (max !== void 0) clamped = Math.min(max, clamped);
3644
3645
  return clamped;
3645
3646
  }
3647
+ function envStrList(key, defaultVal, delimiter3) {
3648
+ const raw = process.env[key];
3649
+ if (raw === void 0) return defaultVal;
3650
+ const entries = raw.split(delimiter3).map((s) => s.trim()).filter((s) => s !== "");
3651
+ return entries.length > 0 ? entries : defaultVal;
3652
+ }
3646
3653
  var FALSY_ENV_VALUES, TRUTHY_ENV_VALUES;
3647
3654
  var init_env = __esm({
3648
3655
  "src/env.ts"() {
@@ -3891,6 +3898,7 @@ var init_project = __esm({
3891
3898
 
3892
3899
  // src/config.ts
3893
3900
  import * as fs9 from "node:fs";
3901
+ import * as path10 from "node:path";
3894
3902
  function getDefaultConfig(section2) {
3895
3903
  return structuredClone(CONFIG_DEFAULTS[section2] ?? {});
3896
3904
  }
@@ -4459,6 +4467,8 @@ function _buildConfig(raw, projectRaw = {}) {
4459
4467
  const mcp = getDefaultConfig("mcp");
4460
4468
  mcp.confine_reads_to_project_root = validatedBool(mcp_raw["confine_reads_to_project_root"], mcp.confine_reads_to_project_root);
4461
4469
  mcp.confine_reads_to_project_root = envBool("TOKEN_GOAT_MCP_CONFINE_READS", mcp.confine_reads_to_project_root);
4470
+ mcp.allowed_roots = validatedStrList(mcp_raw["allowed_roots"], mcp.allowed_roots);
4471
+ mcp.allowed_roots = envStrList("TOKEN_GOAT_MCP_ALLOWED_ROOTS", mcp.allowed_roots, path10.delimiter);
4462
4472
  const hs_raw = section(raw, "hint_stats");
4463
4473
  const hs = getDefaultConfig("hint_stats");
4464
4474
  hs.suppress_threshold_pct = validatedInt(hs_raw["suppress_threshold_pct"], hs.suppress_threshold_pct, ...boundsOf("hint_stats.suppress_threshold_pct"));
@@ -4847,7 +4857,8 @@ var init_config = __esm({
4847
4857
  enabled: true
4848
4858
  },
4849
4859
  mcp: {
4850
- confine_reads_to_project_root: true
4860
+ confine_reads_to_project_root: true,
4861
+ allowed_roots: []
4851
4862
  },
4852
4863
  hint_stats: {
4853
4864
  suppress_threshold_pct: 15,
@@ -5036,6 +5047,7 @@ var init_config = __esm({
5036
5047
  "context.model_window_tokens": ["TOKEN_GOAT_MODEL_WINDOW_TOKENS"],
5037
5048
  "injection.enabled": ["TOKEN_GOAT_INJECTION_ENABLED"],
5038
5049
  "mcp.confine_reads_to_project_root": ["TOKEN_GOAT_MCP_CONFINE_READS"],
5050
+ "mcp.allowed_roots": ["TOKEN_GOAT_MCP_ALLOWED_ROOTS"],
5039
5051
  "indexing.embeddings_enabled": ["TOKEN_GOAT_EMBEDDINGS_ENABLED"]
5040
5052
  };
5041
5053
  }
@@ -5120,7 +5132,7 @@ var init_secret_redact = __esm({
5120
5132
  // src/db.ts
5121
5133
  import * as fs10 from "node:fs";
5122
5134
  import { createRequire as createRequire3 } from "node:module";
5123
- import * as path10 from "node:path";
5135
+ import * as path11 from "node:path";
5124
5136
  import Database from "better-sqlite3";
5125
5137
  function alterTableIdempotent(conn, sql) {
5126
5138
  try {
@@ -5173,8 +5185,8 @@ function initConnection(conn) {
5173
5185
  }
5174
5186
  }
5175
5187
  function resolveDbPath(dbPath) {
5176
- if (path10.isAbsolute(dbPath)) return dbPath;
5177
- if (dbPath.includes("/") || dbPath.includes("\\")) return path10.resolve(dbPath);
5188
+ if (path11.isAbsolute(dbPath)) return dbPath;
5189
+ if (dbPath.includes("/") || dbPath.includes("\\")) return path11.resolve(dbPath);
5178
5190
  return safeJoin(dataDir(), dbPath);
5179
5191
  }
5180
5192
  function connectionKey(dbPath) {
@@ -5185,7 +5197,7 @@ function getDb(dbPath) {
5185
5197
  const { resolved, key } = connectionKey(dbPath);
5186
5198
  const existing = _connections.get(key);
5187
5199
  if (existing !== void 0) return existing;
5188
- const dir = path10.dirname(resolved);
5200
+ const dir = path11.dirname(resolved);
5189
5201
  try {
5190
5202
  fs10.mkdirSync(dir, { recursive: true });
5191
5203
  } catch (e) {
@@ -6222,7 +6234,7 @@ var init_stats_renderer = __esm({
6222
6234
  });
6223
6235
 
6224
6236
  // src/stats.ts
6225
- import * as path11 from "node:path";
6237
+ import * as path12 from "node:path";
6226
6238
  function kindToSource(kind) {
6227
6239
  const src = KIND_TO_SOURCE[kind];
6228
6240
  if (src !== void 0) return src;
@@ -6258,7 +6270,7 @@ function incBucket(bucket, bytesSaved, tokensSaved) {
6258
6270
  }
6259
6271
  function getGlobalDb(homeDir) {
6260
6272
  const basePath = homeDir ? dataDirForHome(homeDir) : dataDir();
6261
- const dbPath = path11.join(basePath, "global.db");
6273
+ const dbPath = path12.join(basePath, "global.db");
6262
6274
  const db = getDb(dbPath);
6263
6275
  if (!_globalSchemaApplied.has(dbPath)) {
6264
6276
  db.exec(GLOBAL_SCHEMA_SQL);
@@ -6707,26 +6719,26 @@ CREATE INDEX IF NOT EXISTS idx_stats_kind ON stats(kind);
6707
6719
 
6708
6720
  // src/disk_cache.ts
6709
6721
  import * as fs11 from "node:fs";
6710
- import * as path12 from "node:path";
6722
+ import * as path13 from "node:path";
6711
6723
  import * as os8 from "node:os";
6712
6724
  function tokenGoatHome() {
6713
6725
  const override = process.env["TOKEN_GOAT_HOME"];
6714
6726
  if (override !== void 0 && override !== "") return override;
6715
- return path12.join(os8.homedir(), ".token-goat");
6727
+ return path13.join(os8.homedir(), ".token-goat");
6716
6728
  }
6717
6729
  function sanitizeId(id) {
6718
6730
  return sanitizeIdForFilename(id, 64);
6719
6731
  }
6720
6732
  function blobDir(subdir) {
6721
- return path12.join(tokenGoatHome(), subdir);
6733
+ return path13.join(tokenGoatHome(), subdir);
6722
6734
  }
6723
6735
  function blobPath(subdir, id) {
6724
6736
  const safe = sanitizeId(id);
6725
6737
  if (!safe) return null;
6726
6738
  const dir = blobDir(subdir);
6727
- const candidate = path12.join(dir, `${safe}.json`);
6739
+ const candidate = path13.join(dir, `${safe}.json`);
6728
6740
  try {
6729
- const rel = path12.relative(dir, candidate);
6741
+ const rel = path13.relative(dir, candidate);
6730
6742
  if (rel.startsWith("..")) return null;
6731
6743
  } catch {
6732
6744
  return null;
@@ -6773,7 +6785,7 @@ function storeBlob(subdir, id, value, opts = {}) {
6773
6785
  }
6774
6786
  if (Number.isFinite(maxBytesPerItem) && Buffer.byteLength(json2, "utf-8") > maxBytesPerItem) return false;
6775
6787
  try {
6776
- const dir = path12.dirname(p);
6788
+ const dir = path13.dirname(p);
6777
6789
  if (!fs11.existsSync(dir)) fs11.mkdirSync(dir, { recursive: true });
6778
6790
  atomicWriteText(p, json2);
6779
6791
  } catch {
@@ -6808,7 +6820,7 @@ function listBlobs(subdir) {
6808
6820
  const id = file2.slice(0, -5);
6809
6821
  let mtime = 0;
6810
6822
  try {
6811
- mtime = fs11.statSync(path12.join(dir, file2)).mtimeMs;
6823
+ mtime = fs11.statSync(path13.join(dir, file2)).mtimeMs;
6812
6824
  } catch {
6813
6825
  }
6814
6826
  const value = loadBlob(subdir, id);
@@ -6829,7 +6841,7 @@ function pruneBlobs(subdir, maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX
6829
6841
  let protectedEntry;
6830
6842
  for (const file2 of fs11.readdirSync(dir)) {
6831
6843
  if (!file2.endsWith(".json")) continue;
6832
- const full = path12.join(dir, file2);
6844
+ const full = path13.join(dir, file2);
6833
6845
  let stat2;
6834
6846
  try {
6835
6847
  stat2 = fs11.statSync(full);
@@ -7260,15 +7272,15 @@ var init_session = __esm({
7260
7272
 
7261
7273
  // src/session_store.ts
7262
7274
  import * as fs13 from "node:fs";
7263
- import * as path13 from "node:path";
7275
+ import * as path14 from "node:path";
7264
7276
  function sessionPath(sessionId) {
7265
7277
  if (!sessionId) return null;
7266
7278
  const safe = sanitizeIdForFilename(sessionId, 64);
7267
7279
  if (!safe) return null;
7268
- const dir = path13.join(tokenGoatHome(), SESSIONS_SUBDIR);
7269
- const candidate = path13.join(dir, `${safe}.json`);
7280
+ const dir = path14.join(tokenGoatHome(), SESSIONS_SUBDIR);
7281
+ const candidate = path14.join(dir, `${safe}.json`);
7270
7282
  try {
7271
- const rel = path13.relative(dir, candidate);
7283
+ const rel = path14.relative(dir, candidate);
7272
7284
  if (rel.startsWith("..")) return null;
7273
7285
  } catch {
7274
7286
  return null;
@@ -7503,13 +7515,13 @@ function listSiblingSessionStates(sessionId) {
7503
7515
  const safeSessionId = sanitizeIdForFilename(sessionId);
7504
7516
  if (!safeSessionId) return [];
7505
7517
  const prefix = `${safeSessionId}${AGENT_SALT_MARKER}`;
7506
- const dir = path13.join(tokenGoatHome(), SESSIONS_SUBDIR);
7518
+ const dir = path14.join(tokenGoatHome(), SESSIONS_SUBDIR);
7507
7519
  const out2 = [];
7508
7520
  try {
7509
7521
  if (!fs13.existsSync(dir)) return out2;
7510
7522
  for (const file2 of fs13.readdirSync(dir)) {
7511
7523
  if (!file2.endsWith(".json") || !file2.startsWith(prefix)) continue;
7512
- const state = readDiskState(path13.join(dir, file2));
7524
+ const state = readDiskState(path14.join(dir, file2));
7513
7525
  if (state !== null) out2.push(state);
7514
7526
  }
7515
7527
  } catch {
@@ -7528,7 +7540,7 @@ function saveSessionState(sessionId) {
7528
7540
  const p = sessionPath(sessionId);
7529
7541
  if (!p) return;
7530
7542
  try {
7531
- const dir = path13.dirname(p);
7543
+ const dir = path14.dirname(p);
7532
7544
  if (!fs13.existsSync(dir)) fs13.mkdirSync(dir, { recursive: true });
7533
7545
  const mem = exportSessionState();
7534
7546
  const writeMerged = () => {
@@ -8108,7 +8120,7 @@ var init_overflow_guard = __esm({
8108
8120
 
8109
8121
  // src/compact.ts
8110
8122
  import * as fs14 from "node:fs";
8111
- import * as path14 from "node:path";
8123
+ import * as path15 from "node:path";
8112
8124
  function tierForFraction(fill) {
8113
8125
  if (fill >= CONTEXT_TIER_CRITICAL) return "critical";
8114
8126
  if (fill >= CONTEXT_TIER_HOT) return "hot";
@@ -8175,7 +8187,7 @@ function inferSessionGoal(cache, maxTokens = 80) {
8175
8187
  const dirCounts = new Counter();
8176
8188
  for (const fpath of editedPaths) {
8177
8189
  try {
8178
- let parent = path14.dirname(fpath);
8190
+ let parent = path15.dirname(fpath);
8179
8191
  if (parent === ".") {
8180
8192
  parent = "root";
8181
8193
  } else if (parent.startsWith("./")) {
@@ -8251,7 +8263,7 @@ function isNoisePath(inputPath) {
8251
8263
  }
8252
8264
  function findLatestSessionId() {
8253
8265
  try {
8254
- const sessionsDir = path14.join(tokenGoatHome(), "sessions");
8266
+ const sessionsDir = path15.join(tokenGoatHome(), "sessions");
8255
8267
  if (!fs14.existsSync(sessionsDir)) {
8256
8268
  return null;
8257
8269
  }
@@ -8265,9 +8277,9 @@ function findLatestSessionId() {
8265
8277
  return null;
8266
8278
  }
8267
8279
  let latestFile = firstFile;
8268
- let latestMtime = fs14.statSync(path14.join(sessionsDir, firstFile)).mtimeMs;
8280
+ let latestMtime = fs14.statSync(path15.join(sessionsDir, firstFile)).mtimeMs;
8269
8281
  for (const file2 of jsonFiles) {
8270
- const mtime = fs14.statSync(path14.join(sessionsDir, file2)).mtimeMs;
8282
+ const mtime = fs14.statSync(path15.join(sessionsDir, file2)).mtimeMs;
8271
8283
  if (mtime > latestMtime) {
8272
8284
  latestFile = file2;
8273
8285
  latestMtime = mtime;
@@ -8289,15 +8301,15 @@ function eventCount(cache) {
8289
8301
  function writeSessionManifest(projectHash2, sessionId, manifestJson) {
8290
8302
  const safeSessionId = sanitizeIdForFilename(sessionId, 64);
8291
8303
  if (!safeSessionId) return;
8292
- const sessionsDir = path14.join(dataDir(), "projects", projectHash2, "sessions");
8304
+ const sessionsDir = path15.join(dataDir(), "projects", projectHash2, "sessions");
8293
8305
  if (!fs14.existsSync(sessionsDir)) {
8294
8306
  fs14.mkdirSync(sessionsDir, { recursive: true });
8295
8307
  }
8296
- const dest = path14.join(sessionsDir, `${safeSessionId}.json`);
8308
+ const dest = path15.join(sessionsDir, `${safeSessionId}.json`);
8297
8309
  atomicWriteText(dest, JSON.stringify(manifestJson));
8298
8310
  }
8299
8311
  function readAllSessionManifests(projectHash2, maxAgeSecs = 3600) {
8300
- const sessionsDir = path14.join(dataDir(), "projects", projectHash2, "sessions");
8312
+ const sessionsDir = path15.join(dataDir(), "projects", projectHash2, "sessions");
8301
8313
  if (!fs14.existsSync(sessionsDir)) {
8302
8314
  return [];
8303
8315
  }
@@ -8310,7 +8322,7 @@ function readAllSessionManifests(projectHash2, maxAgeSecs = 3600) {
8310
8322
  continue;
8311
8323
  }
8312
8324
  try {
8313
- const fullPath = path14.join(sessionsDir, file2);
8325
+ const fullPath = path15.join(sessionsDir, file2);
8314
8326
  const stat2 = fs14.statSync(fullPath);
8315
8327
  if (now - stat2.mtimeMs / 1e3 > maxAgeSecs) {
8316
8328
  try {
@@ -8628,14 +8640,14 @@ var init_compact = __esm({
8628
8640
 
8629
8641
  // src/snapshots.ts
8630
8642
  import * as fs15 from "node:fs";
8631
- import * as path15 from "node:path";
8643
+ import * as path16 from "node:path";
8632
8644
  function sessionDir(sessionId) {
8633
8645
  if (!sessionId) return null;
8634
8646
  const safe = sanitizeIdForFilename(sessionId, 64, "anon");
8635
- const base = path15.join(tokenGoatHome(), "session_snapshots");
8636
- const candidate = path15.join(base, safe);
8647
+ const base = path16.join(tokenGoatHome(), "session_snapshots");
8648
+ const candidate = path16.join(base, safe);
8637
8649
  try {
8638
- const rel = path15.relative(base, candidate);
8650
+ const rel = path16.relative(base, candidate);
8639
8651
  if (rel.startsWith("..")) return null;
8640
8652
  } catch {
8641
8653
  return null;
@@ -8648,7 +8660,7 @@ function pathKey(filePath) {
8648
8660
  function snapshot_path(sessionId, filePath) {
8649
8661
  const d = sessionDir(sessionId);
8650
8662
  if (!d) return null;
8651
- return path15.join(d, `${pathKey(filePath)}.bin`);
8663
+ return path16.join(d, `${pathKey(filePath)}.bin`);
8652
8664
  }
8653
8665
  function kindSidecarPath(snapshotPath) {
8654
8666
  return snapshotPath + ".kind";
@@ -8656,7 +8668,7 @@ function kindSidecarPath(snapshotPath) {
8656
8668
  function writeSnapshotKind(sidecarPath, kind) {
8657
8669
  try {
8658
8670
  const safeKind = VALID_KINDS.has(kind) ? kind : KIND_READ;
8659
- const dir = path15.dirname(sidecarPath);
8671
+ const dir = path16.dirname(sidecarPath);
8660
8672
  if (!fs15.existsSync(dir)) {
8661
8673
  fs15.mkdirSync(dir, { recursive: true });
8662
8674
  }
@@ -8671,7 +8683,7 @@ function evictOldest(d, maxCount) {
8671
8683
  const entries = [];
8672
8684
  const files = fs15.readdirSync(d);
8673
8685
  for (const file2 of files) {
8674
- const fullPath = path15.join(d, file2);
8686
+ const fullPath = path16.join(d, file2);
8675
8687
  if (!file2.endsWith(".bin")) continue;
8676
8688
  try {
8677
8689
  const stat2 = fs15.statSync(fullPath);
@@ -8732,7 +8744,7 @@ function store(sessionId, filePath, content, opts = {}) {
8732
8744
  } catch {
8733
8745
  }
8734
8746
  }
8735
- const dir = path15.dirname(p);
8747
+ const dir = path16.dirname(p);
8736
8748
  if (!fs15.existsSync(dir)) {
8737
8749
  fs15.mkdirSync(dir, { recursive: true });
8738
8750
  }
@@ -8814,11 +8826,11 @@ function buildPackageManifestHint(options) {
8814
8826
  return null;
8815
8827
  }
8816
8828
  }
8817
- function _sanitizeHintPath(path69) {
8818
- if (typeof path69 !== "string") {
8829
+ function _sanitizeHintPath(path70) {
8830
+ if (typeof path70 !== "string") {
8819
8831
  return "???";
8820
8832
  }
8821
- return path69.replace(/[\x00]/g, "").slice(0, 200);
8833
+ return path70.replace(/[\x00]/g, "").slice(0, 200);
8822
8834
  }
8823
8835
  var HINT_PRIORITY_MEDIUM;
8824
8836
  var init_hints = __esm({
@@ -9475,7 +9487,7 @@ var init_init_state = __esm({
9475
9487
  needMoreDataSize: Math.max(
9476
9488
  // Skip if the remaining buffer smaller than comment
9477
9489
  options.comment !== null ? options.comment.length : 0,
9478
- ...options.delimiter ? options.delimiter.map((delimiter2) => delimiter2.length) : [],
9490
+ ...options.delimiter ? options.delimiter.map((delimiter3) => delimiter3.length) : [],
9479
9491
  // Auto discovery of delimiter is limited to 1 character
9480
9492
  options.delimiter_auto ? 1 : 0,
9481
9493
  // Skip if the remaining buffer can be escape sequence
@@ -9743,11 +9755,11 @@ var init_normalize_options = __esm({
9743
9755
  }
9744
9756
  options.delimiter = [options.delimiter];
9745
9757
  }
9746
- options.delimiter = options.delimiter.map(function(delimiter2) {
9747
- if (typeof delimiter2 === "string") {
9748
- delimiter2 = Buffer.from(delimiter2, options.encoding);
9758
+ options.delimiter = options.delimiter.map(function(delimiter3) {
9759
+ if (typeof delimiter3 === "string") {
9760
+ delimiter3 = Buffer.from(delimiter3, options.encoding);
9749
9761
  }
9750
- if (!Buffer.isBuffer(delimiter2) || delimiter2.length === 0) {
9762
+ if (!Buffer.isBuffer(delimiter3) || delimiter3.length === 0) {
9751
9763
  throw new CsvError(
9752
9764
  "CSV_INVALID_OPTION_DELIMITER",
9753
9765
  [
@@ -9758,7 +9770,7 @@ var init_normalize_options = __esm({
9758
9770
  options
9759
9771
  );
9760
9772
  }
9761
- return delimiter2;
9773
+ return delimiter3;
9762
9774
  });
9763
9775
  if (options.escape === void 0 || options.escape === true) {
9764
9776
  options.escape = Buffer.from('"', options.encoding);
@@ -10843,14 +10855,14 @@ var init_api = __esm({
10843
10855
  return 0;
10844
10856
  },
10845
10857
  __isDelimiter: function(buf, pos, chr) {
10846
- const { delimiter: delimiter2, ignore_last_delimiters } = this.options;
10858
+ const { delimiter: delimiter3, ignore_last_delimiters } = this.options;
10847
10859
  if (ignore_last_delimiters === true && this.state.record.length === this.options.columns.length - 1) {
10848
10860
  return 0;
10849
10861
  } else if (ignore_last_delimiters !== false && typeof ignore_last_delimiters === "number" && this.state.record.length === ignore_last_delimiters - 1) {
10850
10862
  return 0;
10851
10863
  }
10852
- loop1: for (let i = 0; i < delimiter2.length; i++) {
10853
- const del = delimiter2[i];
10864
+ loop1: for (let i = 0; i < delimiter3.length; i++) {
10865
+ const del = delimiter3[i];
10854
10866
  if (del[0] === chr) {
10855
10867
  for (let j = 1; j < del.length; j++) {
10856
10868
  if (del[j] !== buf[pos + j]) continue loop1;
@@ -11797,7 +11809,8 @@ function handlePdf(filePath, contentLength) {
11797
11809
  shouldBlock: true,
11798
11810
  message: [
11799
11811
  `PDF file (${formatBytes(contentLength)}) \u2014 Read cannot return PDF content; this is not retryable with different Read parameters.`,
11800
- `Extract text instead: token-goat pdf-extract "${filePath}"`
11812
+ `Inspect first: token-goat pdf-meta "${filePath}" and token-goat pdf-outline "${filePath}"`,
11813
+ `Then extract relevant pages: token-goat pdf-extract "${filePath}" --pages <range>`
11801
11814
  ].join("\n")
11802
11815
  };
11803
11816
  }
@@ -12636,9 +12649,9 @@ var init_lazy_module = __esm({
12636
12649
  // src/image_ocr.ts
12637
12650
  import { spawn as spawn2 } from "node:child_process";
12638
12651
  import { createRequire as createRequire4 } from "node:module";
12639
- import * as path16 from "node:path";
12652
+ import * as path17 from "node:path";
12640
12653
  function ocrCacheDir() {
12641
- return path16.join(tokenGoatHome(), "ocr-cache");
12654
+ return path17.join(tokenGoatHome(), "ocr-cache");
12642
12655
  }
12643
12656
  function resolveTesseractEntry() {
12644
12657
  if (_tesseractEntryPath !== void 0) return _tesseractEntryPath;
@@ -12746,7 +12759,7 @@ var init_image_ocr = __esm({
12746
12759
  // src/image_shrink.ts
12747
12760
  import { createHash as createHash2 } from "node:crypto";
12748
12761
  import * as fs17 from "node:fs";
12749
- import * as path17 from "node:path";
12762
+ import * as path18 from "node:path";
12750
12763
  function formatShrinkSummary(result, subject) {
12751
12764
  const saved = result.originalBytes - result.shrunkBytes;
12752
12765
  const pct = Math.round(saved / result.originalBytes * 100);
@@ -12755,7 +12768,7 @@ function formatShrinkSummary(result, subject) {
12755
12768
  return { summary, dataUrl };
12756
12769
  }
12757
12770
  function isImagePath(p) {
12758
- return IMAGE_EXTENSIONS.has(path17.extname(p).toLowerCase());
12771
+ return IMAGE_EXTENSIONS.has(path18.extname(p).toLowerCase());
12759
12772
  }
12760
12773
  async function probeImageMeta(input) {
12761
12774
  const sharp = await loadSharp();
@@ -12813,7 +12826,7 @@ function statInfo(absPath) {
12813
12826
  }
12814
12827
  }
12815
12828
  function imageShrinkCacheDir() {
12816
- return path17.join(tokenGoatHome(), "image_shrink_cache");
12829
+ return path18.join(tokenGoatHome(), "image_shrink_cache");
12817
12830
  }
12818
12831
  function shrinkCacheKey(originalPath, size, mtimeMs) {
12819
12832
  return createHash2("sha256").update(`${originalPath}:${size}:${mtimeMs}`).digest("hex").slice(0, 16);
@@ -12826,7 +12839,7 @@ function findCachedShrink(originalPath, size, mtimeMs) {
12826
12839
  { ext: ".jpg", format: "jpeg" }
12827
12840
  ];
12828
12841
  for (const { ext: ext2, format } of candidates) {
12829
- const candidate = path17.join(dir, `token-goat-shrink-${key}${ext2}`);
12842
+ const candidate = path18.join(dir, `token-goat-shrink-${key}${ext2}`);
12830
12843
  if (fs17.existsSync(candidate)) return { filePath: candidate, format };
12831
12844
  }
12832
12845
  return null;
@@ -12837,7 +12850,7 @@ function writeCachedShrink(originalPath, result, mtimeMs) {
12837
12850
  fs17.mkdirSync(dir, { recursive: true });
12838
12851
  const key = shrinkCacheKey(originalPath, result.originalBytes, mtimeMs);
12839
12852
  const ext2 = result.format === "jpeg" ? ".jpg" : ".webp";
12840
- atomicWriteBytes(path17.join(dir, `token-goat-shrink-${key}${ext2}`), result.data);
12853
+ atomicWriteBytes(path18.join(dir, `token-goat-shrink-${key}${ext2}`), result.data);
12841
12854
  } catch {
12842
12855
  }
12843
12856
  }
@@ -12851,7 +12864,7 @@ function pruneShrinkCache() {
12851
12864
  const cutoff = now - DEFAULT_MAX_AGE_MS;
12852
12865
  for (const file2 of fs17.readdirSync(dir)) {
12853
12866
  if (!file2.startsWith("token-goat-shrink-")) continue;
12854
- const full = path17.join(dir, file2);
12867
+ const full = path18.join(dir, file2);
12855
12868
  try {
12856
12869
  const st = fs17.statSync(full);
12857
12870
  if (st.mtimeMs < cutoff) fs17.unlinkSync(full);
@@ -12862,7 +12875,7 @@ function pruneShrinkCache() {
12862
12875
  }
12863
12876
  }
12864
12877
  async function finalizeShrinkResult(result, filePath) {
12865
- const basename22 = path17.basename(filePath);
12878
+ const basename22 = path18.basename(filePath);
12866
12879
  if (loadConfig().image_shrink.ocr_enabled) {
12867
12880
  const ocr = await ocrImage(result.data);
12868
12881
  if (ocr !== null && isTextHeavy(ocr, loadConfig().image_shrink.ocr_min_confidence)) {
@@ -12988,7 +13001,7 @@ var init_image_shrink = __esm({
12988
13001
 
12989
13002
  // src/doc_compact.ts
12990
13003
  import * as fs18 from "fs";
12991
- import * as path18 from "path";
13004
+ import * as path19 from "path";
12992
13005
  function sourceHash(filePath) {
12993
13006
  try {
12994
13007
  return fingerprintContent(fs18.readFileSync(filePath));
@@ -12998,14 +13011,14 @@ function sourceHash(filePath) {
12998
13011
  }
12999
13012
  function _compactSlug(absPathStr) {
13000
13013
  const h = fingerprintContent(foldPath(absPathStr)).slice(0, 12);
13001
- const ext2 = path18.extname(absPathStr);
13002
- const stem = path18.basename(absPathStr, ext2);
13014
+ const ext2 = path19.extname(absPathStr);
13015
+ const stem = path19.basename(absPathStr, ext2);
13003
13016
  const safeStem = sanitizeIdForFilename(stem, 32);
13004
13017
  return `${h}_${safeStem}`;
13005
13018
  }
13006
13019
  function compactPathFor(sourcePath) {
13007
13020
  const abs = resolveIndexPath(sourcePath);
13008
- return path18.join(dataDir(), compactSubdir, `${_compactSlug(abs)}.md`);
13021
+ return path19.join(dataDir(), compactSubdir, `${_compactSlug(abs)}.md`);
13009
13022
  }
13010
13023
  function readCompactHeader(compactPath) {
13011
13024
  try {
@@ -13054,13 +13067,13 @@ function readCompactBody(compactPath) {
13054
13067
  }
13055
13068
  }
13056
13069
  function writeCompact(compactPath, sourcePath, compactBody, sourceRel) {
13057
- const srcPath = path18.resolve(sourcePath);
13070
+ const srcPath = path19.resolve(sourcePath);
13058
13071
  const sha = sourceHash(srcPath);
13059
- const displayRel = sourceRel || path18.basename(srcPath);
13072
+ const displayRel = sourceRel || path19.basename(srcPath);
13060
13073
  const header = `${headerPrefix}${sha} source:${displayRel} -->
13061
13074
  `;
13062
13075
  const fullText = header + compactBody.trimStart();
13063
- const dir = path18.dirname(compactPath);
13076
+ const dir = path19.dirname(compactPath);
13064
13077
  if (!fs18.existsSync(dir)) {
13065
13078
  fs18.mkdirSync(dir, { recursive: true });
13066
13079
  }
@@ -13211,7 +13224,7 @@ var init_doc_compact = __esm({
13211
13224
 
13212
13225
  // src/notebook_compact.ts
13213
13226
  import * as fs19 from "node:fs";
13214
- import * as path19 from "node:path";
13227
+ import * as path20 from "node:path";
13215
13228
  function stripNotebook(nbDict) {
13216
13229
  const cells = [];
13217
13230
  for (const cell of nbDict.cells ?? []) {
@@ -13228,14 +13241,14 @@ function stripNotebook(nbDict) {
13228
13241
  return { ...nbDict, cells };
13229
13242
  }
13230
13243
  function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs = SIDECAR_DEFAULT_MAX_AGE_MS) {
13231
- const nbStripDir = path19.join(cacheRoot, "nb_strip");
13244
+ const nbStripDir = path20.join(cacheRoot, "nb_strip");
13232
13245
  let removed = 0;
13233
13246
  try {
13234
13247
  if (!fs19.existsSync(nbStripDir)) return 0;
13235
13248
  const cutoff = Date.now() - maxAgeMs;
13236
13249
  const kept = [];
13237
13250
  for (const entry of fs19.readdirSync(nbStripDir)) {
13238
- const dir = path19.join(nbStripDir, entry);
13251
+ const dir = path20.join(nbStripDir, entry);
13239
13252
  let mtime;
13240
13253
  try {
13241
13254
  mtime = fs19.statSync(dir).mtimeMs;
@@ -13271,8 +13284,8 @@ function pruneSidecars(cacheRoot, maxCount = SIDECAR_DEFAULT_MAX_COUNT, maxAgeMs
13271
13284
  }
13272
13285
  function getOrCreateSidecar(rawBytes, cacheRoot, opts = {}) {
13273
13286
  const sha = fingerprintContent(rawBytes);
13274
- const sidecarDir = path19.join(cacheRoot, "nb_strip", sha);
13275
- const sidecarPath = path19.join(sidecarDir, "stripped.ipynb");
13287
+ const sidecarDir = path20.join(cacheRoot, "nb_strip", sha);
13288
+ const sidecarPath = path20.join(sidecarDir, "stripped.ipynb");
13276
13289
  if (fs19.existsSync(sidecarPath)) {
13277
13290
  return [sidecarPath, false];
13278
13291
  }
@@ -13313,20 +13326,20 @@ var init_notebook_compact = __esm({
13313
13326
  });
13314
13327
 
13315
13328
  // src/parser_types.ts
13316
- import * as path20 from "node:path";
13329
+ import * as path21 from "node:path";
13317
13330
  function detectLanguage(filePath) {
13318
- const base = path20.basename(filePath).toLowerCase();
13331
+ const base = path21.basename(filePath).toLowerCase();
13319
13332
  if (DOTENV_VARIANT_RE.test(base)) return "env_file";
13320
13333
  const byName = FILENAME_LANGUAGE.get(base);
13321
13334
  if (byName !== void 0) return byName;
13322
13335
  if (base.endsWith("-meta.xml")) {
13323
13336
  return "salesforce_metadata";
13324
13337
  }
13325
- const ext2 = path20.extname(base).toLowerCase();
13338
+ const ext2 = path21.extname(base).toLowerCase();
13326
13339
  return EXTENSION_LANGUAGE.get(ext2) ?? "unknown";
13327
13340
  }
13328
13341
  function unsupportedLanguageName(filePath) {
13329
- const ext2 = path20.extname(filePath).toLowerCase();
13342
+ const ext2 = path21.extname(filePath).toLowerCase();
13330
13343
  return UNSUPPORTED_LANGUAGE_EXTENSIONS.get(ext2);
13331
13344
  }
13332
13345
  var EXTENSION_LANGUAGE, FILENAME_LANGUAGE, DOTENV_VARIANT_RE, UNSUPPORTED_LANGUAGE_EXTENSIONS;
@@ -13478,7 +13491,7 @@ var init_parser_types = __esm({
13478
13491
 
13479
13492
  // src/hooks_read.ts
13480
13493
  import * as fs20 from "node:fs";
13481
- import * as path21 from "node:path";
13494
+ import * as path22 from "node:path";
13482
13495
  function isTsConfigFile(basename22) {
13483
13496
  const lower = basename22.toLowerCase();
13484
13497
  return /^tsconfig(\..+)?\.json$/i.test(lower) || lower === "jsconfig.json";
@@ -13493,8 +13506,8 @@ function isNodeModulesPath(p) {
13493
13506
  return check2.includes("/node_modules/") || check2.includes("\\node_modules\\");
13494
13507
  }
13495
13508
  function relPathWithinRoot(root, target) {
13496
- const rel = path21.relative(root, target).replace(/\\/g, "/");
13497
- if (rel.startsWith("..") || path21.isAbsolute(rel)) return null;
13509
+ const rel = path22.relative(root, target).replace(/\\/g, "/");
13510
+ if (rel.startsWith("..") || path22.isAbsolute(rel)) return null;
13498
13511
  return rel;
13499
13512
  }
13500
13513
  function _isDocFile(filePath) {
@@ -13586,7 +13599,7 @@ function isSourceExtension(basename22) {
13586
13599
  return language === "apex" || language === "salesforce_metadata" || language === "salesforce_markup";
13587
13600
  }
13588
13601
  function isDispatchedFileType(basename22) {
13589
- return DISPATCHED_FILE_TYPE_EXTS.has(path21.extname(basename22).slice(1).toLowerCase());
13602
+ return DISPATCHED_FILE_TYPE_EXTS.has(path22.extname(basename22).slice(1).toLowerCase());
13590
13603
  }
13591
13604
  function surgicalHint(filePath, basename22, lineCount) {
13592
13605
  if (lineCount < loadConfig().hints.min_file_lines_for_hint) return "";
@@ -13730,7 +13743,7 @@ function preReadHandlerInner(event) {
13730
13743
  "node_modules is typically noise; use npm ls, npm outdated, or npm audit instead for dependency info. To force access, use: token-goat read node_modules/package/file.js::symbol-name or token-goat section node_modules/package/file.js::heading"
13731
13744
  );
13732
13745
  }
13733
- const basename22 = path21.basename(normalized);
13746
+ const basename22 = path22.basename(normalized);
13734
13747
  if (isLockFile(basename22)) {
13735
13748
  return denyOutput(
13736
13749
  'Lock files are rarely useful to read in full. Use `token-goat section "' + normalized + '::<section>"` to extract a specific dependency, or read the relevant manifest instead.'
@@ -14051,7 +14064,7 @@ function preReadHandlerInner(event) {
14051
14064
  "Note: " + normalized + " is large (" + kb + "KB). " + hint + contextPressureAdvisorySuffix()
14052
14065
  );
14053
14066
  }
14054
- const fileTypeExt = path21.extname(normalized).slice(1).toLowerCase();
14067
+ const fileTypeExt = path22.extname(normalized).slice(1).toLowerCase();
14055
14068
  const fileStatSize = size ?? statSize(normalized) ?? 0;
14056
14069
  const isKnownFileType = DISPATCHED_FILE_TYPE_EXTS.has(fileTypeExt);
14057
14070
  if (event.toolName !== "Grep" && !isImagePath(normalized) && (isKnownFileType || fileStatSize >= FILE_TYPE_THRESHOLDS.generic)) {
@@ -14108,7 +14121,7 @@ function postReadHandlerInner(event) {
14108
14121
  if (respText.includes("[Truncated:") || respText.includes("Truncated: PARTIAL view")) {
14109
14122
  markFileTruncated(normalized);
14110
14123
  }
14111
- const postBasename = path21.basename(normalized);
14124
+ const postBasename = path22.basename(normalized);
14112
14125
  const diffSourcesEnabled = loadConfig().hints.serve_diff_on_reread;
14113
14126
  if (/\.(md|mdx|markdown|rst|txt)$/i.test(postBasename) || isSessionArtifactFile(normalized) || diffSourcesEnabled && DIFFABLE_SOURCE_RE.test(postBasename)) {
14114
14127
  try {
@@ -14962,8 +14975,8 @@ async function readOoxmlZip(filePath) {
14962
14975
  const data = fs22.readFileSync(filePath);
14963
14976
  return fflate.unzipSync(new Uint8Array(data));
14964
14977
  }
14965
- function decodeZipEntry(entries, path69) {
14966
- const bytes = entries[path69];
14978
+ function decodeZipEntry(entries, path70) {
14979
+ const bytes = entries[path70];
14967
14980
  if (bytes === void 0) return null;
14968
14981
  return new TextDecoder("utf-8").decode(bytes);
14969
14982
  }
@@ -15173,9 +15186,9 @@ async function notesPathFor(entries, slidePath) {
15173
15186
  }
15174
15187
  return null;
15175
15188
  }
15176
- async function parseSlide(entries, path69) {
15177
- const xml = decodeZipEntry(entries, path69);
15178
- if (xml === null) throw new Error(`missing part: ${path69}`);
15189
+ async function parseSlide(entries, path70) {
15190
+ const xml = decodeZipEntry(entries, path70);
15191
+ if (xml === null) throw new Error(`missing part: ${path70}`);
15179
15192
  return parseOoxmlPart(xml);
15180
15193
  }
15181
15194
  async function notesTextFor(entries, notesPath) {
@@ -15191,8 +15204,8 @@ async function pptxOutline(filePath) {
15191
15204
  const { entries, slidePaths } = await listSlideParts(filePath);
15192
15205
  const out2 = [];
15193
15206
  for (let i = 0; i < slidePaths.length; i++) {
15194
- const path69 = slidePaths[i];
15195
- const parsed = await parseSlide(entries, path69);
15207
+ const path70 = slidePaths[i];
15208
+ const parsed = await parseSlide(entries, path70);
15196
15209
  const shapes = slideShapes(parsed);
15197
15210
  const titleShape = shapes.find((s) => {
15198
15211
  const t = shapePlaceholderType(s);
@@ -15201,7 +15214,7 @@ async function pptxOutline(filePath) {
15201
15214
  const title = titleShape !== void 0 ? shapeText(titleShape) : "";
15202
15215
  const allText = collectTextRuns(parsed, "a:t").join(" ");
15203
15216
  const bodyChars = Math.max(0, allText.length - title.length);
15204
- const hasNotes = (await notesTextFor(entries, await notesPathFor(entries, path69))).length > 0;
15217
+ const hasNotes = (await notesTextFor(entries, await notesPathFor(entries, path70))).length > 0;
15205
15218
  out2.push({ slide: i + 1, title, bodyChars, hasNotes });
15206
15219
  }
15207
15220
  return out2;
@@ -15211,13 +15224,13 @@ async function pptxSlideText(filePath, slideNumber, includeNotes) {
15211
15224
  if (slideNumber < 1 || slideNumber > slidePaths.length) {
15212
15225
  throw new Error(`slide ${slideNumber} out of range (this deck has ${slidePaths.length} slides)`);
15213
15226
  }
15214
- const path69 = slidePaths[slideNumber - 1];
15215
- const parsed = await parseSlide(entries, path69);
15227
+ const path70 = slidePaths[slideNumber - 1];
15228
+ const parsed = await parseSlide(entries, path70);
15216
15229
  const shapes = slideShapes(parsed);
15217
15230
  const blocks = [...shapes.map(shapeText).filter((t) => t.length > 0), ...tableRowBlocks(parsed)];
15218
15231
  const lines2 = [`# Slide ${slideNumber}`, ...blocks];
15219
15232
  if (includeNotes) {
15220
- const notes = await notesTextFor(entries, await notesPathFor(entries, path69));
15233
+ const notes = await notesTextFor(entries, await notesPathFor(entries, path70));
15221
15234
  if (notes.length > 0) lines2.push("", "## Speaker notes", notes);
15222
15235
  }
15223
15236
  return lines2.join("\n\n");
@@ -15261,18 +15274,18 @@ var init_pptx_extract = __esm({
15261
15274
 
15262
15275
  // src/csv_query.ts
15263
15276
  function parseRecords(content, opts) {
15264
- const delimiter2 = opts.delimiter ?? ",";
15277
+ const delimiter3 = opts.delimiter ?? ",";
15265
15278
  if (opts.noHeader === true) {
15266
- const rows = parse3(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true });
15279
+ const rows = parse3(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true });
15267
15280
  return rows.map((row) => Object.fromEntries(row.map((cell, i) => [`col${i + 1}`, cell])));
15268
15281
  }
15269
- return parse3(content, { columns: true, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true });
15282
+ return parse3(content, { columns: true, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true });
15270
15283
  }
15271
15284
  function csvHeader(content, opts) {
15272
15285
  if (opts.noHeader === true) return [];
15273
- const delimiter2 = opts.delimiter ?? ",";
15286
+ const delimiter3 = opts.delimiter ?? ",";
15274
15287
  try {
15275
- const rows = parse3(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter2, bom: true, to: 1 });
15288
+ const rows = parse3(content, { columns: false, skip_empty_lines: true, trim: true, delimiter: delimiter3, bom: true, to: 1 });
15276
15289
  return rows[0] ?? [];
15277
15290
  } catch {
15278
15291
  return [];
@@ -15634,13 +15647,13 @@ var init_xlsx_extract = __esm({
15634
15647
 
15635
15648
  // src/doc_embed_extract.ts
15636
15649
  import * as fs23 from "node:fs";
15637
- import * as path23 from "node:path";
15650
+ import * as path24 from "node:path";
15638
15651
  function isEmbeddableDocument(filePath) {
15639
- return EMBEDDABLE_DOCUMENT_EXTENSIONS.has(path23.extname(filePath).toLowerCase());
15652
+ return EMBEDDABLE_DOCUMENT_EXTENSIONS.has(path24.extname(filePath).toLowerCase());
15640
15653
  }
15641
15654
  async function extractEmbeddableDocumentText(filePath) {
15642
15655
  try {
15643
- switch (path23.extname(filePath).toLowerCase()) {
15656
+ switch (path24.extname(filePath).toLowerCase()) {
15644
15657
  case ".pdf": {
15645
15658
  const data = await fs23.promises.readFile(filePath);
15646
15659
  const { text } = await extractPdfText(new Uint8Array(data));
@@ -16286,7 +16299,7 @@ var init_html = __esm({
16286
16299
  });
16287
16300
 
16288
16301
  // src/languages/liquid.ts
16289
- import * as path24 from "node:path";
16302
+ import * as path25 from "node:path";
16290
16303
  function extractLiquid(content, filePath, relPath) {
16291
16304
  const symbols = [];
16292
16305
  const imports = [];
@@ -16320,7 +16333,7 @@ function extractLiquid(content, filePath, relPath) {
16320
16333
  const resolvedRel = relPath ?? filePath;
16321
16334
  const relPosix = resolvedRel.replace(/\\/g, "/");
16322
16335
  if (relPosix.startsWith("sections/") || relPosix.includes("/sections/")) {
16323
- const stem = path24.basename(resolvedRel, path24.extname(resolvedRel));
16336
+ const stem = path25.basename(resolvedRel, path25.extname(resolvedRel));
16324
16337
  symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "", parent: "" });
16325
16338
  }
16326
16339
  const totalLines = content.split("\n").length;
@@ -18549,7 +18562,7 @@ var init_apex = __esm({
18549
18562
  });
18550
18563
 
18551
18564
  // src/languages/salesforce_metadata.ts
18552
- import * as path25 from "node:path";
18565
+ import * as path26 from "node:path";
18553
18566
  function xmlText(content, tag) {
18554
18567
  const re = new RegExp(
18555
18568
  `<(?:[A-Za-z_][\\w.-]*:)?${tag}(?:\\s[^>]*)?>([\\s\\S]*?)</(?:[A-Za-z_][\\w.-]*:)?${tag}>`,
@@ -18585,7 +18598,7 @@ function normalizedPath(filePath) {
18585
18598
  return filePath.replace(/\\/g, "/");
18586
18599
  }
18587
18600
  function basenameWithout(filePath, suffix) {
18588
- const base = path25.basename(filePath);
18601
+ const base = path26.basename(filePath);
18589
18602
  return base.toLowerCase().endsWith(suffix.toLowerCase()) ? base.slice(0, base.length - suffix.length) : base;
18590
18603
  }
18591
18604
  function objectNameFromPath(filePath) {
@@ -18624,12 +18637,12 @@ function snakeCase(value) {
18624
18637
  return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
18625
18638
  }
18626
18639
  function companionName(filePath) {
18627
- const base = path25.basename(filePath);
18640
+ const base = path26.basename(filePath);
18628
18641
  const match2 = /^(.+)\.(?:cls|trigger|page|component|cmp|app|evt|intf|design|auradoc|tokens|js)-meta\.xml$/i.exec(base);
18629
18642
  return match2?.[1] === void 0 ? null : `${match2[1]}.metadata`;
18630
18643
  }
18631
18644
  function metadataArtifactName(filePath) {
18632
- const base = path25.basename(filePath);
18645
+ const base = path26.basename(filePath);
18633
18646
  const match2 = /^(.+)\.[^.]+-meta\.xml$/i.exec(base);
18634
18647
  return match2?.[1] ?? basenameWithout(filePath, "-meta.xml");
18635
18648
  }
@@ -18720,7 +18733,7 @@ function extractSalesforceMetadata(rawContent, filePath) {
18720
18733
  const seen = /* @__PURE__ */ new Set();
18721
18734
  const refs = [];
18722
18735
  const seenRefs = /* @__PURE__ */ new Set();
18723
- const base = path25.basename(filePath).toLowerCase();
18736
+ const base = path26.basename(filePath).toLowerCase();
18724
18737
  const whole = wholeFileSpan(content);
18725
18738
  const root = rootElement(content);
18726
18739
  if (root === null) return { symbols, refs };
@@ -18894,14 +18907,14 @@ var init_salesforce_metadata = __esm({
18894
18907
  });
18895
18908
 
18896
18909
  // src/languages/salesforce_frontend.ts
18897
- import * as path26 from "node:path";
18910
+ import * as path27 from "node:path";
18898
18911
  function lines(content) {
18899
18912
  return content.split("\n");
18900
18913
  }
18901
18914
  function bundleName(filePath) {
18902
18915
  const normalized = filePath.replaceAll("\\", "/");
18903
- const parent = path26.posix.basename(path26.posix.dirname(normalized));
18904
- const base = path26.posix.basename(normalized).replace(/\.[^.]+$/, "");
18916
+ const parent = path27.posix.basename(path27.posix.dirname(normalized));
18917
+ const base = path27.posix.basename(normalized).replace(/\.[^.]+$/, "");
18905
18918
  return parent === "lwc" || parent === "aura" ? base : parent;
18906
18919
  }
18907
18920
  function lwcTagAlias(name2) {
@@ -18993,7 +19006,7 @@ function extractLwcTemplate(content, filePath) {
18993
19006
  }
18994
19007
  function markupArtifactName(filePath, extension) {
18995
19008
  if (extension === ".page" || extension === ".component" || extension === ".email") {
18996
- return path26.posix.basename(filePath.replaceAll("\\", "/")).replace(new RegExp(`${extension.replace(".", "\\.")}$`, "i"), "");
19009
+ return path27.posix.basename(filePath.replaceAll("\\", "/")).replace(new RegExp(`${extension.replace(".", "\\.")}$`, "i"), "");
18997
19010
  }
18998
19011
  return bundleName(filePath);
18999
19012
  }
@@ -19013,7 +19026,7 @@ function attributeRefs(refs, content, filePath, attribute, split = false) {
19013
19026
  }
19014
19027
  function extractSalesforceMarkup(content, filePath) {
19015
19028
  const normalized = filePath.replaceAll("\\", "/");
19016
- const extension = path26.posix.extname(normalized).toLowerCase();
19029
+ const extension = path27.posix.extname(normalized).toLowerCase();
19017
19030
  const sourceLines = lines(content);
19018
19031
  const kind = MARKUP_KIND[extension] ?? "salesforce_markup";
19019
19032
  const symbols = [
@@ -19066,7 +19079,7 @@ var init_salesforce_frontend = __esm({
19066
19079
  });
19067
19080
 
19068
19081
  // src/languages/sfc_idx.ts
19069
- import * as path27 from "node:path";
19082
+ import * as path28 from "node:path";
19070
19083
  function dedupe2(values, key) {
19071
19084
  const seen = /* @__PURE__ */ new Set();
19072
19085
  return values.filter((value) => {
@@ -19084,7 +19097,7 @@ function finalize(symbols, refs) {
19084
19097
  }
19085
19098
  function componentName(filePath) {
19086
19099
  const normalized = filePath.replaceAll("\\", "/");
19087
- return path27.posix.basename(normalized).replace(/\.[^.]+$/, "");
19100
+ return path28.posix.basename(normalized).replace(/\.[^.]+$/, "");
19088
19101
  }
19089
19102
  function matchLine2(content, offset) {
19090
19103
  return content.slice(0, offset).split("\n").length;
@@ -19324,7 +19337,7 @@ var init_ipynb_idx = __esm({
19324
19337
  // src/parser.ts
19325
19338
  import * as fs24 from "node:fs";
19326
19339
  import { createRequire as createRequire6 } from "node:module";
19327
- import * as path28 from "node:path";
19340
+ import * as path29 from "node:path";
19328
19341
  function loadParserCtor() {
19329
19342
  if (_parserCtor !== void 0) return _parserCtor;
19330
19343
  try {
@@ -19406,8 +19419,8 @@ function countNewlines(s) {
19406
19419
  return n;
19407
19420
  }
19408
19421
  function loadGrammar(lang, filePath, content) {
19409
- const useTsx = lang === "typescript" && filePath !== void 0 && path28.extname(filePath).toLowerCase() === ".tsx";
19410
- const useCppHeader = lang === "c" && filePath !== void 0 && path28.extname(filePath).toLowerCase() === ".h" && content !== void 0 && CPP_HEADER_SNIFF_RE.test(content);
19422
+ const useTsx = lang === "typescript" && filePath !== void 0 && path29.extname(filePath).toLowerCase() === ".tsx";
19423
+ const useCppHeader = lang === "c" && filePath !== void 0 && path29.extname(filePath).toLowerCase() === ".h" && content !== void 0 && CPP_HEADER_SNIFF_RE.test(content);
19411
19424
  const cacheKey = useTsx ? "typescript:tsx" : useCppHeader ? "c:cpp-header" : lang;
19412
19425
  const cached2 = _grammarCache.get(cacheKey);
19413
19426
  if (cached2 !== void 0) return cached2;
@@ -20456,7 +20469,7 @@ function isUnderSkipDir(filePath, skipDirs) {
20456
20469
  }
20457
20470
  function isParseSkipEligible(filePath, cfg) {
20458
20471
  if (isUnderSkipDir(filePath, cfg.skip_dirs)) return true;
20459
- if (cfg.skip_files.includes(path28.basename(filePath))) return true;
20472
+ if (cfg.skip_files.includes(path29.basename(filePath))) return true;
20460
20473
  try {
20461
20474
  const stat2 = fs24.statSync(filePath);
20462
20475
  if (stat2.size > cfg.large_file_skip_kb * 1024) return true;
@@ -21194,7 +21207,7 @@ var init_parser = __esm({
21194
21207
 
21195
21208
  // src/index_prune.ts
21196
21209
  import * as fs25 from "node:fs";
21197
- import * as path29 from "node:path";
21210
+ import * as path30 from "node:path";
21198
21211
  function removeFileFromIndex(db, filePath) {
21199
21212
  const tx = db.transaction(() => {
21200
21213
  deleteFileRows(db, filePath);
@@ -21270,7 +21283,7 @@ function pruneSystemTempFiles(dbPath = globalDbPath()) {
21270
21283
  return removeFilesBestEffort(db, findSystemTempFiles(dbPath));
21271
21284
  }
21272
21285
  function recordKnownRoot(filePath, dbPath = globalDbPath()) {
21273
- const project = findProject(path29.dirname(filePath));
21286
+ const project = findProject(path30.dirname(filePath));
21274
21287
  if (project === null || isTooShallowToPrune(project.root)) return;
21275
21288
  const db = getDb(dbPath);
21276
21289
  db.prepare(
@@ -21279,7 +21292,7 @@ function recordKnownRoot(filePath, dbPath = globalDbPath()) {
21279
21292
  ).run(project.root, Date.now());
21280
21293
  }
21281
21294
  function knownRootRecordMarkerPath(dir, filePath) {
21282
- return path29.join(dir, `known-root-record-${shortFingerprint(path29.dirname(filePath))}.marker`);
21295
+ return path30.join(dir, `known-root-record-${shortFingerprint(path30.dirname(filePath))}.marker`);
21283
21296
  }
21284
21297
  function recordKnownRootThrottled(filePath, dir = dataDir(), dbPath = globalDbPath()) {
21285
21298
  const markerPath = knownRootRecordMarkerPath(dir, filePath);
@@ -21315,13 +21328,13 @@ var init_index_prune = __esm({
21315
21328
  // src/worker.ts
21316
21329
  import { spawn as spawn3 } from "node:child_process";
21317
21330
  import * as fs26 from "node:fs";
21318
- import * as path30 from "node:path";
21331
+ import * as path31 from "node:path";
21319
21332
  import { fileURLToPath as fileURLToPath2 } from "node:url";
21320
21333
  function dirtyQueuePathFor(dir) {
21321
- return path30.join(dir, "queue", "dirty.txt");
21334
+ return path31.join(dir, "queue", "dirty.txt");
21322
21335
  }
21323
21336
  function drainHeartbeatPathFor(dir) {
21324
- return path30.join(dir, "queue", "drain-heartbeat");
21337
+ return path31.join(dir, "queue", "drain-heartbeat");
21325
21338
  }
21326
21339
  function hasFreshWorkerHeartbeat(dir, pid) {
21327
21340
  try {
@@ -21354,7 +21367,7 @@ function parseDirtyQueueLines(raw) {
21354
21367
  return out2;
21355
21368
  }
21356
21369
  function workerPidPath(dir = dataDir()) {
21357
- return path30.join(dir, "worker.pid");
21370
+ return path31.join(dir, "worker.pid");
21358
21371
  }
21359
21372
  function getDirtyPathsFor(dir) {
21360
21373
  let raw;
@@ -21366,7 +21379,7 @@ function getDirtyPathsFor(dir) {
21366
21379
  return parseDirtyQueueLines(raw);
21367
21380
  }
21368
21381
  function workerErrorLogPath(dir) {
21369
- return path30.join(dir, "worker-errors.log");
21382
+ return path31.join(dir, "worker-errors.log");
21370
21383
  }
21371
21384
  function appendWorkerErrorLog(dir, line) {
21372
21385
  try {
@@ -21397,7 +21410,7 @@ function isWorkerRunning(dir = dataDir()) {
21397
21410
  return pidAlive(pid) && hasFreshWorkerHeartbeat(dir, pid);
21398
21411
  }
21399
21412
  function workerHealthCheckMarkerPath(dir) {
21400
- return path30.join(dir, "worker-healthcheck.marker");
21413
+ return path31.join(dir, "worker-healthcheck.marker");
21401
21414
  }
21402
21415
  function ensureWorkerAlive(dir = dataDir()) {
21403
21416
  if (process.env["TOKEN_GOAT_NO_WORKER_SPAWN"] === "1") return;
@@ -21553,13 +21566,13 @@ var init_worker = __esm({
21553
21566
 
21554
21567
  // src/hooks_index.ts
21555
21568
  import * as fs27 from "node:fs";
21556
- import * as path31 from "node:path";
21569
+ import * as path32 from "node:path";
21557
21570
  function dirtyQueuePath() {
21558
- return path31.join(dataDir(), "queue", "dirty.txt");
21571
+ return path32.join(dataDir(), "queue", "dirty.txt");
21559
21572
  }
21560
21573
  function appendDirtyPath(normalizedPath2) {
21561
21574
  const queuePath = dirtyQueuePath();
21562
- const dir = path31.dirname(queuePath);
21575
+ const dir = path32.dirname(queuePath);
21563
21576
  try {
21564
21577
  fs27.mkdirSync(dir, { recursive: true });
21565
21578
  } catch (e) {
@@ -21593,9 +21606,9 @@ function getDirtyPaths() {
21593
21606
  function preCompactIndexHandler(_event) {
21594
21607
  const paths = getDirtyPaths();
21595
21608
  if (paths.length > 0) {
21596
- const sidecar = path31.join(dataDir(), "queue", "pending.txt");
21609
+ const sidecar = path32.join(dataDir(), "queue", "pending.txt");
21597
21610
  try {
21598
- fs27.mkdirSync(path31.dirname(sidecar), { recursive: true });
21611
+ fs27.mkdirSync(path32.dirname(sidecar), { recursive: true });
21599
21612
  atomicWriteBytes(sidecar, Buffer.from(`${paths.join("\n")}
21600
21613
  `, "utf8"));
21601
21614
  } catch {
@@ -22556,7 +22569,7 @@ var require_command = __commonJS({
22556
22569
  init_define_import_meta_env();
22557
22570
  var EventEmitter = __require("node:events").EventEmitter;
22558
22571
  var childProcess = __require("node:child_process");
22559
- var path69 = __require("node:path");
22572
+ var path70 = __require("node:path");
22560
22573
  var fs61 = __require("node:fs");
22561
22574
  var process4 = __require("node:process");
22562
22575
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -23489,9 +23502,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
23489
23502
  let launchWithNode = false;
23490
23503
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
23491
23504
  function findFile(baseDir, baseName) {
23492
- const localBin = path69.resolve(baseDir, baseName);
23505
+ const localBin = path70.resolve(baseDir, baseName);
23493
23506
  if (fs61.existsSync(localBin)) return localBin;
23494
- if (sourceExt.includes(path69.extname(baseName))) return void 0;
23507
+ if (sourceExt.includes(path70.extname(baseName))) return void 0;
23495
23508
  const foundExt = sourceExt.find(
23496
23509
  (ext2) => fs61.existsSync(`${localBin}${ext2}`)
23497
23510
  );
@@ -23509,17 +23522,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
23509
23522
  } catch (err2) {
23510
23523
  resolvedScriptPath = this._scriptPath;
23511
23524
  }
23512
- executableDir = path69.resolve(
23513
- path69.dirname(resolvedScriptPath),
23525
+ executableDir = path70.resolve(
23526
+ path70.dirname(resolvedScriptPath),
23514
23527
  executableDir
23515
23528
  );
23516
23529
  }
23517
23530
  if (executableDir) {
23518
23531
  let localFile = findFile(executableDir, executableFile);
23519
23532
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
23520
- const legacyName = path69.basename(
23533
+ const legacyName = path70.basename(
23521
23534
  this._scriptPath,
23522
- path69.extname(this._scriptPath)
23535
+ path70.extname(this._scriptPath)
23523
23536
  );
23524
23537
  if (legacyName !== this._name) {
23525
23538
  localFile = findFile(
@@ -23530,7 +23543,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
23530
23543
  }
23531
23544
  executableFile = localFile || executableFile;
23532
23545
  }
23533
- launchWithNode = sourceExt.includes(path69.extname(executableFile));
23546
+ launchWithNode = sourceExt.includes(path70.extname(executableFile));
23534
23547
  let proc;
23535
23548
  if (process4.platform !== "win32") {
23536
23549
  if (launchWithNode) {
@@ -24370,7 +24383,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
24370
24383
  * @return {Command}
24371
24384
  */
24372
24385
  nameFromFilename(filename) {
24373
- this._name = path69.basename(filename, path69.extname(filename));
24386
+ this._name = path70.basename(filename, path70.extname(filename));
24374
24387
  return this;
24375
24388
  }
24376
24389
  /**
@@ -24384,9 +24397,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
24384
24397
  * @param {string} [path]
24385
24398
  * @return {(string|null|Command)}
24386
24399
  */
24387
- executableDir(path70) {
24388
- if (path70 === void 0) return this._executableDir;
24389
- this._executableDir = path70;
24400
+ executableDir(path71) {
24401
+ if (path71 === void 0) return this._executableDir;
24402
+ this._executableDir = path71;
24390
24403
  return this;
24391
24404
  }
24392
24405
  /**
@@ -27320,10 +27333,10 @@ var init_json_query = __esm({
27320
27333
  });
27321
27334
 
27322
27335
  // src/openapi_query.ts
27323
- import * as path33 from "node:path";
27336
+ import * as path34 from "node:path";
27324
27337
  function parseOpenApiSpec(text, filePath) {
27325
27338
  text = stripBom(text);
27326
- const ext2 = path33.extname(filePath).toLowerCase();
27339
+ const ext2 = path34.extname(filePath).toLowerCase();
27327
27340
  if (ext2 === ".yaml" || ext2 === ".yml") return load2(text);
27328
27341
  if (ext2 === ".json") return JSON.parse(text);
27329
27342
  try {
@@ -28402,7 +28415,7 @@ var init_conflict_query = __esm({
28402
28415
  // src/screenshot.ts
28403
28416
  import dns from "node:dns/promises";
28404
28417
  import fs29 from "node:fs";
28405
- import path34 from "node:path";
28418
+ import path35 from "node:path";
28406
28419
  function findPlaywrightChromium(msPlaywrightDir) {
28407
28420
  let entries;
28408
28421
  try {
@@ -28414,7 +28427,7 @@ function findPlaywrightChromium(msPlaywrightDir) {
28414
28427
  const candidates = [];
28415
28428
  for (const m of versioned) {
28416
28429
  for (const sub of PLAYWRIGHT_CHROME_SUBDIRS) {
28417
- candidates.push(path34.join(msPlaywrightDir, m[0], sub, "chrome.exe"));
28430
+ candidates.push(path35.join(msPlaywrightDir, m[0], sub, "chrome.exe"));
28418
28431
  }
28419
28432
  }
28420
28433
  return candidates;
@@ -28425,23 +28438,23 @@ function platformCandidatePaths() {
28425
28438
  const programFiles = process.env["PROGRAMFILES"];
28426
28439
  const programFilesX86 = process.env["PROGRAMFILES(X86)"];
28427
28440
  const localAppData = process.env["LOCALAPPDATA"];
28428
- if (programFiles) candidates2.push(path34.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"));
28429
- if (programFilesX86) candidates2.push(path34.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"));
28441
+ if (programFiles) candidates2.push(path35.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"));
28442
+ if (programFilesX86) candidates2.push(path35.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"));
28430
28443
  if (localAppData) {
28431
- candidates2.push(path34.join(localAppData, "Google", "Chrome", "Application", "chrome.exe"));
28432
- candidates2.push(...findPlaywrightChromium(path34.join(localAppData, "ms-playwright")));
28444
+ candidates2.push(path35.join(localAppData, "Google", "Chrome", "Application", "chrome.exe"));
28445
+ candidates2.push(...findPlaywrightChromium(path35.join(localAppData, "ms-playwright")));
28433
28446
  }
28434
28447
  return candidates2;
28435
28448
  }
28436
28449
  if (process.platform === "darwin") {
28437
28450
  const home2 = process.env["HOME"];
28438
28451
  const candidates2 = ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"];
28439
- if (home2) candidates2.push(...findPlaywrightChromium(path34.join(home2, "Library", "Caches", "ms-playwright")));
28452
+ if (home2) candidates2.push(...findPlaywrightChromium(path35.join(home2, "Library", "Caches", "ms-playwright")));
28440
28453
  return candidates2;
28441
28454
  }
28442
28455
  const home = process.env["HOME"];
28443
28456
  const candidates = ["/usr/bin/google-chrome-stable", "/usr/bin/google-chrome", "/usr/bin/chromium-browser", "/usr/bin/chromium"];
28444
- if (home) candidates.push(...findPlaywrightChromium(path34.join(home, ".cache", "ms-playwright")));
28457
+ if (home) candidates.push(...findPlaywrightChromium(path35.join(home, ".cache", "ms-playwright")));
28445
28458
  return candidates;
28446
28459
  }
28447
28460
  function resolveBrowserExecutablePath(explicit) {
@@ -28856,7 +28869,7 @@ var init_notes = __esm({
28856
28869
 
28857
28870
  // src/ts_refs.ts
28858
28871
  import { createRequire as createRequire7 } from "node:module";
28859
- import * as path35 from "node:path";
28872
+ import * as path36 from "node:path";
28860
28873
  function loadTs() {
28861
28874
  if (_tsOverride !== void 0) return _tsOverride;
28862
28875
  if (!_tsLoadAttempted) {
@@ -28876,7 +28889,7 @@ function loadError() {
28876
28889
  return _tsError;
28877
28890
  }
28878
28891
  function isTsPath(filePath) {
28879
- return TS_EXTENSIONS.has(path35.extname(filePath).toLowerCase());
28892
+ return TS_EXTENSIONS.has(path36.extname(filePath).toLowerCase());
28880
28893
  }
28881
28894
  function resolveTypedRefs(input) {
28882
28895
  const ts = loadTs();
@@ -28906,7 +28919,7 @@ function resolveTypedRefs(input) {
28906
28919
  if (defSymbol === null) return null;
28907
28920
  const out2 = [];
28908
28921
  for (const ref2 of input.candidates) {
28909
- if (!TS_JS_EXTENSIONS.has(path35.extname(ref2.filePath).toLowerCase())) {
28922
+ if (!TS_JS_EXTENSIONS.has(path36.extname(ref2.filePath).toLowerCase())) {
28910
28923
  out2.push(ref2);
28911
28924
  continue;
28912
28925
  }
@@ -28932,12 +28945,12 @@ function buildScopedProgram(ts, rootNames, searchFrom) {
28932
28945
  resolveJsonModule: true,
28933
28946
  esModuleInterop: true
28934
28947
  };
28935
- const configPath2 = ts.findConfigFile(path35.dirname(searchFrom), ts.sys.fileExists, "tsconfig.json");
28948
+ const configPath2 = ts.findConfigFile(path36.dirname(searchFrom), ts.sys.fileExists, "tsconfig.json");
28936
28949
  if (configPath2 !== void 0) {
28937
28950
  try {
28938
28951
  const raw = ts.readConfigFile(configPath2, ts.sys.readFile);
28939
28952
  if (raw.error === void 0) {
28940
- const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path35.dirname(configPath2));
28953
+ const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, path36.dirname(configPath2));
28941
28954
  Object.assign(options, parsed.options);
28942
28955
  }
28943
28956
  } catch {
@@ -29041,7 +29054,7 @@ var init_ts_refs = __esm({
29041
29054
 
29042
29055
  // src/read_commands.ts
29043
29056
  import * as fs31 from "node:fs";
29044
- import * as path36 from "node:path";
29057
+ import * as path37 from "node:path";
29045
29058
  function fileExists(p) {
29046
29059
  try {
29047
29060
  fs31.statSync(p);
@@ -29108,7 +29121,7 @@ function verifyPin(p, pinned) {
29108
29121
  verifyPinnedIdentity(p, pinned);
29109
29122
  }
29110
29123
  function indexFileSyncPinned(resolvedPath, dbPath) {
29111
- const pinned = activePins?.get(pinKey(path36.resolve(resolvedPath)));
29124
+ const pinned = activePins?.get(pinKey(path37.resolve(resolvedPath)));
29112
29125
  if (pinned === void 0) {
29113
29126
  indexFileSync(resolvedPath, dbPath);
29114
29127
  return;
@@ -29130,7 +29143,7 @@ function indexFileSyncPinned(resolvedPath, dbPath) {
29130
29143
  indexFileSync(resolvedPath, dbPath, bytes);
29131
29144
  }
29132
29145
  function readFileText(p) {
29133
- const pinned = activePins?.get(pinKey(path36.resolve(p)));
29146
+ const pinned = activePins?.get(pinKey(path37.resolve(p)));
29134
29147
  try {
29135
29148
  if (pinned === ABSENT_PIN) {
29136
29149
  verifyStillAbsent(p);
@@ -29144,7 +29157,7 @@ function readFileText(p) {
29144
29157
  }
29145
29158
  }
29146
29159
  function readFileBytes(p) {
29147
- const pinned = activePins?.get(pinKey(path36.resolve(p)));
29160
+ const pinned = activePins?.get(pinKey(path37.resolve(p)));
29148
29161
  try {
29149
29162
  if (pinned === ABSENT_PIN) {
29150
29163
  verifyStillAbsent(p);
@@ -29862,7 +29875,7 @@ ${sub.text}`);
29862
29875
  return { text, code: 1 };
29863
29876
  }
29864
29877
  function resolveAgainstProjectRoot(file2, projectRoot) {
29865
- return projectRoot !== void 0 && !path36.isAbsolute(file2) ? path36.resolve(projectRoot, file2) : file2;
29878
+ return projectRoot !== void 0 && !path37.isAbsolute(file2) ? path37.resolve(projectRoot, file2) : file2;
29866
29879
  }
29867
29880
  function runSection(opts) {
29868
29881
  const crossFilePairs = parseCrossFileMultiSpec(opts.spec);
@@ -29943,7 +29956,7 @@ function runSectionCrossFile(pairs, opts) {
29943
29956
  textBlocks.push(`${key}:
29944
29957
  ${sub.text}`);
29945
29958
  }
29946
- const resolvePath = (f) => opts.projectRoot !== void 0 && !path36.isAbsolute(f) ? path36.resolve(opts.projectRoot, f) : f;
29959
+ const resolvePath = (f) => opts.projectRoot !== void 0 && !path37.isAbsolute(f) ? path37.resolve(opts.projectRoot, f) : f;
29947
29960
  const text = opts.json === true ? JSON.stringify(jsonOut, null, 2) : textBlocks.join("\n\n");
29948
29961
  if (anyFound) {
29949
29962
  const fullSourceBytes = sumFileSizes(Array.from(distinctFiles, resolvePath));
@@ -30916,7 +30929,7 @@ function runConflicts(opts) {
30916
30929
  if (opts.path === void 0) {
30917
30930
  files = walkProject(process.cwd()).files;
30918
30931
  } else {
30919
- const abs = path36.resolve(opts.path);
30932
+ const abs = path37.resolve(opts.path);
30920
30933
  let stat2;
30921
30934
  try {
30922
30935
  stat2 = fs31.statSync(abs);
@@ -31310,6 +31323,10 @@ function buildChangedRefHint(cwd, ref2) {
31310
31323
  }
31311
31324
  function runChanged(opts = {}) {
31312
31325
  const ref2 = opts.ref ?? "HEAD~5";
31326
+ if (ref2.startsWith("-")) {
31327
+ emitErr(`Refusing a git ref that starts with '-': ${ref2}`);
31328
+ return 1;
31329
+ }
31313
31330
  const cwd = opts.projectRoot ?? process.cwd();
31314
31331
  const projectRoot = resolveProjectRoot({ project: cwd });
31315
31332
  let changedFiles;
@@ -31674,7 +31691,7 @@ function runGrep(opts) {
31674
31691
  try {
31675
31692
  for (const entry of fs31.readdirSync(dir)) {
31676
31693
  if (entry.startsWith(".")) continue;
31677
- const full = path36.join(dir, entry);
31694
+ const full = path37.join(dir, entry);
31678
31695
  let lst;
31679
31696
  try {
31680
31697
  lst = fs31.lstatSync(full);
@@ -31716,14 +31733,14 @@ function runGrep(opts) {
31716
31733
  }
31717
31734
  const stat2 = fs31.statSync(searchPath);
31718
31735
  if (stat2.isDirectory()) {
31719
- const pinned = activePins?.get(pinKey(path36.resolve(searchPath)));
31736
+ const pinned = activePins?.get(pinKey(path37.resolve(searchPath)));
31720
31737
  if (pinned !== void 0) verifyPin(searchPath, pinned);
31721
31738
  let boundaryReal;
31722
31739
  try {
31723
31740
  boundaryReal = fs31.realpathSync(searchPath);
31724
31741
  } catch (err2) {
31725
31742
  if (pinned === void 0) {
31726
- boundaryReal = path36.resolve(searchPath);
31743
+ boundaryReal = path37.resolve(searchPath);
31727
31744
  } else {
31728
31745
  throw new ConfinementIdentityError(
31729
31746
  `refused: "${searchPath}" could not be resolved after validation (${String(err2)}). The path may have been replaced or redirected after the confinement check, so the search was not performed.`
@@ -31854,7 +31871,7 @@ function runConfigGet(opts) {
31854
31871
  emit2(value);
31855
31872
  return 0;
31856
31873
  }
31857
- const ext2 = path36.extname(opts.file).toLowerCase();
31874
+ const ext2 = path37.extname(opts.file).toLowerCase();
31858
31875
  if (ext2 === ".json") {
31859
31876
  try {
31860
31877
  let obj = JSON.parse(text);
@@ -31972,7 +31989,7 @@ function runExports(opts) {
31972
31989
  names.push(s.name);
31973
31990
  }
31974
31991
  }
31975
- const ext2 = path36.extname(opts.file).toLowerCase();
31992
+ const ext2 = path37.extname(opts.file).toLowerCase();
31976
31993
  const text = readFileText(diskPath);
31977
31994
  if (text === null && symbols.length === 0) {
31978
31995
  emitErr(`Could not read: ${opts.file}`);
@@ -32310,9 +32327,9 @@ function extractImports(text, ext2) {
32310
32327
  return found;
32311
32328
  }
32312
32329
  function importsExtensionFor(filePath) {
32313
- const base = path36.basename(filePath).toLowerCase();
32330
+ const base = path37.basename(filePath).toLowerCase();
32314
32331
  if (base === "makefile" || base === "gnumakefile" || base === "bsdmakefile") return ".mk";
32315
- return path36.extname(filePath);
32332
+ return path37.extname(filePath);
32316
32333
  }
32317
32334
  function runImports(opts) {
32318
32335
  const multiFiles = parseMultiFileSpec(opts.file);
@@ -32403,7 +32420,7 @@ async function runSemantic(query, opts) {
32403
32420
  }
32404
32421
  const n = opts.limit !== void 0 && Number.isFinite(opts.limit) ? opts.limit : 20;
32405
32422
  if (opts.projectRoot !== void 0) {
32406
- if (!path36.isAbsolute(opts.projectRoot) || !fs31.existsSync(opts.projectRoot) || !fs31.statSync(opts.projectRoot).isDirectory()) {
32423
+ if (!path37.isAbsolute(opts.projectRoot) || !fs31.existsSync(opts.projectRoot) || !fs31.statSync(opts.projectRoot).isDirectory()) {
32407
32424
  const message = `token-goat: projectRoot must be an absolute, existing directory, got '${opts.projectRoot}'`;
32408
32425
  if (opts.json === true) {
32409
32426
  return { text: JSON.stringify({ error: message }, null, 2), code: 1 };
@@ -32655,14 +32672,14 @@ var init_read_commands = __esm({
32655
32672
  });
32656
32673
 
32657
32674
  // src/repomap.ts
32658
- import * as path37 from "path";
32675
+ import * as path38 from "path";
32659
32676
  function getTrackedFiles(cwd = process.cwd()) {
32660
32677
  try {
32661
32678
  const result = runGit(["ls-files"], { cwd });
32662
32679
  if (result.exitCode !== 0 || !result.stdout) {
32663
32680
  return [];
32664
32681
  }
32665
- return result.stdout.split("\n").filter((line) => line.trim().length > 0).map((rel) => path37.join(cwd, rel));
32682
+ return result.stdout.split("\n").filter((line) => line.trim().length > 0).map((rel) => path38.join(cwd, rel));
32666
32683
  } catch {
32667
32684
  return [];
32668
32685
  }
@@ -32678,7 +32695,7 @@ var init_repomap = __esm({
32678
32695
  // src/graph_commands.ts
32679
32696
  import * as fs32 from "node:fs";
32680
32697
  import * as os9 from "node:os";
32681
- import * as path38 from "node:path";
32698
+ import * as path39 from "node:path";
32682
32699
  import { execFileSync, spawnSync as spawnSync4 } from "node:child_process";
32683
32700
  import { randomUUID as randomUUID2 } from "node:crypto";
32684
32701
  function emit3(text) {
@@ -32971,7 +32988,19 @@ function runImpact(opts) {
32971
32988
  }
32972
32989
  }
32973
32990
  hops.delete(rootName);
32974
- const sorted = [...hops.entries()].sort(compareHopEntries).slice(0, top);
32991
+ const allSorted = [...hops.entries()].sort(compareHopEntries);
32992
+ const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
32993
+ const grepped = matchesGrep !== void 0 ? allSorted.filter(([symbol3]) => matchesGrep(symbol3)) : allSorted;
32994
+ const sorted = grepped.slice(0, top);
32995
+ if (matchesGrep !== void 0 && sorted.length === 0 && allSorted.length > 0) {
32996
+ if (opts.json === true) {
32997
+ emitErr2(grepFilteredToEmptyNotice(allSorted.length, opts.grep, "impacted symbol", "impacted symbols"));
32998
+ emit3(JSON.stringify([], null, 2));
32999
+ return 0;
33000
+ }
33001
+ emit3(grepFilteredToEmptyNotice(allSorted.length, opts.grep, "impacted symbol", "impacted symbols"));
33002
+ return 0;
33003
+ }
32975
33004
  if (sorted.length === 0) {
32976
33005
  if (opts.excludeTests === true && suppressedCount > 0) {
32977
33006
  if (opts.json === true) {
@@ -33107,17 +33136,17 @@ function runDeps(opts) {
33107
33136
  }
33108
33137
  const ext2 = importsExtensionFor(opts.file);
33109
33138
  const raw = extractImports(text, ext2);
33110
- const dir = path38.dirname(opts.file);
33139
+ const dir = path39.dirname(opts.file);
33111
33140
  const internal = [];
33112
33141
  const external = [];
33113
33142
  for (const imp of raw) {
33114
33143
  if (imp.startsWith("./") || imp.startsWith("../")) {
33115
- const base = path38.resolve(dir, imp);
33144
+ const base = path39.resolve(dir, imp);
33116
33145
  let resolved = imp;
33117
33146
  if (fs32.existsSync(base) && fs32.statSync(base).isFile()) {
33118
33147
  resolved = base;
33119
33148
  } else {
33120
- const baseExt = path38.extname(base);
33149
+ const baseExt = path39.extname(base);
33121
33150
  const bareBase = SOURCE_EXTENSIONS.includes(baseExt) ? base.slice(0, -baseExt.length) : base;
33122
33151
  for (const srcExt of SOURCE_EXTENSIONS) {
33123
33152
  const candidate = bareBase + srcExt;
@@ -33128,7 +33157,7 @@ function runDeps(opts) {
33128
33157
  }
33129
33158
  if (resolved === imp && fs32.existsSync(base) && fs32.statSync(base).isDirectory()) {
33130
33159
  for (const srcExt of SOURCE_EXTENSIONS) {
33131
- const candidate = path38.join(base, "index" + srcExt);
33160
+ const candidate = path39.join(base, "index" + srcExt);
33132
33161
  if (fs32.existsSync(candidate)) {
33133
33162
  resolved = candidate;
33134
33163
  break;
@@ -33144,7 +33173,7 @@ function runDeps(opts) {
33144
33173
  }
33145
33174
  }
33146
33175
  const rootDir = resolveProjectRoot({ project: process.cwd() });
33147
- const displayInternal = internal.map((i) => path38.isAbsolute(i) ? toDisplayPath(rootDir, normalizePath(i)) : i);
33176
+ const displayInternal = internal.map((i) => path39.isAbsolute(i) ? toDisplayPath(rootDir, normalizePath(i)) : i);
33148
33177
  const preFilterCount = displayInternal.length + external.length;
33149
33178
  const matchesGrep = opts.grep !== void 0 ? compileGrepMatcher(opts.grep) : void 0;
33150
33179
  const filteredInternal = matchesGrep !== void 0 ? displayInternal.filter((i) => matchesGrep(i)) : displayInternal;
@@ -33537,15 +33566,15 @@ function runArch(opts) {
33537
33566
  const importedBy = /* @__PURE__ */ new Map();
33538
33567
  const resolveRelImport = (fromFile, spec) => {
33539
33568
  if (!spec.startsWith(".")) return null;
33540
- const dir = path38.dirname(fromFile);
33569
+ const dir = path39.dirname(fromFile);
33541
33570
  const strippedSpec = spec.replace(/\.(m?js|cjs)$/, "");
33542
- const base = path38.resolve(dir, strippedSpec);
33571
+ const base = path39.resolve(dir, strippedSpec);
33543
33572
  for (const ext2 of ["", ".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs", ".cjs", ".cts", ".py"]) {
33544
33573
  const candidate = base + ext2;
33545
33574
  const match2 = filesByFoldedPath.get(foldPath(candidate));
33546
33575
  if (match2 !== void 0) return match2;
33547
33576
  }
33548
- const idx = path38.join(base, "index");
33577
+ const idx = path39.join(base, "index");
33549
33578
  for (const ext2 of [".ts", ".js", ".tsx", ".jsx", ".mts", ".cts"]) {
33550
33579
  const candidate = idx + ext2;
33551
33580
  const match2 = filesByFoldedPath.get(foldPath(candidate));
@@ -33670,7 +33699,7 @@ ANSWER:`;
33670
33699
  try {
33671
33700
  let askArgs;
33672
33701
  if (isCodex) {
33673
- codexOutPath = path38.join(os9.tmpdir(), `tg-ask-${process.pid}-${randomUUID2()}.txt`);
33702
+ codexOutPath = path39.join(os9.tmpdir(), `tg-ask-${process.pid}-${randomUUID2()}.txt`);
33674
33703
  askArgs = ["exec", "--ephemeral", "--output-last-message", codexOutPath];
33675
33704
  } else {
33676
33705
  askArgs = ["--print", "--bare", "--no-session-persistence"];
@@ -33866,12 +33895,12 @@ var init_graph_commands = __esm({
33866
33895
 
33867
33896
  // src/project_memory.ts
33868
33897
  import * as fs33 from "node:fs";
33869
- import * as path39 from "node:path";
33898
+ import * as path40 from "node:path";
33870
33899
  function ordinal(a, b) {
33871
33900
  return a < b ? -1 : a > b ? 1 : 0;
33872
33901
  }
33873
33902
  function memoryPath(projectHash2) {
33874
- return path39.join(dataDir(), "projects", `${projectHash2}_memory.toml`);
33903
+ return path40.join(dataDir(), "projects", `${projectHash2}_memory.toml`);
33875
33904
  }
33876
33905
  function validateKey(key) {
33877
33906
  if (!KEY_RE.test(key)) {
@@ -33930,7 +33959,7 @@ function save(filePath, entries) {
33930
33959
  lines2.push(`${k} = "${escaped}"`);
33931
33960
  }
33932
33961
  const content = lines2.length > 0 ? lines2.join("\n") + "\n" : "";
33933
- const dir = path39.dirname(filePath);
33962
+ const dir = path40.dirname(filePath);
33934
33963
  ensureDirSync(dir);
33935
33964
  atomicWriteText(filePath, content);
33936
33965
  }
@@ -33940,7 +33969,7 @@ function loadEntries(projectHash2) {
33940
33969
  function setEntry(projectHash2, key, value) {
33941
33970
  validateKey(key);
33942
33971
  const p = memoryPath(projectHash2);
33943
- const dir = path39.dirname(p);
33972
+ const dir = path40.dirname(p);
33944
33973
  ensureDirSync(dir);
33945
33974
  const doSet = () => {
33946
33975
  const entries = loadRaw(p);
@@ -33995,7 +34024,7 @@ var init_project_memory = __esm({
33995
34024
 
33996
34025
  // src/text_commands.ts
33997
34026
  import * as fs34 from "fs";
33998
- import * as path40 from "path";
34027
+ import * as path41 from "path";
33999
34028
  function readInput(src) {
34000
34029
  if (src !== void 0) return fs34.readFileSync(src, "utf8");
34001
34030
  return fs34.readFileSync(0, "utf8");
@@ -34046,7 +34075,7 @@ function collectTodoFiles(patterns) {
34046
34075
  if (patterns.length > 0) {
34047
34076
  const results = [];
34048
34077
  for (const p of patterns) {
34049
- const abs = path40.resolve(p);
34078
+ const abs = path41.resolve(p);
34050
34079
  try {
34051
34080
  const stat2 = fs34.statSync(abs);
34052
34081
  if (stat2.isDirectory()) {
@@ -34304,7 +34333,7 @@ function isProjectFrame(framePath, cwd) {
34304
34333
  if (framePath.includes("/rustc/")) return false;
34305
34334
  if (framePath.includes(".cargo/registry") || framePath.includes(".cargo\\registry")) return false;
34306
34335
  if (/^<.+>$/.test(framePath)) return false;
34307
- if (!path40.isAbsolute(framePath) && !framePath.startsWith("..")) return true;
34336
+ if (!path41.isAbsolute(framePath) && !framePath.startsWith("..")) return true;
34308
34337
  return false;
34309
34338
  }
34310
34339
  function resolveFrameSymbol(frame, projectRoot) {
@@ -34490,17 +34519,17 @@ function findLockfile(startPath) {
34490
34519
  if (stat2 !== void 0 && stat2.isFile()) {
34491
34520
  return { file: startPath, others: [] };
34492
34521
  }
34493
- const dir = stat2 !== void 0 && stat2.isDirectory() ? startPath : path40.dirname(startPath);
34522
+ const dir = stat2 !== void 0 && stat2.isDirectory() ? startPath : path41.dirname(startPath);
34494
34523
  const found = [];
34495
34524
  for (const name2 of LOCK_PRIORITY) {
34496
- const candidate = path40.join(dir, name2);
34525
+ const candidate = path41.join(dir, name2);
34497
34526
  if (fs34.existsSync(candidate)) found.push(candidate);
34498
34527
  }
34499
34528
  try {
34500
34529
  const entries = fs34.readdirSync(dir);
34501
34530
  for (const e of entries) {
34502
34531
  if (/^requirements.*\.txt$/.test(e)) {
34503
- const p = path40.join(dir, e);
34532
+ const p = path41.join(dir, e);
34504
34533
  if (!found.includes(p)) found.push(p);
34505
34534
  }
34506
34535
  }
@@ -34697,7 +34726,7 @@ function parsePnpmLock(content) {
34697
34726
  return deps;
34698
34727
  }
34699
34728
  function parseLockFile(filePath) {
34700
- const base = path40.basename(filePath);
34729
+ const base = path41.basename(filePath);
34701
34730
  const content = fs34.readFileSync(filePath, "utf8");
34702
34731
  if (base === "package-lock.json") return { format: "npm", deps: parsePackageLockJson(content) };
34703
34732
  if (base === "yarn.lock") return { format: "yarn", deps: parseYarnLock(content) };
@@ -34813,7 +34842,7 @@ Depended on by direct/top-level deps (${dependedOnBy.length}):
34813
34842
  `);
34814
34843
  }
34815
34844
  function cmdLockdeps(filePath, opts) {
34816
- const target = filePath !== void 0 ? path40.resolve(filePath) : process.cwd();
34845
+ const target = filePath !== void 0 ? path41.resolve(filePath) : process.cwd();
34817
34846
  const found = findLockfile(target);
34818
34847
  if (found === null) {
34819
34848
  throw new Error("No lockfile found. Expected one of: " + LOCK_PRIORITY.join(", ") + ", requirements*.txt");
@@ -34901,7 +34930,7 @@ function cmdNote(action, key, value, opts) {
34901
34930
  throw new Error(`Unknown note action: ${action}. Use: set, get, unset, list, clear`);
34902
34931
  }
34903
34932
  function loadAllSessionReadCounts() {
34904
- const sessionsDir = path40.join(tokenGoatHome(), "sessions");
34933
+ const sessionsDir = path41.join(tokenGoatHome(), "sessions");
34905
34934
  const totals = /* @__PURE__ */ new Map();
34906
34935
  let entries;
34907
34936
  try {
@@ -34911,7 +34940,7 @@ function loadAllSessionReadCounts() {
34911
34940
  }
34912
34941
  for (const entry of entries) {
34913
34942
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
34914
- const filePath = path40.join(sessionsDir, entry.name);
34943
+ const filePath = path41.join(sessionsDir, entry.name);
34915
34944
  let raw;
34916
34945
  try {
34917
34946
  raw = JSON.parse(fs34.readFileSync(filePath, "utf8"));
@@ -34999,8 +35028,8 @@ function detectWalkMode(cwd) {
34999
35028
  if (project?.marker === ".git") return "git";
35000
35029
  let cur = cwd;
35001
35030
  while (true) {
35002
- if (fs34.existsSync(path40.join(cur, ".git"))) return "git";
35003
- const parent = path40.dirname(cur);
35031
+ if (fs34.existsSync(path41.join(cur, ".git"))) return "git";
35032
+ const parent = path41.dirname(cur);
35004
35033
  if (parent === cur) break;
35005
35034
  cur = parent;
35006
35035
  }
@@ -35198,7 +35227,7 @@ var init_confirm_apply = __esm({
35198
35227
 
35199
35228
  // src/memory_prune.ts
35200
35229
  import * as fs36 from "node:fs";
35201
- import * as path41 from "node:path";
35230
+ import * as path42 from "node:path";
35202
35231
  function parseIndex(text) {
35203
35232
  const passthrough2 = [];
35204
35233
  const entries = [];
@@ -35241,7 +35270,7 @@ function pruneIndex(memoryDir, opts) {
35241
35270
  changed: false,
35242
35271
  tokensSaved: 0
35243
35272
  };
35244
- const memoryMd = path41.join(memoryDir, "MEMORY.md");
35273
+ const memoryMd = path42.join(memoryDir, "MEMORY.md");
35245
35274
  let text;
35246
35275
  try {
35247
35276
  text = fs36.readFileSync(memoryMd, "utf-8");
@@ -35255,7 +35284,7 @@ function pruneIndex(memoryDir, opts) {
35255
35284
  const dups = [];
35256
35285
  for (const entry of entries) {
35257
35286
  const isUrl = URL_SCHEME_RE.test(entry.target);
35258
- const targetExists = isUrl ? true : path41.isAbsolute(entry.target) ? fs36.existsSync(entry.target) : fs36.existsSync(path41.join(memoryDir, entry.target));
35287
+ const targetExists = isUrl ? true : path42.isAbsolute(entry.target) ? fs36.existsSync(entry.target) : fs36.existsSync(path42.join(memoryDir, entry.target));
35259
35288
  const foldedTarget = foldPath(entry.target);
35260
35289
  if (!targetExists) {
35261
35290
  dead.push(entry);
@@ -35399,7 +35428,7 @@ async function tryEmbeddingClusters(siblings, snippets, threshold) {
35399
35428
  }
35400
35429
  async function findContentDuplicates(memoryDir, _opts) {
35401
35430
  const threshold = _opts?.threshold ?? 0.92;
35402
- const siblings = fs36.readdirSync(memoryDir).filter((name2) => name2.toLowerCase().endsWith(".md") && name2.toLowerCase() !== "memory.md").map((name2) => path41.join(memoryDir, name2)).sort();
35431
+ const siblings = fs36.readdirSync(memoryDir).filter((name2) => name2.toLowerCase().endsWith(".md") && name2.toLowerCase() !== "memory.md").map((name2) => path42.join(memoryDir, name2)).sort();
35403
35432
  if (siblings.length < 2) {
35404
35433
  return [];
35405
35434
  }
@@ -35483,7 +35512,7 @@ function auditClaudeMd(files) {
35483
35512
  const overlaps = [];
35484
35513
  for (const [stripped, filesSet] of lineToFiles) {
35485
35514
  if (filesSet.has(report.path) && filesSet.size > 1) {
35486
- const others = Array.from(filesSet).filter((p) => p !== report.path).map((p) => path41.basename(p));
35515
+ const others = Array.from(filesSet).filter((p) => p !== report.path).map((p) => path42.basename(p));
35487
35516
  if (others.length > 0) {
35488
35517
  if (stripped.length > 60) {
35489
35518
  overlaps.push(
@@ -35516,7 +35545,7 @@ var init_memory_prune = __esm({
35516
35545
  // src/cli_context_stats.ts
35517
35546
  import * as fs37 from "node:fs";
35518
35547
  import * as os10 from "node:os";
35519
- import * as path42 from "node:path";
35548
+ import * as path43 from "node:path";
35520
35549
  function tok(filePath) {
35521
35550
  try {
35522
35551
  const size = fs37.statSync(filePath).size;
@@ -35528,18 +35557,18 @@ function tok(filePath) {
35528
35557
  function findClaudeMdFiles(projectRoot, homeDir = os10.homedir()) {
35529
35558
  const found = [];
35530
35559
  const seen = /* @__PURE__ */ new Set();
35531
- let current = path42.resolve(projectRoot);
35560
+ let current = path43.resolve(projectRoot);
35532
35561
  while (true) {
35533
- const candidate = path42.join(current, "CLAUDE.md");
35562
+ const candidate = path43.join(current, "CLAUDE.md");
35534
35563
  if (!seen.has(candidate) && fs37.existsSync(candidate)) {
35535
35564
  found.push(candidate);
35536
35565
  seen.add(candidate);
35537
35566
  }
35538
- const parent = path42.dirname(current);
35567
+ const parent = path43.dirname(current);
35539
35568
  if (parent === current) break;
35540
35569
  current = parent;
35541
35570
  }
35542
- const globalMd = path42.join(homeDir, ".claude", "CLAUDE.md");
35571
+ const globalMd = path43.join(homeDir, ".claude", "CLAUDE.md");
35543
35572
  if (!seen.has(globalMd) && fs37.existsSync(globalMd)) {
35544
35573
  found.push(globalMd);
35545
35574
  }
@@ -35547,9 +35576,9 @@ function findClaudeMdFiles(projectRoot, homeDir = os10.homedir()) {
35547
35576
  }
35548
35577
  function findMemoryMd(projectRoot, homeDir = os10.homedir(), alternateRoots = []) {
35549
35578
  try {
35550
- const projectsDir = path42.join(homeDir, ".claude", "projects");
35579
+ const projectsDir = path43.join(homeDir, ".claude", "projects");
35551
35580
  if (!fs37.existsSync(projectsDir)) return null;
35552
- const rootStr = path42.resolve(projectRoot);
35581
+ const rootStr = path43.resolve(projectRoot);
35553
35582
  const candidateRoots2 = [rootStr];
35554
35583
  try {
35555
35584
  const realRoot = fs37.realpathSync.native(rootStr);
@@ -35557,12 +35586,12 @@ function findMemoryMd(projectRoot, homeDir = os10.homedir(), alternateRoots = []
35557
35586
  } catch {
35558
35587
  }
35559
35588
  for (const alternate of alternateRoots) {
35560
- const resolved = path42.resolve(alternate);
35589
+ const resolved = path43.resolve(alternate);
35561
35590
  if (!candidateRoots2.includes(resolved)) candidateRoots2.push(resolved);
35562
35591
  }
35563
35592
  for (const root of candidateRoots2) {
35564
35593
  const expectedSlug = root.replace(/[^A-Za-z0-9]/g, "-");
35565
- const candidate = path42.join(projectsDir, expectedSlug, "memory", "MEMORY.md");
35594
+ const candidate = path43.join(projectsDir, expectedSlug, "memory", "MEMORY.md");
35566
35595
  if (fs37.existsSync(candidate)) return candidate;
35567
35596
  }
35568
35597
  return null;
@@ -35577,10 +35606,10 @@ function buildStats(projectRoot, homeDir = os10.homedir(), alternateRoots = [])
35577
35606
  for (const p of claudeMds) {
35578
35607
  const t = tok(p);
35579
35608
  claudeMdTotal += t;
35580
- const parentDir = path42.basename(path42.dirname(p));
35609
+ const parentDir = path43.basename(path43.dirname(p));
35581
35610
  const label = parentDir === ".claude" ? "~/.claude/CLAUDE.md" : (() => {
35582
35611
  try {
35583
- return path42.relative(projectRoot, p);
35612
+ return path43.relative(projectRoot, p);
35584
35613
  } catch {
35585
35614
  return p;
35586
35615
  }
@@ -35644,7 +35673,7 @@ async function runContextStats(opts = {}) {
35644
35673
  process.stdout.write("[--fix] No MEMORY.md found; nothing to prune.\n");
35645
35674
  } else {
35646
35675
  const memPath = result.memory_md_path;
35647
- const pruneResult = pruneIndex(path42.dirname(memPath), { dryRun: true });
35676
+ const pruneResult = pruneIndex(path43.dirname(memPath), { dryRun: true });
35648
35677
  if (!pruneResult.changed || pruneResult.after === void 0) {
35649
35678
  process.stdout.write("[--fix] MEMORY.md already clean; nothing to prune.\n");
35650
35679
  } else {
@@ -35686,7 +35715,7 @@ var init_cli_context_stats = __esm({
35686
35715
 
35687
35716
  // src/baseline.ts
35688
35717
  import * as fs38 from "node:fs";
35689
- import * as path43 from "node:path";
35718
+ import * as path44 from "node:path";
35690
35719
  function walkProject(rootDir, opts = {}) {
35691
35720
  const files = [];
35692
35721
  const languages = {};
@@ -35705,7 +35734,7 @@ function walkProject(rootDir, opts = {}) {
35705
35734
  continue;
35706
35735
  }
35707
35736
  for (const entry of entries) {
35708
- const full = path43.join(dir, entry.name);
35737
+ const full = path44.join(dir, entry.name);
35709
35738
  if (entry.isDirectory()) {
35710
35739
  if (SKIP_DIRS.has(entry.name) || extraSkipDirs.includes(entry.name)) continue;
35711
35740
  if (entry.name.startsWith(".") && entry.name !== ".") {
@@ -35769,7 +35798,7 @@ function fetchTopSymbols(limit, dbPath, rootDir) {
35769
35798
  }
35770
35799
  }
35771
35800
  function buildProjectMap(rootDir = process.cwd(), opts = {}) {
35772
- const root = path43.resolve(rootDir);
35801
+ const root = path44.resolve(rootDir);
35773
35802
  const config2 = loadConfig();
35774
35803
  const { files, languages } = walkProject(root, { excludeTests: config2.repomap.exclude_tests });
35775
35804
  const compact = opts.compact === true || files.length > config2.repomap.compact_file_threshold;
@@ -35783,7 +35812,7 @@ function buildProjectMap(rootDir = process.cwd(), opts = {}) {
35783
35812
  mtime = 0;
35784
35813
  }
35785
35814
  return { f, mtime };
35786
- }).sort((a, b) => b.mtime - a.mtime).slice(0, compact ? 5 : 15).map((x) => path43.relative(root, x.f));
35815
+ }).sort((a, b) => b.mtime - a.mtime).slice(0, compact ? 5 : 15).map((x) => path44.relative(root, x.f));
35787
35816
  return {
35788
35817
  rootDir: root,
35789
35818
  fileCount: files.length,
@@ -35795,7 +35824,7 @@ function buildProjectMap(rootDir = process.cwd(), opts = {}) {
35795
35824
  }
35796
35825
  function formatProjectMap(map3, compact = false) {
35797
35826
  const lines2 = [];
35798
- const rel = path43.basename(map3.rootDir);
35827
+ const rel = path44.basename(map3.rootDir);
35799
35828
  lines2.push(`# Project map: ${rel}`);
35800
35829
  lines2.push(`Files: ${map3.fileCount}`);
35801
35830
  const langPairs = Object.entries(map3.languages).sort((a, b) => b[1] - a[1]);
@@ -35823,7 +35852,7 @@ function formatProjectMap(map3, compact = false) {
35823
35852
  }
35824
35853
  function mapLookupBytesSaved(map3, emittedText) {
35825
35854
  const referencedFiles = /* @__PURE__ */ new Set([
35826
- ...map3.recentFiles.map((f) => normalizePath(path43.resolve(map3.rootDir, f))),
35855
+ ...map3.recentFiles.map((f) => normalizePath(path44.resolve(map3.rootDir, f))),
35827
35856
  ...map3.topSymbols.map((s) => normalizePath(s.filePath))
35828
35857
  ]);
35829
35858
  let fullSourceBytes = 0;
@@ -35840,7 +35869,7 @@ function findMemSuggestionCandidates(projectRoot) {
35840
35869
  const claudeMdFiles = findClaudeMdFiles(projectRoot);
35841
35870
  const candidateFiles = new Set(claudeMdFiles);
35842
35871
  for (const claudeMd of claudeMdFiles) {
35843
- const agentsMd = path43.join(path43.dirname(claudeMd), "AGENTS.md");
35872
+ const agentsMd = path44.join(path44.dirname(claudeMd), "AGENTS.md");
35844
35873
  if (fs38.existsSync(agentsMd)) candidateFiles.add(agentsMd);
35845
35874
  }
35846
35875
  const suggestions = [];
@@ -35876,7 +35905,7 @@ function formatMemSuggestions(projectRoot) {
35876
35905
  if (suggestions.length === 0) return "";
35877
35906
  const lines2 = ["", "## mem suggestions"];
35878
35907
  for (const s of suggestions) {
35879
- const basename22 = path43.basename(s.path);
35908
+ const basename22 = path44.basename(s.path);
35880
35909
  lines2.push(
35881
35910
  "Consider: mem import --from-md " + s.path + " # migrates " + s.count + " preference-shaped lines from " + basename22 + " as pending facts for review"
35882
35911
  );
@@ -35930,7 +35959,7 @@ var init_baseline = __esm({
35930
35959
 
35931
35960
  // src/content_store.ts
35932
35961
  import { deflateRawSync } from "node:zlib";
35933
- import * as path66 from "node:path";
35962
+ import * as path67 from "node:path";
35934
35963
  function estimateTextTokens(bytes) {
35935
35964
  return Math.round(bytes / TEXT_BYTES_PER_TOKEN);
35936
35965
  }
@@ -35946,7 +35975,7 @@ function contentId(text) {
35946
35975
  return `tg_${shortFingerprint(text)}`;
35947
35976
  }
35948
35977
  function normalizeProjectRoot(projectRoot) {
35949
- const candidate = path66.resolve(projectRoot ?? process.cwd());
35978
+ const candidate = path67.resolve(projectRoot ?? process.cwd());
35950
35979
  return findProject(candidate)?.root ?? candidate;
35951
35980
  }
35952
35981
  function handoffId(name2, projectRoot) {
@@ -36310,10 +36339,10 @@ function mergeDefs(...defs) {
36310
36339
  function cloneDef(schema) {
36311
36340
  return mergeDefs(schema._zod.def);
36312
36341
  }
36313
- function getElementAtPath(obj, path69) {
36314
- if (!path69)
36342
+ function getElementAtPath(obj, path70) {
36343
+ if (!path70)
36315
36344
  return obj;
36316
- return path69.reduce((acc, key) => acc?.[key], obj);
36345
+ return path70.reduce((acc, key) => acc?.[key], obj);
36317
36346
  }
36318
36347
  function promiseAllObject(promisesObj) {
36319
36348
  const keys = Object.keys(promisesObj);
@@ -36641,11 +36670,11 @@ function explicitlyAborted(x, startIndex = 0) {
36641
36670
  }
36642
36671
  return false;
36643
36672
  }
36644
- function prefixIssues(path69, issues) {
36673
+ function prefixIssues(path70, issues) {
36645
36674
  return issues.map((iss) => {
36646
36675
  var _a6;
36647
36676
  (_a6 = iss).path ?? (_a6.path = []);
36648
- iss.path.unshift(path69);
36677
+ iss.path.unshift(path70);
36649
36678
  return iss;
36650
36679
  });
36651
36680
  }
@@ -36863,16 +36892,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
36863
36892
  }
36864
36893
  function formatError2(error52, mapper = (issue2) => issue2.message) {
36865
36894
  const fieldErrors = { _errors: [] };
36866
- const processError = (error53, path69 = []) => {
36895
+ const processError = (error53, path70 = []) => {
36867
36896
  for (const issue2 of error53.issues) {
36868
36897
  if (issue2.code === "invalid_union" && issue2.errors.length) {
36869
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
36898
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
36870
36899
  } else if (issue2.code === "invalid_key") {
36871
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
36900
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
36872
36901
  } else if (issue2.code === "invalid_element") {
36873
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
36902
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
36874
36903
  } else {
36875
- const fullpath = [...path69, ...issue2.path];
36904
+ const fullpath = [...path70, ...issue2.path];
36876
36905
  if (fullpath.length === 0) {
36877
36906
  fieldErrors._errors.push(mapper(issue2));
36878
36907
  } else {
@@ -36899,17 +36928,17 @@ function formatError2(error52, mapper = (issue2) => issue2.message) {
36899
36928
  }
36900
36929
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
36901
36930
  const result = { errors: [] };
36902
- const processError = (error53, path69 = []) => {
36931
+ const processError = (error53, path70 = []) => {
36903
36932
  var _a6, _b;
36904
36933
  for (const issue2 of error53.issues) {
36905
36934
  if (issue2.code === "invalid_union" && issue2.errors.length) {
36906
- issue2.errors.map((issues) => processError({ issues }, [...path69, ...issue2.path]));
36935
+ issue2.errors.map((issues) => processError({ issues }, [...path70, ...issue2.path]));
36907
36936
  } else if (issue2.code === "invalid_key") {
36908
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
36937
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
36909
36938
  } else if (issue2.code === "invalid_element") {
36910
- processError({ issues: issue2.issues }, [...path69, ...issue2.path]);
36939
+ processError({ issues: issue2.issues }, [...path70, ...issue2.path]);
36911
36940
  } else {
36912
- const fullpath = [...path69, ...issue2.path];
36941
+ const fullpath = [...path70, ...issue2.path];
36913
36942
  if (fullpath.length === 0) {
36914
36943
  result.errors.push(mapper(issue2));
36915
36944
  continue;
@@ -36941,8 +36970,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
36941
36970
  }
36942
36971
  function toDotPath(_path) {
36943
36972
  const segs = [];
36944
- const path69 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
36945
- for (const seg of path69) {
36973
+ const path70 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
36974
+ for (const seg of path70) {
36946
36975
  if (typeof seg === "number")
36947
36976
  segs.push(`[${seg}]`);
36948
36977
  else if (typeof seg === "symbol")
@@ -37212,8 +37241,8 @@ var init_regexes = __esm({
37212
37241
  _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
37213
37242
  ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
37214
37243
  ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
37215
- mac = (delimiter2) => {
37216
- const escapedDelim = escapeRegex(delimiter2 ?? ":");
37244
+ mac = (delimiter3) => {
37245
+ const escapedDelim = escapeRegex(delimiter3 ?? ":");
37217
37246
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
37218
37247
  };
37219
37248
  cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -50445,13 +50474,13 @@ function resolveRef(ref2, ctx) {
50445
50474
  if (!ref2.startsWith("#")) {
50446
50475
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
50447
50476
  }
50448
- const path69 = ref2.slice(1).split("/").filter(Boolean);
50449
- if (path69.length === 0) {
50477
+ const path70 = ref2.slice(1).split("/").filter(Boolean);
50478
+ if (path70.length === 0) {
50450
50479
  return ctx.rootSchema;
50451
50480
  }
50452
50481
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
50453
- if (path69[0] === defsKey) {
50454
- const key = path69[1];
50482
+ if (path70[0] === defsKey) {
50483
+ const key = path70[1];
50455
50484
  if (!key || !ctx.defs[key]) {
50456
50485
  throw new Error(`Reference not found: ${ref2}`);
50457
50486
  }
@@ -51228,7 +51257,7 @@ __export(mcp_server_exports, {
51228
51257
  createMcpServer: () => createMcpServer
51229
51258
  });
51230
51259
  import * as fs59 from "fs";
51231
- import * as path67 from "path";
51260
+ import * as path68 from "path";
51232
51261
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
51233
51262
  function mcpFriendlyText(text) {
51234
51263
  let out2 = text.replace(TOKEN_GOAT_RETRY_RE, (_match, cmd, arg) => {
@@ -51297,7 +51326,7 @@ function resolveToolRoot(projectRoot) {
51297
51326
  }
51298
51327
  function checkWithinProjectRoot(target, resolvedRoot) {
51299
51328
  const root = forCompare(normalizePath(realPathOrSelf(resolvedRoot)));
51300
- const abs = path67.resolve(resolvedRoot, normalizePath(target));
51329
+ const abs = path68.resolve(resolvedRoot, normalizePath(target));
51301
51330
  let identity;
51302
51331
  try {
51303
51332
  identity = fileIdentity(fs59.statSync(abs, { bigint: true }));
@@ -51316,6 +51345,16 @@ function specFilePart(spec) {
51316
51345
  }
51317
51346
  function confineTargets(targets, resolvedRoot, splitCommas = true) {
51318
51347
  if (!loadConfig(resolvedRoot).mcp.confine_reads_to_project_root) return { ok: true, targets, pins: NO_PINS };
51348
+ const allowedRoots = loadConfig().mcp.allowed_roots;
51349
+ if (allowedRoots.length > 0 && !allowedRoots.some((allowed) => checkWithinProjectRoot(resolvedRoot, allowed).inside)) {
51350
+ return {
51351
+ ok: false,
51352
+ refusal: toCallToolResult({
51353
+ text: `refused: "${resolvedRoot}" is not inside any root listed in mcp.allowed_roots. A caller-supplied projectRoot is untrusted input, so this deployment pins which roots may be named; add the root to mcp.allowed_roots (or TOKEN_GOAT_MCP_ALLOWED_ROOTS) to permit it.`,
51354
+ code: 1
51355
+ })
51356
+ };
51357
+ }
51319
51358
  const checked = [];
51320
51359
  const pins = /* @__PURE__ */ new Map();
51321
51360
  for (const raw of targets) {
@@ -52066,7 +52105,7 @@ init_define_import_meta_env();
52066
52105
  init_define_import_meta_env();
52067
52106
  init_bash_compress();
52068
52107
  import * as fs21 from "node:fs";
52069
- import * as path22 from "node:path";
52108
+ import * as path23 from "node:path";
52070
52109
  var DEFAULT_MAX_LINES = 1e3;
52071
52110
  var DEFAULT_MAX_BYTES = 64 * 1024;
52072
52111
  var MAX_INSPECT_BYTES = 2 * 1024 * 1024;
@@ -52487,13 +52526,13 @@ function loadPackageScripts(candidate, stat2) {
52487
52526
  function findNearestPackageScripts(startDir) {
52488
52527
  let dir = startDir;
52489
52528
  for (; ; ) {
52490
- const candidate = path22.join(dir, "package.json");
52529
+ const candidate = path23.join(dir, "package.json");
52491
52530
  try {
52492
52531
  const stat2 = fs21.statSync(candidate);
52493
52532
  if (stat2.isFile()) return loadPackageScripts(candidate, stat2);
52494
52533
  } catch {
52495
52534
  }
52496
- const parent = path22.dirname(dir);
52535
+ const parent = path23.dirname(dir);
52497
52536
  if (parent === dir) return null;
52498
52537
  dir = parent;
52499
52538
  }
@@ -65664,7 +65703,7 @@ function grepIntInput(toolInput, key) {
65664
65703
  function grepSignature(toolInput) {
65665
65704
  const pattern = toolInput["pattern"];
65666
65705
  if (typeof pattern !== "string" || pattern === "") return null;
65667
- const path69 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
65706
+ const path70 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
65668
65707
  const outputMode = typeof toolInput["output_mode"] === "string" ? toolInput["output_mode"] : "files_with_matches";
65669
65708
  const glob = typeof toolInput["glob"] === "string" ? toolInput["glob"] : "";
65670
65709
  const type = typeof toolInput["type"] === "string" ? toolInput["type"] : "";
@@ -65679,7 +65718,7 @@ function grepSignature(toolInput) {
65679
65718
  const offset = grepIntInput(toolInput, "offset");
65680
65719
  return JSON.stringify([
65681
65720
  pattern,
65682
- path69,
65721
+ path70,
65683
65722
  outputMode,
65684
65723
  glob,
65685
65724
  type,
@@ -65779,8 +65818,8 @@ init_session();
65779
65818
  function globSignature(toolInput) {
65780
65819
  const pattern = toolInput["pattern"];
65781
65820
  if (typeof pattern !== "string" || pattern === "") return null;
65782
- const path69 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
65783
- return JSON.stringify([pattern, path69]);
65821
+ const path70 = typeof toolInput["path"] === "string" ? toolInput["path"] : "";
65822
+ return JSON.stringify([pattern, path70]);
65784
65823
  }
65785
65824
  var { post: postGlobHandler, pre: preGlobDedupHandler } = makeDedupHintHandlers({
65786
65825
  toolName: "Glob",
@@ -65809,7 +65848,7 @@ init_stats();
65809
65848
  init_config();
65810
65849
  init_doc_compact();
65811
65850
  init_worker();
65812
- import * as path32 from "node:path";
65851
+ import * as path33 from "node:path";
65813
65852
  import { statSync as statSync15 } from "node:fs";
65814
65853
  function postEditHandlerInner(event) {
65815
65854
  const filePath = getFilePath(event);
@@ -65837,7 +65876,7 @@ function postEditHandlerInner(event) {
65837
65876
  if (loadConfig().hints.stable_doc_compacts) {
65838
65877
  markCompactStale(compactPathFor(normalized));
65839
65878
  }
65840
- const editedBasename = path32.basename(normalized);
65879
+ const editedBasename = path33.basename(normalized);
65841
65880
  if (/\.(md|mdx|markdown|rst)$/i.test(editedBasename)) {
65842
65881
  let editedSize = Infinity;
65843
65882
  try {
@@ -66159,11 +66198,11 @@ function gitStateFingerprintSync(cwd) {
66159
66198
  }
66160
66199
  }
66161
66200
  var DIR_FINGERPRINT_LISTING_CAP_ENTRIES = 1e4;
66162
- function dirStateFingerprintSync(path69) {
66201
+ function dirStateFingerprintSync(path70) {
66163
66202
  try {
66164
- const stat2 = statSync17(path69);
66203
+ const stat2 = statSync17(path70);
66165
66204
  if (!stat2.isDirectory()) return null;
66166
- const entries = readdirSync12(path69);
66205
+ const entries = readdirSync12(path70);
66167
66206
  if (entries.length <= DIR_FINGERPRINT_LISTING_CAP_ENTRIES) {
66168
66207
  return shortFingerprint(entries.slice().sort().join("\0"));
66169
66208
  }
@@ -66173,12 +66212,12 @@ function dirStateFingerprintSync(path69) {
66173
66212
  }
66174
66213
  }
66175
66214
  var FILE_FINGERPRINT_CONTENT_CAP_BYTES = 2 * 1024 * 1024;
66176
- function fileStateFingerprintSync(path69) {
66215
+ function fileStateFingerprintSync(path70) {
66177
66216
  try {
66178
- const stat2 = statSync17(path69);
66217
+ const stat2 = statSync17(path70);
66179
66218
  if (!stat2.isFile()) return null;
66180
66219
  if (stat2.size <= FILE_FINGERPRINT_CONTENT_CAP_BYTES) {
66181
- return shortFingerprint(readFileSync22(path69));
66220
+ return shortFingerprint(readFileSync22(path70));
66182
66221
  }
66183
66222
  return shortFingerprint(`${stat2.mtimeMs}\0${stat2.size}`);
66184
66223
  } catch {
@@ -66656,7 +66695,7 @@ init_baseline();
66656
66695
  init_stats();
66657
66696
  init_repomap();
66658
66697
  import * as fs60 from "fs";
66659
- import * as path68 from "path";
66698
+ import * as path69 from "path";
66660
66699
  import { homedir as homedir19 } from "os";
66661
66700
 
66662
66701
  // src/walk_index.ts
@@ -66665,27 +66704,27 @@ init_baseline();
66665
66704
  init_util2();
66666
66705
  import * as fs39 from "node:fs";
66667
66706
  import * as os11 from "node:os";
66668
- import * as path44 from "node:path";
66707
+ import * as path45 from "node:path";
66669
66708
  function isWalkExcluded(file2) {
66670
- const base = path44.basename(file2).toLowerCase();
66709
+ const base = path45.basename(file2).toLowerCase();
66671
66710
  if (base === ".env" || base.startsWith(".env.")) return true;
66672
66711
  if (base.endsWith(".d.ts")) return true;
66673
66712
  return false;
66674
66713
  }
66675
66714
  function assertWalkableRoot(root) {
66676
- let resolved = path44.resolve(root);
66715
+ let resolved = path45.resolve(root);
66677
66716
  try {
66678
66717
  resolved = fs39.realpathSync.native(resolved);
66679
66718
  } catch {
66680
66719
  }
66681
66720
  const norm = foldPath(normalizePath(resolved));
66682
- const fsRoot = foldPath(normalizePath(path44.parse(resolved).root));
66721
+ const fsRoot = foldPath(normalizePath(path45.parse(resolved).root));
66683
66722
  if (norm === fsRoot) {
66684
66723
  throw new Error(`refusing to walk-index a filesystem root: ${resolved}`);
66685
66724
  }
66686
66725
  const home = os11.homedir();
66687
66726
  if (home) {
66688
- const normHome = foldPath(normalizePath(path44.resolve(home)));
66727
+ const normHome = foldPath(normalizePath(path45.resolve(home)));
66689
66728
  if (norm === normHome) {
66690
66729
  throw new Error(`refusing to walk-index the home directory: ${resolved}`);
66691
66730
  }
@@ -66697,7 +66736,7 @@ function assertWalkableRoot(root) {
66697
66736
  }
66698
66737
  var MAX_FILES_SCANNED_FORCED = 5e5;
66699
66738
  function collectWalkIndexFiles(root, opts = {}) {
66700
- const resolved = path44.resolve(root);
66739
+ const resolved = path45.resolve(root);
66701
66740
  assertWalkableRoot(resolved);
66702
66741
  const force = opts.force === true;
66703
66742
  const ceiling = force ? MAX_FILES_SCANNED_FORCED : MAX_FILES_SCANNED;
@@ -66731,7 +66770,7 @@ init_codex_install();
66731
66770
  init_define_import_meta_env();
66732
66771
  import * as fs40 from "node:fs";
66733
66772
  import * as os12 from "node:os";
66734
- import * as path45 from "node:path";
66773
+ import * as path46 from "node:path";
66735
66774
  init_install();
66736
66775
  init_util2();
66737
66776
  init_matcher_group();
@@ -66747,7 +66786,7 @@ var GEMINI_POST_TOOLS = /* @__PURE__ */ new Set(["Bash", "Read", "Write", "Edit"
66747
66786
  var GeminiSettingsParseError = class extends Error {
66748
66787
  };
66749
66788
  function geminiSettingsPath() {
66750
- return path45.join(os12.homedir(), ".gemini", "settings.json");
66789
+ return path46.join(os12.homedir(), ".gemini", "settings.json");
66751
66790
  }
66752
66791
  function readGeminiSettings(p, opts = {}) {
66753
66792
  let raw;
@@ -66868,7 +66907,7 @@ init_install();
66868
66907
  init_util2();
66869
66908
  import * as fs41 from "node:fs";
66870
66909
  import * as os13 from "node:os";
66871
- import * as path46 from "node:path";
66910
+ import * as path47 from "node:path";
66872
66911
  var QWEN_HOOK_EVENTS = ["PreToolUse", "PostToolUse", "PreCompact", "UserPromptSubmit", "SubagentStop"];
66873
66912
  var QWEN_EVENT_ARG = {
66874
66913
  PreToolUse: "pre_tool_use",
@@ -66880,7 +66919,7 @@ var QWEN_EVENT_ARG = {
66880
66919
  var QwenSettingsParseError = class extends Error {
66881
66920
  };
66882
66921
  function qwenSettingsPath() {
66883
- return path46.join(os13.homedir(), ".qwen", "settings.json");
66922
+ return path47.join(os13.homedir(), ".qwen", "settings.json");
66884
66923
  }
66885
66924
  function readQwenSettings(p, opts = {}) {
66886
66925
  let raw;
@@ -66983,7 +67022,7 @@ function uninstallQwen() {
66983
67022
  init_define_import_meta_env();
66984
67023
  init_util2();
66985
67024
  import * as os14 from "node:os";
66986
- import * as path47 from "node:path";
67025
+ import * as path48 from "node:path";
66987
67026
 
66988
67027
  // src/bridges/pi.ts
66989
67028
  init_define_import_meta_env();
@@ -67297,16 +67336,16 @@ export default function (pi: ExtensionAPI) {
67297
67336
 
67298
67337
  // src/bridges/pi_install.ts
67299
67338
  function piGlobalExtensionPath() {
67300
- return path47.join(os14.homedir(), ".pi", "agent", "extensions", "token-goat.ts");
67339
+ return path48.join(os14.homedir(), ".pi", "agent", "extensions", "token-goat.ts");
67301
67340
  }
67302
67341
  function piLocalExtensionPath() {
67303
- return path47.join(process.cwd(), ".pi", "extensions", "token-goat.ts");
67342
+ return path48.join(process.cwd(), ".pi", "extensions", "token-goat.ts");
67304
67343
  }
67305
67344
  function piExtensionPath(opts = {}) {
67306
67345
  return opts.local === true ? piLocalExtensionPath() : piGlobalExtensionPath();
67307
67346
  }
67308
67347
  function piEntrySidecarPath(opts = {}) {
67309
- return path47.join(path47.dirname(piExtensionPath(opts)), "token-goat-entry.json");
67348
+ return path48.join(path48.dirname(piExtensionPath(opts)), "token-goat-entry.json");
67310
67349
  }
67311
67350
  function installPi(opts = {}) {
67312
67351
  const extensionPath = piExtensionPath(opts);
@@ -67329,7 +67368,7 @@ function uninstallPi(opts = {}) {
67329
67368
  init_define_import_meta_env();
67330
67369
  init_util2();
67331
67370
  import * as os15 from "node:os";
67332
- import * as path48 from "node:path";
67371
+ import * as path49 from "node:path";
67333
67372
 
67334
67373
  // src/bridges/opencode.ts
67335
67374
  init_define_import_meta_env();
@@ -67609,17 +67648,17 @@ function opencodeGlobalConfigDir() {
67609
67648
  if (process.platform === "win32") {
67610
67649
  const appData = process.env["APPDATA"];
67611
67650
  if (appData !== void 0 && appData.trim() !== "") return appData;
67612
- return path48.join(os15.homedir(), "AppData", "Roaming");
67651
+ return path49.join(os15.homedir(), "AppData", "Roaming");
67613
67652
  }
67614
67653
  const xdgConfigHome = process.env["XDG_CONFIG_HOME"];
67615
67654
  if (xdgConfigHome !== void 0 && xdgConfigHome.trim() !== "") return xdgConfigHome;
67616
- return path48.join(os15.homedir(), ".config");
67655
+ return path49.join(os15.homedir(), ".config");
67617
67656
  }
67618
67657
  function opencodePluginPath() {
67619
- return path48.join(opencodeGlobalConfigDir(), "opencode", "plugins", "token-goat.ts");
67658
+ return path49.join(opencodeGlobalConfigDir(), "opencode", "plugins", "token-goat.ts");
67620
67659
  }
67621
67660
  function opencodeEntrySidecarPath() {
67622
- return path48.join(path48.dirname(opencodePluginPath()), "token-goat-entry.json");
67661
+ return path49.join(path49.dirname(opencodePluginPath()), "token-goat-entry.json");
67623
67662
  }
67624
67663
  function installOpencode() {
67625
67664
  const pluginPath = opencodePluginPath();
@@ -67635,7 +67674,7 @@ init_define_import_meta_env();
67635
67674
  init_util2();
67636
67675
  import * as fs42 from "node:fs";
67637
67676
  import * as os16 from "node:os";
67638
- import * as path49 from "node:path";
67677
+ import * as path50 from "node:path";
67639
67678
 
67640
67679
  // src/bridges/openclaw.ts
67641
67680
  init_define_import_meta_env();
@@ -67771,16 +67810,16 @@ var OpenclawConfigParseError = class extends Error {
67771
67810
  };
67772
67811
  var OPENCLAW_PLUGIN_ID = "token-goat";
67773
67812
  function openclawHomeDir() {
67774
- return path49.join(os16.homedir(), ".openclaw");
67813
+ return path50.join(os16.homedir(), ".openclaw");
67775
67814
  }
67776
67815
  function openclawConfigPath() {
67777
- return path49.join(openclawHomeDir(), "openclaw.json");
67816
+ return path50.join(openclawHomeDir(), "openclaw.json");
67778
67817
  }
67779
67818
  function openclawPluginPath() {
67780
- return path49.join(openclawHomeDir(), "plugins", "token-goat.ts");
67819
+ return path50.join(openclawHomeDir(), "plugins", "token-goat.ts");
67781
67820
  }
67782
67821
  function openclawEntrySidecarPath() {
67783
- return path49.join(path49.dirname(openclawPluginPath()), "token-goat-entry.json");
67822
+ return path50.join(path50.dirname(openclawPluginPath()), "token-goat-entry.json");
67784
67823
  }
67785
67824
  function readOpenclawConfig(p, opts = {}) {
67786
67825
  let raw;
@@ -67833,7 +67872,7 @@ function installOpenclaw() {
67833
67872
  const settings = readOpenclawConfig(configPath2, { strict: true });
67834
67873
  const entryPath = process.argv[1];
67835
67874
  if (entryPath) {
67836
- ensureDirSync(path49.dirname(pluginPath));
67875
+ ensureDirSync(path50.dirname(pluginPath));
67837
67876
  atomicWriteText(openclawEntrySidecarPath(), JSON.stringify({ entryPath }));
67838
67877
  }
67839
67878
  const plugins = settings.plugins ?? {};
@@ -67852,7 +67891,7 @@ function installOpenclaw() {
67852
67891
  return { configPath: configPath2, pluginPath, alreadyInstalled: true };
67853
67892
  }
67854
67893
  if (pluginChanged) {
67855
- ensureDirSync(path49.dirname(pluginPath));
67894
+ ensureDirSync(path50.dirname(pluginPath));
67856
67895
  atomicWriteText(pluginPath, OPENCLAW_PLUGIN_SCRIPT);
67857
67896
  }
67858
67897
  if (configChanged) {
@@ -67985,7 +68024,7 @@ import * as os17 from "node:os";
67985
68024
  // src/shell.ts
67986
68025
  init_define_import_meta_env();
67987
68026
  import * as fs43 from "node:fs";
67988
- import * as path50 from "node:path";
68027
+ import * as path51 from "node:path";
67989
68028
  var WSL_LAUNCHER_SEGMENTS = /* @__PURE__ */ new Set(["system32", "syswow64", "windowsapps"]);
67990
68029
  function isExecutable(p) {
67991
68030
  try {
@@ -67998,15 +68037,15 @@ function isWslLauncherDir(dir) {
67998
68037
  return dir.toLowerCase().split(/[\\/]+/).some((seg) => WSL_LAUNCHER_SEGMENTS.has(seg));
67999
68038
  }
68000
68039
  function locateBashOnPath(pathValue, isExe = isExecutable) {
68001
- for (const dir of (pathValue ?? "").split(path50.delimiter)) {
68040
+ for (const dir of (pathValue ?? "").split(path51.delimiter)) {
68002
68041
  if (!dir || isWslLauncherDir(dir)) continue;
68003
- const cand = path50.join(dir, "bash.exe");
68042
+ const cand = path51.join(dir, "bash.exe");
68004
68043
  if (isExe(cand)) return cand;
68005
68044
  }
68006
68045
  return null;
68007
68046
  }
68008
68047
  function knownGitBashPaths() {
68009
- const localPrograms = process.env["LOCALAPPDATA"] ? path50.join(process.env["LOCALAPPDATA"], "Programs") : void 0;
68048
+ const localPrograms = process.env["LOCALAPPDATA"] ? path51.join(process.env["LOCALAPPDATA"], "Programs") : void 0;
68010
68049
  const bases = [
68011
68050
  process.env["ProgramFiles"],
68012
68051
  process.env["ProgramFiles(x86)"],
@@ -68016,8 +68055,8 @@ function knownGitBashPaths() {
68016
68055
  const out2 = [];
68017
68056
  for (const base of bases) {
68018
68057
  if (!base) continue;
68019
- out2.push(path50.join(base, "Git", "bin", "bash.exe"));
68020
- out2.push(path50.join(base, "Git", "usr", "bin", "bash.exe"));
68058
+ out2.push(path51.join(base, "Git", "bin", "bash.exe"));
68059
+ out2.push(path51.join(base, "Git", "usr", "bin", "bash.exe"));
68021
68060
  }
68022
68061
  return out2;
68023
68062
  }
@@ -68420,7 +68459,7 @@ init_define_import_meta_env();
68420
68459
  init_util2();
68421
68460
  import * as fs44 from "node:fs";
68422
68461
  import * as os18 from "node:os";
68423
- import * as path51 from "node:path";
68462
+ import * as path52 from "node:path";
68424
68463
  var TENANT_HOST_RE = /^([a-z0-9-]+?)(-my)?\.sharepoint\.com$/i;
68425
68464
  function parseShareUrl(url2) {
68426
68465
  let u;
@@ -68470,7 +68509,7 @@ function candidateRoots(env, home) {
68470
68509
  try {
68471
68510
  for (const entry of fs44.readdirSync(home, { withFileTypes: true })) {
68472
68511
  if (entry.isDirectory() && /onedrive/i.test(entry.name)) {
68473
- const full = path51.join(home, entry.name);
68512
+ const full = path52.join(home, entry.name);
68474
68513
  if (!roots.includes(full)) roots.push(full);
68475
68514
  }
68476
68515
  }
@@ -68479,13 +68518,13 @@ function candidateRoots(env, home) {
68479
68518
  return roots;
68480
68519
  }
68481
68520
  function tryLibraryPaths(root, libSegments, triedPaths) {
68482
- const rawJoined = path51.join(root, ...libSegments);
68521
+ const rawJoined = path52.join(root, ...libSegments);
68483
68522
  triedPaths.push(rawJoined);
68484
68523
  if (fs44.existsSync(rawJoined)) return rawJoined;
68485
68524
  if (libSegments.length > 0) {
68486
68525
  const aliasedFirst = normalizeLibrarySegment(libSegments[0]);
68487
68526
  if (aliasedFirst !== libSegments[0]) {
68488
- const aliasedJoined = path51.join(root, aliasedFirst, ...libSegments.slice(1));
68527
+ const aliasedJoined = path52.join(root, aliasedFirst, ...libSegments.slice(1));
68489
68528
  triedPaths.push(aliasedJoined);
68490
68529
  if (fs44.existsSync(aliasedJoined)) return aliasedJoined;
68491
68530
  }
@@ -68497,9 +68536,9 @@ function resolveLocalPath(parsed, env = process.env, home = os18.homedir()) {
68497
68536
  const libSegments = parsed.libraryPath.split(/[/\\]+/).filter((s) => s.length > 0 && s !== "." && s !== "..");
68498
68537
  const triedPaths = [];
68499
68538
  function withinRoot(root, candidate) {
68500
- const resolvedRoot = path51.resolve(root) + path51.sep;
68501
- const resolvedCandidate = path51.resolve(candidate);
68502
- return (resolvedCandidate + path51.sep).startsWith(resolvedRoot);
68539
+ const resolvedRoot = path52.resolve(root) + path52.sep;
68540
+ const resolvedCandidate = path52.resolve(candidate);
68541
+ return (resolvedCandidate + path52.sep).startsWith(resolvedRoot);
68503
68542
  }
68504
68543
  function safeTryLibraryPaths(root, segments, tried) {
68505
68544
  const found = tryLibraryPaths(root, segments, tried);
@@ -68513,7 +68552,7 @@ function resolveLocalPath(parsed, env = process.env, home = os18.homedir()) {
68513
68552
  try {
68514
68553
  for (const entry of fs44.readdirSync(root, { withFileTypes: true })) {
68515
68554
  if (!entry.isDirectory() || !entry.name.toLowerCase().includes(parsed.siteName.toLowerCase())) continue;
68516
- const siteRoot = path51.join(root, entry.name);
68555
+ const siteRoot = path52.join(root, entry.name);
68517
68556
  const siteFound = safeTryLibraryPaths(siteRoot, libSegments, triedPaths);
68518
68557
  if (siteFound !== null) return { resolvedPath: siteFound, triedPaths };
68519
68558
  }
@@ -68703,7 +68742,7 @@ init_session();
68703
68742
  init_util2();
68704
68743
  init_ansi();
68705
68744
  import * as fs46 from "node:fs";
68706
- import * as path52 from "node:path";
68745
+ import * as path53 from "node:path";
68707
68746
  function writeRaw(text) {
68708
68747
  const payload = colorStdout() ? text : stripAnsi(text);
68709
68748
  process.stdout.write(ensureNewline(payload));
@@ -68715,7 +68754,7 @@ function formatTopFiles(ranked) {
68715
68754
  if (ranked.length === 0) return "";
68716
68755
  const lines2 = ["Top files this session:"];
68717
68756
  for (const { path: filePath, count } of ranked) {
68718
- const basename22 = path52.basename(filePath);
68757
+ const basename22 = path53.basename(filePath);
68719
68758
  lines2.push(` ${count.toString().padStart(3)}x ${basename22} (${filePath})`);
68720
68759
  }
68721
68760
  return lines2.join("\n");
@@ -68732,12 +68771,12 @@ function renderTopSessionFiles(topN = 5) {
68732
68771
  }
68733
68772
  function renderTopSessionFilesFromDisk(topN = 5, overrideSessionsDir) {
68734
68773
  try {
68735
- const sessionsDir = overrideSessionsDir ?? path52.join(dataDir(), "sessions");
68774
+ const sessionsDir = overrideSessionsDir ?? path53.join(dataDir(), "sessions");
68736
68775
  if (!fs46.existsSync(sessionsDir)) return "";
68737
- const files = fs46.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs46.statSync(path52.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
68776
+ const files = fs46.readdirSync(sessionsDir).filter((f) => f.endsWith(".json")).map((f) => ({ name: f, mtime: fs46.statSync(path53.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).slice(0, 3);
68738
68777
  for (const { name: name2 } of files) {
68739
68778
  try {
68740
- const raw = fs46.readFileSync(path52.join(sessionsDir, name2), "utf-8");
68779
+ const raw = fs46.readFileSync(path53.join(sessionsDir, name2), "utf-8");
68741
68780
  const data = JSON.parse(raw);
68742
68781
  const filesList = data["files"];
68743
68782
  if (!Array.isArray(filesList)) continue;
@@ -68804,14 +68843,14 @@ init_install();
68804
68843
  init_ts_refs();
68805
68844
  init_parser();
68806
68845
  import * as fs47 from "fs";
68807
- import * as path53 from "path";
68846
+ import * as path54 from "path";
68808
68847
  import { execSync, spawnSync as spawnSync7 } from "child_process";
68809
68848
  function checkWorkerRunning(dataDir2) {
68810
68849
  return dataDir2 !== void 0 ? isWorkerRunning(dataDir2) : isWorkerRunning();
68811
68850
  }
68812
68851
  var DB_SIZE_WARN_BYTES = 1024 * 1024 * 1024;
68813
68852
  function checkDbExists(dataDir2) {
68814
- const dbPath = path53.join(dataDir2, "global.db");
68853
+ const dbPath = path54.join(dataDir2, "global.db");
68815
68854
  if (!fs47.existsSync(dbPath)) {
68816
68855
  return {
68817
68856
  name: "Database",
@@ -69123,8 +69162,8 @@ function runDoctor(dataDir2, configPath2, rootDir) {
69123
69162
  results.push(checkStrayClaudeMdBlocks());
69124
69163
  results.push(checkWorkerRunning(actualDataDir) ? { name: "Worker", status: "ok", message: "running" } : { name: "Worker", status: "warn", message: "not running" });
69125
69164
  results.push(checkDbExists(actualDataDir));
69126
- results.push(checkSymbolBodySize(path53.join(actualDataDir, "global.db")));
69127
- results.push(checkSymbolCount(path53.join(actualDataDir, "global.db"), rootDir));
69165
+ results.push(checkSymbolBodySize(path54.join(actualDataDir, "global.db")));
69166
+ results.push(checkSymbolCount(path54.join(actualDataDir, "global.db"), rootDir));
69128
69167
  results.push(checkDirtyQueueHealth(actualDataDir));
69129
69168
  const actualConfigPath = configPath2 || configPath();
69130
69169
  results.push(checkConfigValid(actualConfigPath));
@@ -69162,7 +69201,7 @@ async function runDoctorAndExit(opts) {
69162
69201
  console.log();
69163
69202
  try {
69164
69203
  const dir = skillOutputsDir();
69165
- const pregenPath = path53.join(dir, "pregen.json");
69204
+ const pregenPath = path54.join(dir, "pregen.json");
69166
69205
  if (fs47.existsSync(pregenPath)) {
69167
69206
  const content = JSON.parse(fs47.readFileSync(pregenPath, "utf-8"));
69168
69207
  const pregenNames = new Set(content.names || []);
@@ -69172,7 +69211,7 @@ async function runDoctorAndExit(opts) {
69172
69211
  for (const entry of entries) {
69173
69212
  if (!entry.isFile() || !entry.name.endsWith(".meta")) continue;
69174
69213
  try {
69175
- const meta3 = JSON.parse(fs47.readFileSync(path53.join(dir, entry.name), "utf-8"));
69214
+ const meta3 = JSON.parse(fs47.readFileSync(path54.join(dir, entry.name), "utf-8"));
69176
69215
  if (meta3.skillName && !pregenNames.has(meta3.skillName)) {
69177
69216
  skillsSeen.add(meta3.skillName);
69178
69217
  }
@@ -69635,7 +69674,7 @@ async function getSectionContent(fileId, heading, opts = {}) {
69635
69674
  // src/pack.ts
69636
69675
  init_define_import_meta_env();
69637
69676
  import * as fs48 from "node:fs";
69638
- import * as path55 from "node:path";
69677
+ import * as path56 from "node:path";
69639
69678
 
69640
69679
  // node_modules/minimatch/dist/esm/index.js
69641
69680
  var esm_exports = {};
@@ -70718,11 +70757,11 @@ var qmarksTestNoExtDot = ([$0]) => {
70718
70757
  return (f) => f.length === len && f !== "." && f !== "..";
70719
70758
  };
70720
70759
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
70721
- var path54 = {
70760
+ var path55 = {
70722
70761
  win32: { sep: "\\" },
70723
70762
  posix: { sep: "/" }
70724
70763
  };
70725
- var sep2 = defaultPlatform === "win32" ? path54.win32.sep : path54.posix.sep;
70764
+ var sep2 = defaultPlatform === "win32" ? path55.win32.sep : path55.posix.sep;
70726
70765
  minimatch.sep = sep2;
70727
70766
  var GLOBSTAR = Symbol("globstar **");
70728
70767
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -71508,7 +71547,7 @@ var LANG_MAP = {
71508
71547
  ".exs": "elixir"
71509
71548
  };
71510
71549
  function getLang(filePath) {
71511
- const ext2 = path55.extname(filePath).toLowerCase();
71550
+ const ext2 = path56.extname(filePath).toLowerCase();
71512
71551
  return LANG_MAP[ext2] ?? "";
71513
71552
  }
71514
71553
  function matches(rel, patterns) {
@@ -71518,8 +71557,8 @@ function matches(rel, patterns) {
71518
71557
  return patterns.some((pat) => mm.minimatch(norm, pat) || mm.minimatch(base, pat));
71519
71558
  }
71520
71559
  function isPathWithinRoot(rootReal, resolvedPath) {
71521
- const rel = path55.relative(rootReal, resolvedPath);
71522
- return rel !== "" && rel !== ".." && !rel.startsWith(".." + path55.sep) && !path55.isAbsolute(rel);
71560
+ const rel = path56.relative(rootReal, resolvedPath);
71561
+ return rel !== "" && rel !== ".." && !rel.startsWith(".." + path56.sep) && !path56.isAbsolute(rel);
71523
71562
  }
71524
71563
  function openWithinRoot(rootReal, p) {
71525
71564
  let fd;
@@ -71559,11 +71598,11 @@ function openWithinRoot(rootReal, p) {
71559
71598
  }
71560
71599
  function* resolveOpenCandidates(projectRoot, patterns, rootReal, ignorePatterns, seen, skipped) {
71561
71600
  for (const pattern of patterns) {
71562
- const p = path55.isAbsolute(pattern) ? pattern : path55.join(projectRoot, pattern);
71601
+ const p = path56.isAbsolute(pattern) ? pattern : path56.join(projectRoot, pattern);
71563
71602
  if (seen.has(p)) continue;
71564
71603
  let rel;
71565
71604
  try {
71566
- rel = path55.relative(projectRoot, p).replace(/\\/g, "/");
71605
+ rel = path56.relative(projectRoot, p).replace(/\\/g, "/");
71567
71606
  } catch {
71568
71607
  skipped.push(`${p} (outside project root)`);
71569
71608
  continue;
@@ -71637,7 +71676,7 @@ function stripBlockComments(content, pattern, lineStates) {
71637
71676
  );
71638
71677
  }
71639
71678
  function stripComments4(content, filePath) {
71640
- const ext2 = path55.extname(filePath).toLowerCase();
71679
+ const ext2 = path56.extname(filePath).toLowerCase();
71641
71680
  const lineStates = computeLineStartQuoteStates(content);
71642
71681
  if (ext2 === ".py") {
71643
71682
  return stripLineComments(content, PY_LINE_COMMENT_RE, lineStates);
@@ -71675,7 +71714,7 @@ var SAFE_EXTS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp
71675
71714
  function scanSecrets(files) {
71676
71715
  const hits = [];
71677
71716
  for (const pf of files) {
71678
- if (SAFE_EXTS.has(path55.extname(pf.path).toLowerCase())) {
71717
+ if (SAFE_EXTS.has(path56.extname(pf.path).toLowerCase())) {
71679
71718
  continue;
71680
71719
  }
71681
71720
  for (const [lineno, line] of pf.content.split("\n").entries()) {
@@ -71698,7 +71737,7 @@ function scanSecrets(files) {
71698
71737
  function collectFiles(projectRoot, patterns, opts = {}) {
71699
71738
  const result = { files: [], skipped: [], total_lines: 0, total_tokens: 0 };
71700
71739
  const seen = /* @__PURE__ */ new Set();
71701
- const rootResolved = path55.resolve(projectRoot);
71740
+ const rootResolved = path56.resolve(projectRoot);
71702
71741
  let rootReal;
71703
71742
  try {
71704
71743
  rootReal = fs48.realpathSync(rootResolved);
@@ -71873,7 +71912,7 @@ function formatPack(result, style, opts = {}) {
71873
71912
  function estimateBudget(projectRoot, patterns, opts = {}) {
71874
71913
  const result = { entries: [], skipped: [], total_lines: 0, total_tokens: 0 };
71875
71914
  const seen = /* @__PURE__ */ new Set();
71876
- const rootResolved = path55.resolve(projectRoot);
71915
+ const rootResolved = path56.resolve(projectRoot);
71877
71916
  let rootReal;
71878
71917
  try {
71879
71918
  rootReal = fs48.realpathSync(rootResolved);
@@ -72327,7 +72366,7 @@ init_define_import_meta_env();
72327
72366
  init_constants();
72328
72367
  init_util2();
72329
72368
  import * as fs49 from "node:fs";
72330
- import * as path56 from "node:path";
72369
+ import * as path57 from "node:path";
72331
72370
  var KEY_RE2 = /^[A-Za-z0-9_-]{1,80}$/;
72332
72371
  var DEFAULT_FAILURES_STATE_KEY = "default";
72333
72372
  function validateKey2(key) {
@@ -72339,7 +72378,7 @@ function validateKey2(key) {
72339
72378
  }
72340
72379
  function failuresStatePath(projectHash2, key) {
72341
72380
  validateKey2(key);
72342
- return path56.join(dataDir(), "projects", `${projectHash2}_failures_${key}.json`);
72381
+ return path57.join(dataDir(), "projects", `${projectHash2}_failures_${key}.json`);
72343
72382
  }
72344
72383
  function loadFailureSnapshot(projectHash2, key) {
72345
72384
  const p = failuresStatePath(projectHash2, key);
@@ -72360,7 +72399,7 @@ function loadFailureSnapshot(projectHash2, key) {
72360
72399
  }
72361
72400
  function saveFailureSnapshot(projectHash2, key, snapshot) {
72362
72401
  const p = failuresStatePath(projectHash2, key);
72363
- const dir = path56.dirname(p);
72402
+ const dir = path57.dirname(p);
72364
72403
  ensureDirSync(dir);
72365
72404
  const content = JSON.stringify(snapshot);
72366
72405
  const doSave = () => {
@@ -72383,7 +72422,7 @@ init_stats();
72383
72422
  init_util2();
72384
72423
  import { createRequire as createRequire8 } from "node:module";
72385
72424
  import * as fs50 from "node:fs";
72386
- import * as path57 from "node:path";
72425
+ import * as path58 from "node:path";
72387
72426
  var _require6 = createRequire8(import.meta.url);
72388
72427
  var _ts2 = null;
72389
72428
  var _tsLoadAttempted2 = false;
@@ -72434,7 +72473,7 @@ function listInstalledPackageNames(nodeModulesDir) {
72434
72473
  if (entry.name.startsWith("@")) {
72435
72474
  let scoped;
72436
72475
  try {
72437
- scoped = fs50.readdirSync(path57.join(nodeModulesDir, entry.name), { withFileTypes: true });
72476
+ scoped = fs50.readdirSync(path58.join(nodeModulesDir, entry.name), { withFileTypes: true });
72438
72477
  } catch {
72439
72478
  continue;
72440
72479
  }
@@ -72451,7 +72490,7 @@ var README_NAME_RE = /^readme(\.(md|markdown|txt))?$/i;
72451
72490
  function findReadmeFile(pkgDir) {
72452
72491
  const direct = findReadmeIn(pkgDir);
72453
72492
  if (direct !== null) return direct;
72454
- return findReadmeIn(path57.join(pkgDir, "docs"));
72493
+ return findReadmeIn(path58.join(pkgDir, "docs"));
72455
72494
  }
72456
72495
  function findReadmeIn(dir) {
72457
72496
  let entries;
@@ -72468,7 +72507,7 @@ function findReadmeIn(dir) {
72468
72507
  return 1;
72469
72508
  };
72470
72509
  matches2.sort((a, b) => rank(a.name) - rank(b.name));
72471
- return path57.join(dir, matches2[0].name);
72510
+ return path58.join(dir, matches2[0].name);
72472
72511
  }
72473
72512
  function typesPackageDirName(pkgName) {
72474
72513
  if (pkgName.startsWith("@")) {
@@ -72495,30 +72534,30 @@ function resolveTypesLocation(pkgDir, pkgJson, nodeModulesDir, pkgName) {
72495
72534
  if (declared !== void 0) {
72496
72535
  const candidates = [declared, declared.endsWith(".d.ts") ? declared : `${declared}.d.ts`, declared.replace(/\.[cm]?[jt]s$/, ".d.ts")];
72497
72536
  for (const c of candidates) {
72498
- const p = path57.join(pkgDir, c);
72537
+ const p = path58.join(pkgDir, c);
72499
72538
  if (fileExists2(p)) return { path: p, source: "bundled" };
72500
72539
  }
72501
72540
  }
72502
72541
  const main = typeof pkgJson["main"] === "string" ? pkgJson["main"] : "index.js";
72503
- const mainDts = path57.join(pkgDir, main.replace(/\.[cm]?js$/, ".d.ts"));
72542
+ const mainDts = path58.join(pkgDir, main.replace(/\.[cm]?js$/, ".d.ts"));
72504
72543
  if (fileExists2(mainDts)) return { path: mainDts, source: "bundled" };
72505
- const indexDts = path57.join(pkgDir, "index.d.ts");
72544
+ const indexDts = path58.join(pkgDir, "index.d.ts");
72506
72545
  if (fileExists2(indexDts)) return { path: indexDts, source: "bundled" };
72507
72546
  const typesDirName = typesPackageDirName(pkgName);
72508
- const typesPkgDir = path57.join(nodeModulesDir, "@types", typesDirName);
72509
- const typesPkgJsonRaw = readFileTextOrNull(path57.join(typesPkgDir, "package.json"));
72547
+ const typesPkgDir = path58.join(nodeModulesDir, "@types", typesDirName);
72548
+ const typesPkgJsonRaw = readFileTextOrNull(path58.join(typesPkgDir, "package.json"));
72510
72549
  if (typesPkgJsonRaw !== null) {
72511
72550
  try {
72512
72551
  const typesPkgJson = JSON.parse(typesPkgJsonRaw);
72513
72552
  const entry = (typeof typesPkgJson["types"] === "string" ? typesPkgJson["types"] : void 0) ?? (typeof typesPkgJson["main"] === "string" ? typesPkgJson["main"] : void 0) ?? "index.d.ts";
72514
72553
  const entryCandidates = [entry, entry.endsWith(".d.ts") ? entry : `${entry}.d.ts`, entry.replace(/\.[cm]?[jt]s$/, ".d.ts")];
72515
72554
  for (const c of entryCandidates) {
72516
- const entryPath = path57.join(typesPkgDir, c);
72555
+ const entryPath = path58.join(typesPkgDir, c);
72517
72556
  if (fileExists2(entryPath)) return { path: entryPath, source: "@types" };
72518
72557
  }
72519
72558
  } catch {
72520
72559
  }
72521
- const fallback = path57.join(typesPkgDir, "index.d.ts");
72560
+ const fallback = path58.join(typesPkgDir, "index.d.ts");
72522
72561
  if (fileExists2(fallback)) return { path: fallback, source: "@types" };
72523
72562
  }
72524
72563
  return null;
@@ -72585,9 +72624,9 @@ function recordDepDocsStat(fullSourceBytes, emittedText, packageName) {
72585
72624
  }
72586
72625
  function runDepDocs(opts) {
72587
72626
  const root = resolveProjectRoot({ project: opts.projectRoot ?? process.cwd() });
72588
- const nodeModulesDir = path57.join(root, "node_modules");
72589
- const pkgDir = path57.join(nodeModulesDir, opts.packageName);
72590
- const pkgJsonPath = path57.join(pkgDir, "package.json");
72627
+ const nodeModulesDir = path58.join(root, "node_modules");
72628
+ const pkgDir = path58.join(nodeModulesDir, opts.packageName);
72629
+ const pkgJsonPath = path58.join(pkgDir, "package.json");
72591
72630
  if (!dirExists(pkgDir) || !fileExists2(pkgJsonPath)) {
72592
72631
  const known = listInstalledPackageNames(nodeModulesDir);
72593
72632
  const suggestions = suggestPackageNames(opts.packageName, known);
@@ -73115,7 +73154,7 @@ init_db();
73115
73154
  init_constants();
73116
73155
  init_worker();
73117
73156
  import * as fs51 from "node:fs";
73118
- import * as path58 from "node:path";
73157
+ import * as path59 from "node:path";
73119
73158
  var DERIVED_TABLES = ["chunk_vectors", "chunks", "refs", "symbols", "files"];
73120
73159
  function indexSizeBytes(dbPath) {
73121
73160
  let total = 0;
@@ -73183,7 +73222,7 @@ function mb(bytes) {
73183
73222
  }
73184
73223
  function cmdReclaimIndex(opts) {
73185
73224
  const dbPath = opts.dbPath ?? globalDbPath();
73186
- if (opts.force !== true && isWorkerRunning(path58.dirname(dbPath))) {
73225
+ if (opts.force !== true && isWorkerRunning(path59.dirname(dbPath))) {
73187
73226
  throw new Error(
73188
73227
  "reclaim-index: the worker daemon is running and writing to this index. Stop it first with 'token-goat worker stop', then re-run. Pass --force to proceed anyway (results may be inaccurate if the worker is really live)."
73189
73228
  );
@@ -73218,7 +73257,7 @@ function cmdReclaimIndex(opts) {
73218
73257
  }
73219
73258
  if (result.checkpointBusy) {
73220
73259
  process.stdout.write(
73221
- ` note: a concurrent reader blocked WAL truncation, so some space may still be held in ${path58.basename(dbPath)}-wal
73260
+ ` note: a concurrent reader blocked WAL truncation, so some space may still be held in ${path59.basename(dbPath)}-wal
73222
73261
  `
73223
73262
  );
73224
73263
  }
@@ -73235,7 +73274,7 @@ init_index_prune();
73235
73274
  init_disk_cache();
73236
73275
  import * as fs52 from "node:fs";
73237
73276
  import * as os19 from "node:os";
73238
- import * as path59 from "node:path";
73277
+ import * as path60 from "node:path";
73239
73278
  init_util2();
73240
73279
  init_paths();
73241
73280
  init_ansi();
@@ -73249,7 +73288,7 @@ function emitErr4(text) {
73249
73288
  process.stderr.write(ensureNewline(text));
73250
73289
  }
73251
73290
  function saveConfigSafe(cfg) {
73252
- ensureDirSync(path59.dirname(configPath()));
73291
+ ensureDirSync(path60.dirname(configPath()));
73253
73292
  saveConfig(cfg);
73254
73293
  }
73255
73294
  function levenshtein(a, b, cap = 3) {
@@ -73496,8 +73535,8 @@ function cmdConfig(opts) {
73496
73535
  saveConfigSafe(cfg);
73497
73536
  return coercedValue;
73498
73537
  };
73499
- ensureDirSync(path59.dirname(configPath()));
73500
- const lockPath = path59.join(path59.dirname(configPath()), ".config.lock");
73538
+ ensureDirSync(path60.dirname(configPath()));
73539
+ const lockPath = path60.join(path60.dirname(configPath()), ".config.lock");
73501
73540
  const lockResult = withFileLock(lockPath, applySet, { waitMs: LOCK_WAIT_MS_HARDENED });
73502
73541
  const coerced = lockResult === void 0 ? applySet() : lockResult;
73503
73542
  invalidateConfigCache();
@@ -73633,7 +73672,7 @@ function cmdProject(opts) {
73633
73672
  emitErr4("project exclude requires a path argument");
73634
73673
  throw new Error("missing path");
73635
73674
  }
73636
- const target = path59.resolve(opts.pathArg);
73675
+ const target = path60.resolve(opts.pathArg);
73637
73676
  const cfg = loadPersistedConfig();
73638
73677
  const targetFolded = foldPath(normalizePath(target));
73639
73678
  if (cfg.worker.blocked_roots.some((r) => foldPath(normalizePath(r)) === targetFolded)) {
@@ -73702,7 +73741,7 @@ function recordCompactDocStat(fullSourceBytes, emittedText, detail) {
73702
73741
  recordStat("compact_doc", bytesSaved, Math.round(bytesSaved / 4), void 0, detail);
73703
73742
  }
73704
73743
  function cmdCompactDoc(opts) {
73705
- const resolved = path59.resolve(opts.filePath);
73744
+ const resolved = path60.resolve(opts.filePath);
73706
73745
  if (opts.heading !== void 0) {
73707
73746
  const result = compactDoc(resolved, opts.heading);
73708
73747
  if (result === null) {
@@ -73809,7 +73848,7 @@ async function cmdFetchImage(opts) {
73809
73848
  throw new Error(`fetch failed: ${opts.url}`, { cause: e });
73810
73849
  }
73811
73850
  const buf = fetched.body;
73812
- const outPath = opts.out ?? path59.join(os19.tmpdir(), `tg-fetch-${Date.now()}${extensionForContentType(fetched.contentType)}`);
73851
+ const outPath = opts.out ?? path60.join(os19.tmpdir(), `tg-fetch-${Date.now()}${extensionForContentType(fetched.contentType)}`);
73813
73852
  const originalBytes = buf.length;
73814
73853
  let shrunkBytes;
73815
73854
  let outData;
@@ -73898,7 +73937,7 @@ init_cli_context_stats();
73898
73937
  init_project();
73899
73938
  import * as fs53 from "node:fs";
73900
73939
  import * as os20 from "node:os";
73901
- import * as path60 from "node:path";
73940
+ import * as path61 from "node:path";
73902
73941
  import * as readline2 from "node:readline";
73903
73942
  var FRONTMATTER_KEYS = /* @__PURE__ */ new Set(["description", "tools", "allowed-tools", "allowed_tools"]);
73904
73943
  function parseBudget(name2, value) {
@@ -73957,17 +73996,17 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
73957
73996
  logicalRoot = await fs53.promises.realpath(root);
73958
73997
  } catch (error52) {
73959
73998
  if (error52.code === "ENOENT") return entries;
73960
- diagnostics.push({ path: path60.resolve(root), reason: "unreadable root" });
73999
+ diagnostics.push({ path: path61.resolve(root), reason: "unreadable root" });
73961
74000
  return entries;
73962
74001
  }
73963
74002
  if (rootIsLink && !followLinks) {
73964
- diagnostics.push({ path: path60.resolve(root), reason: "external root link skipped (use --follow-links)" });
74003
+ diagnostics.push({ path: path61.resolve(root), reason: "external root link skipped (use --follow-links)" });
73965
74004
  return entries;
73966
74005
  }
73967
74006
  const canonicalKey = (candidate) => process.platform === "win32" ? candidate.toLocaleLowerCase() : candidate;
73968
74007
  const isContained = (candidate, allowedRoot) => {
73969
- const relative11 = path60.relative(canonicalKey(allowedRoot), canonicalKey(candidate));
73970
- return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path60.sep}`) && !path60.isAbsolute(relative11);
74008
+ const relative11 = path61.relative(canonicalKey(allowedRoot), canonicalKey(candidate));
74009
+ return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path61.sep}`) && !path61.isAbsolute(relative11);
73971
74010
  };
73972
74011
  async function visit(candidate, allowedRoot, topLevel = false) {
73973
74012
  let real;
@@ -73976,13 +74015,13 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
73976
74015
  candidateIsLink = (await fs53.promises.lstat(candidate)).isSymbolicLink();
73977
74016
  real = await fs53.promises.realpath(candidate);
73978
74017
  } catch {
73979
- diagnostics.push({ path: path60.resolve(candidate), reason: "broken or unreadable link" });
74018
+ diagnostics.push({ path: path61.resolve(candidate), reason: "broken or unreadable link" });
73980
74019
  return;
73981
74020
  }
73982
74021
  const withinAllowedRoot = allowedRoot === void 0 ? isContained(real, logicalRoot) : isContained(real, allowedRoot);
73983
74022
  const canFollowExternal = followLinks && topLevel;
73984
74023
  if (!withinAllowedRoot && !canFollowExternal) {
73985
- diagnostics.push({ path: path60.resolve(candidate), reason: candidateIsLink ? "external link skipped (use --follow-links)" : "canonical target outside scan root" });
74024
+ diagnostics.push({ path: path61.resolve(candidate), reason: candidateIsLink ? "external link skipped (use --follow-links)" : "canonical target outside scan root" });
73986
74025
  return;
73987
74026
  }
73988
74027
  const trustedRoot = !withinAllowedRoot && canFollowExternal ? real : allowedRoot ?? real;
@@ -73990,7 +74029,7 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
73990
74029
  try {
73991
74030
  stat2 = await fs53.promises.stat(real);
73992
74031
  } catch {
73993
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable" });
74032
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable" });
73994
74033
  return;
73995
74034
  }
73996
74035
  const canonical = process.platform === "win32" ? real.toLocaleLowerCase() : real;
@@ -74001,14 +74040,14 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
74001
74040
  try {
74002
74041
  children = await fs53.promises.readdir(real, { withFileTypes: true });
74003
74042
  } catch {
74004
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable directory" });
74043
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable directory" });
74005
74044
  return;
74006
74045
  }
74007
74046
  children.sort((a, b) => a.name.localeCompare(b.name));
74008
- for (const child of children) await visit(path60.join(real, child.name), trustedRoot);
74047
+ for (const child of children) await visit(path61.join(real, child.name), trustedRoot);
74009
74048
  return;
74010
74049
  }
74011
- if (!stat2.isFile() || path60.extname(real).toLowerCase() !== ".md") return;
74050
+ if (!stat2.isFile() || path61.extname(real).toLowerCase() !== ".md") return;
74012
74051
  if (seenFiles.has(canonical)) return;
74013
74052
  seenFiles.add(canonical);
74014
74053
  try {
@@ -74018,35 +74057,35 @@ async function scanMetadataRoot(root, kind, diagnostics, visitedDirs = /* @__PUR
74018
74057
  const toolsBytes = Buffer.byteLength(metadata.tools, "utf8");
74019
74058
  entries.push({
74020
74059
  kind,
74021
- path: path60.resolve(real),
74060
+ path: path61.resolve(real),
74022
74061
  description_bytes: descriptionBytes,
74023
74062
  tools_bytes: toolsBytes,
74024
74063
  metadata_bytes: descriptionBytes + toolsBytes,
74025
74064
  estimated_tokens: Math.floor((descriptionBytes + toolsBytes) / 4)
74026
74065
  });
74027
74066
  } catch {
74028
- diagnostics.push({ path: path60.resolve(candidate), reason: "unreadable file" });
74067
+ diagnostics.push({ path: path61.resolve(candidate), reason: "unreadable file" });
74029
74068
  }
74030
74069
  }
74031
74070
  try {
74032
74071
  const children = await fs53.promises.readdir(logicalRoot, { withFileTypes: true });
74033
74072
  children.sort((a, b) => a.name.localeCompare(b.name));
74034
- for (const child of children) await visit(path60.join(logicalRoot, child.name), void 0, true);
74073
+ for (const child of children) await visit(path61.join(logicalRoot, child.name), void 0, true);
74035
74074
  } catch {
74036
- diagnostics.push({ path: path60.resolve(root), reason: "unreadable root" });
74075
+ diagnostics.push({ path: path61.resolve(root), reason: "unreadable root" });
74037
74076
  }
74038
74077
  return entries;
74039
74078
  }
74040
74079
  async function buildBootstrapAudit(opts = {}) {
74041
74080
  const project = resolveProjectRoot(opts.project === void 0 ? {} : { project: opts.project });
74042
- const home = path60.resolve(opts.home ?? os20.homedir());
74081
+ const home = path61.resolve(opts.home ?? os20.homedir());
74043
74082
  const context = buildStats(project, home, opts.project === void 0 ? [] : [opts.project]);
74044
74083
  const diagnostics = [];
74045
74084
  const top = opts.top === void 0 ? 10 : parseBudget("--top", opts.top) ?? 10;
74046
74085
  const visitedDirs = /* @__PURE__ */ new Set();
74047
74086
  const seenFiles = /* @__PURE__ */ new Set();
74048
- const agents = await scanMetadataRoot(path60.join(home, ".claude", "agents"), "agent", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
74049
- const skills = await scanMetadataRoot(path60.join(home, ".claude", "skills"), "skill", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
74087
+ const agents = await scanMetadataRoot(path61.join(home, ".claude", "agents"), "agent", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
74088
+ const skills = await scanMetadataRoot(path61.join(home, ".claude", "skills"), "skill", diagnostics, visitedDirs, seenFiles, opts.followLinks === true);
74050
74089
  const largest = [...agents, ...skills].sort((a, b) => b.metadata_bytes - a.metadata_bytes || a.path.localeCompare(b.path)).slice(0, top);
74051
74090
  const metadataBytes = [...agents, ...skills].reduce((sum, entry) => sum + entry.metadata_bytes, 0);
74052
74091
  const totalTokens = context.total_tokens + Math.floor(metadataBytes / 4);
@@ -74112,7 +74151,7 @@ init_memory_prune();
74112
74151
  init_project();
74113
74152
  init_confirm_apply();
74114
74153
  import * as fs54 from "node:fs";
74115
- import * as path61 from "node:path";
74154
+ import * as path62 from "node:path";
74116
74155
  function removeExactDupLines(text, report) {
74117
74156
  if (report.exactDupLines.length === 0) return text;
74118
74157
  const toRemove = new Set(report.exactDupLines.map(([, dupIdx]) => dupIdx));
@@ -74170,7 +74209,7 @@ function printReport(reports, clusters) {
74170
74209
  } else {
74171
74210
  for (const cluster of clusters) {
74172
74211
  w(
74173
- ` [${cluster.method}, similarity ${cluster.similarity}, ~${cluster.tokens} tok] ${cluster.members.map((m) => path61.basename(m)).join(", ")}
74212
+ ` [${cluster.method}, similarity ${cluster.similarity}, ~${cluster.tokens} tok] ${cluster.members.map((m) => path62.basename(m)).join(", ")}
74174
74213
  `
74175
74214
  );
74176
74215
  }
@@ -74185,7 +74224,7 @@ async function runMemoryCommand(opts = {}) {
74185
74224
  const claudeMds = findClaudeMdFiles(projectRoot);
74186
74225
  const reports = auditClaudeMd(claudeMds);
74187
74226
  const memoryMdPath = findMemoryMd(projectRoot);
74188
- const clusters = memoryMdPath !== null ? await findContentDuplicates(path61.dirname(memoryMdPath)) : [];
74227
+ const clusters = memoryMdPath !== null ? await findContentDuplicates(path62.dirname(memoryMdPath)) : [];
74189
74228
  printReport(reports, clusters);
74190
74229
  if (opts.fix !== true) return;
74191
74230
  const changes = [];
@@ -74233,18 +74272,18 @@ async function runMemoryCommand(opts = {}) {
74233
74272
  init_define_import_meta_env();
74234
74273
  init_project();
74235
74274
  import * as fs56 from "node:fs";
74236
- import * as path63 from "node:path";
74275
+ import * as path64 from "node:path";
74237
74276
 
74238
74277
  // src/waste.ts
74239
74278
  init_define_import_meta_env();
74240
74279
  init_overflow_guard();
74241
74280
  import * as fs55 from "node:fs";
74242
74281
  import * as os21 from "node:os";
74243
- import * as path62 from "node:path";
74282
+ import * as path63 from "node:path";
74244
74283
  function projectTranscriptsDir(projectRoot) {
74245
- const rootStr = path62.resolve(projectRoot);
74284
+ const rootStr = path63.resolve(projectRoot);
74246
74285
  const slug = rootStr.replace(/[^A-Za-z0-9]/g, "-");
74247
- return path62.join(os21.homedir(), ".claude", "projects", slug);
74286
+ return path63.join(os21.homedir(), ".claude", "projects", slug);
74248
74287
  }
74249
74288
  function findLatestTranscript(projectRoot) {
74250
74289
  const dir = projectTranscriptsDir(projectRoot);
@@ -74256,7 +74295,7 @@ function findLatestTranscript(projectRoot) {
74256
74295
  }
74257
74296
  let best = null;
74258
74297
  for (const name2 of entries) {
74259
- const full = path62.join(dir, name2);
74298
+ const full = path63.join(dir, name2);
74260
74299
  let stat2;
74261
74300
  try {
74262
74301
  stat2 = fs55.statSync(full);
@@ -74538,7 +74577,7 @@ function printReport2(report) {
74538
74577
  }
74539
74578
  async function runWasteCommand(opts = {}) {
74540
74579
  const projectRoot = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
74541
- const transcriptPath = opts.transcript !== void 0 ? path63.resolve(opts.transcript) : findLatestTranscript(projectRoot);
74580
+ const transcriptPath = opts.transcript !== void 0 ? path64.resolve(opts.transcript) : findLatestTranscript(projectRoot);
74542
74581
  if (transcriptPath === null) {
74543
74582
  if (opts.json === true) {
74544
74583
  process.stdout.write(`${JSON.stringify({ error: "no session transcript found", project: projectRoot })}
@@ -74571,7 +74610,7 @@ async function runWasteCommand(opts = {}) {
74571
74610
  init_define_import_meta_env();
74572
74611
  init_compact();
74573
74612
  import * as fs57 from "node:fs";
74574
- import * as path64 from "node:path";
74613
+ import * as path65 from "node:path";
74575
74614
  import * as readline3 from "node:readline";
74576
74615
  init_project();
74577
74616
  function resolveSessionTranscript(arg, opts = {}) {
@@ -74580,7 +74619,7 @@ function resolveSessionTranscript(arg, opts = {}) {
74580
74619
  const projectRoot2 = resolveProjectRoot(opts.project !== void 0 ? { project: opts.project } : {});
74581
74620
  const dir = projectTranscriptsDir(projectRoot2);
74582
74621
  const byId = arg.endsWith(".jsonl") ? arg : `${arg}.jsonl`;
74583
- const candidate = path64.join(dir, byId);
74622
+ const candidate = path65.join(dir, byId);
74584
74623
  if (fs57.existsSync(candidate) && fs57.statSync(candidate).isFile()) return candidate;
74585
74624
  return null;
74586
74625
  }
@@ -74741,9 +74780,9 @@ init_define_import_meta_env();
74741
74780
  init_project();
74742
74781
  init_disk_cache();
74743
74782
  import * as fs58 from "node:fs";
74744
- import * as path65 from "node:path";
74783
+ import * as path66 from "node:path";
74745
74784
  function readMcpConfig(projectRoot) {
74746
- const configPath2 = path65.join(projectRoot, ".mcp.json");
74785
+ const configPath2 = path66.join(projectRoot, ".mcp.json");
74747
74786
  try {
74748
74787
  if (!fs58.existsSync(configPath2)) {
74749
74788
  return null;
@@ -75392,14 +75431,14 @@ async function cmdInstall(opts) {
75392
75431
  );
75393
75432
  }
75394
75433
  try {
75395
- const skillDir2 = path68.join(homedir19(), ".claude", "skills");
75434
+ const skillDir2 = path69.join(homedir19(), ".claude", "skills");
75396
75435
  if (fs60.existsSync(skillDir2)) {
75397
75436
  const entries = fs60.readdirSync(skillDir2, { withFileTypes: true });
75398
75437
  const skillNames = [];
75399
75438
  const sessionId = getSessionId();
75400
75439
  for (const entry of entries) {
75401
75440
  if (!entry.isDirectory()) continue;
75402
- const skillFile = path68.join(skillDir2, entry.name, "SKILL.md");
75441
+ const skillFile = path69.join(skillDir2, entry.name, "SKILL.md");
75403
75442
  if (fs60.existsSync(skillFile)) {
75404
75443
  const body = fs60.readFileSync(skillFile, "utf-8");
75405
75444
  const compact = extractCompactFromMarker(body);
@@ -75412,7 +75451,7 @@ async function cmdInstall(opts) {
75412
75451
  if (skillNames.length > 0) {
75413
75452
  const dir = skillOutputsDir();
75414
75453
  await fs60.promises.mkdir(dir, { recursive: true });
75415
- const pregenPath = path68.join(dir, "pregen.json");
75454
+ const pregenPath = path69.join(dir, "pregen.json");
75416
75455
  const pregenData = { ts: Date.now(), names: skillNames };
75417
75456
  await fs60.promises.writeFile(pregenPath, JSON.stringify(pregenData, null, 2));
75418
75457
  out(`Pre-generated ${skillNames.length} skill compacts.`);
@@ -76150,8 +76189,8 @@ async function cmdSkillCompact(name2, opts) {
76150
76189
  }
76151
76190
  throw new CliError(`failed to read skill file '${opts.path}': ${extractErrorMessage(e)}`);
76152
76191
  }
76153
- cacheName = name2 ?? path68.basename(path68.dirname(path68.resolve(opts.path)));
76154
- sourcePath = path68.resolve(opts.path);
76192
+ cacheName = name2 ?? path69.basename(path69.dirname(path69.resolve(opts.path)));
76193
+ sourcePath = path69.resolve(opts.path);
76155
76194
  } else {
76156
76195
  if (name2 === void 0 || !name2.trim()) {
76157
76196
  throw new CliError("skill-compact requires a <name> or --path <file>");
@@ -76292,8 +76331,8 @@ async function cmdSkillDiff(name2) {
76292
76331
  }
76293
76332
  const newer = versions[0];
76294
76333
  const older = versions[1];
76295
- const newerBody = await fs60.promises.readFile(path68.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
76296
- const olderBody = await fs60.promises.readFile(path68.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
76334
+ const newerBody = await fs60.promises.readFile(path69.resolve(dir, `${newer.outputId}.txt`), "utf-8").catch(() => null);
76335
+ const olderBody = await fs60.promises.readFile(path69.resolve(dir, `${older.outputId}.txt`), "utf-8").catch(() => null);
76297
76336
  if (newerBody === null || olderBody === null) {
76298
76337
  out(`a cached version of '${name2}' was evicted while diffing -- try again`);
76299
76338
  return;
@@ -76340,7 +76379,7 @@ function atomicWriteBuffer(dest, data) {
76340
76379
  if (e.code !== "ENOENT") throw e;
76341
76380
  }
76342
76381
  const rnd = Math.random().toString(36).slice(2, 8);
76343
- const tmp = path68.join(path68.dirname(path68.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
76382
+ const tmp = path69.join(path69.dirname(path69.resolve(dest)), `.tmp.${process.pid}.${rnd}`);
76344
76383
  try {
76345
76384
  fs60.writeFileSync(tmp, data, { mode: 384 });
76346
76385
  try {
@@ -76378,9 +76417,9 @@ function mapFsError(e, src, dest, srcLabel = "source") {
76378
76417
  const fe = e;
76379
76418
  if (fe.code === "ENOENT") {
76380
76419
  const errPath = fe.path ?? "";
76381
- const isSource = src !== void 0 && path68.resolve(errPath) === path68.resolve(src);
76420
+ const isSource = src !== void 0 && path69.resolve(errPath) === path69.resolve(src);
76382
76421
  if (isSource) throw new CliError(`${srcLabel} file not found: ${src}`);
76383
- const destDir = dest ? path68.dirname(path68.resolve(dest)) : path68.dirname(path68.resolve(errPath || "."));
76422
+ const destDir = dest ? path69.dirname(path69.resolve(dest)) : path69.dirname(path69.resolve(errPath || "."));
76384
76423
  throw new CliError(`destination directory does not exist: ${destDir}`);
76385
76424
  }
76386
76425
  if (fe.code === "ENOTDIR") {
@@ -76391,7 +76430,7 @@ function mapFsError(e, src, dest, srcLabel = "source") {
76391
76430
  }
76392
76431
  if (fe.code === "EISDIR") {
76393
76432
  const errPath = fe.path ?? "";
76394
- const isSource = src !== void 0 && (errPath === "" || path68.resolve(errPath) === path68.resolve(src));
76433
+ const isSource = src !== void 0 && (errPath === "" || path69.resolve(errPath) === path69.resolve(src));
76395
76434
  if (isSource) throw new CliError(`source is a directory, not a file: ${src}`);
76396
76435
  throw new CliError(`destination is a directory, not a file: ${dest ?? (errPath || "(unknown)")}`);
76397
76436
  }
@@ -76460,7 +76499,7 @@ function validateWritablePath(dest, label) {
76460
76499
  throw new CliError(`${label} path contains a null byte`);
76461
76500
  }
76462
76501
  if (isWindows()) {
76463
- const base = path68.basename(dest);
76502
+ const base = path69.basename(dest);
76464
76503
  const stem = base.replace(/\.[^.]*$/, "").toUpperCase();
76465
76504
  if (WIN_RESERVED.has(stem)) {
76466
76505
  throw new CliError(`${label} '${base}' is a reserved Windows device name`);
@@ -76964,17 +77003,17 @@ function expandGlobs(root, patterns, globFnOverride) {
76964
77003
  if (globFn !== void 0 && (p.includes("*") || p.includes("?") || p.includes("{"))) {
76965
77004
  try {
76966
77005
  const hits = globFn(p, { cwd: root });
76967
- for (const h of hits) out2.push(path68.isAbsolute(h) ? h : path68.join(root, h));
77006
+ for (const h of hits) out2.push(path69.isAbsolute(h) ? h : path69.join(root, h));
76968
77007
  continue;
76969
77008
  } catch {
76970
77009
  }
76971
77010
  }
76972
- out2.push(path68.isAbsolute(p) ? p : path68.join(root, p));
77011
+ out2.push(path69.isAbsolute(p) ? p : path69.join(root, p));
76973
77012
  }
76974
77013
  return out2;
76975
77014
  }
76976
77015
  function readIgnoreFile(root) {
76977
- const ignorePath = path68.join(root, ".tokengoatignore");
77016
+ const ignorePath = path69.join(root, ".tokengoatignore");
76978
77017
  let raw;
76979
77018
  try {
76980
77019
  raw = fs60.readFileSync(ignorePath, "utf8");
@@ -77043,7 +77082,7 @@ function cmdTokens(patterns, opts) {
77043
77082
  if (opts.tree === true) {
77044
77083
  const dirs = /* @__PURE__ */ new Map();
77045
77084
  for (const e of entries) {
77046
- const dir = path68.dirname(e.rel_path);
77085
+ const dir = path69.dirname(e.rel_path);
77047
77086
  if (!dirs.has(dir)) dirs.set(dir, []);
77048
77087
  dirs.get(dir).push(e);
77049
77088
  }
@@ -77053,7 +77092,7 @@ function cmdTokens(patterns, opts) {
77053
77092
  const pct = result.total_tokens > 0 ? Math.round(dirTokens / result.total_tokens * 100) : 0;
77054
77093
  lines3.push(`${dir}/ (${dirTokens} tokens, ${pct}%)`);
77055
77094
  for (const e of dirEntries) {
77056
- lines3.push(` ${path68.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
77095
+ lines3.push(` ${path69.basename(e.rel_path).padEnd(30)} ${String(e.tokens).padStart(8)} tokens`);
77057
77096
  }
77058
77097
  }
77059
77098
  out(lines3.join("\n"));
@@ -77336,13 +77375,14 @@ function buildProgram() {
77336
77375
  })
77337
77376
  )
77338
77377
  );
77339
- program2.command("impact <symbol>").description("transitive set of callers impacted by a change (with hop depth; accepts file::symbol to disambiguate which same-named definition is meant)").option("--top <n>", "limit output to top N results").option("-j, --json", "output as JSON").option("--exclude-tests", "hide callers whose call site lives in a test file (opt-in; default output is unchanged)").action(
77378
+ program2.command("impact <symbol>").description("transitive set of callers impacted by a change (with hop depth; accepts file::symbol to disambiguate which same-named definition is meant)").option("--top <n>", "limit output to top N results").option("-j, --json", "output as JSON").option("--exclude-tests", "hide callers whose call site lives in a test file (opt-in; default output is unchanged)").option("--grep <pattern>", "only show impacted symbols whose name matches this regex (literal substring if it is not valid regex)").action(
77340
77379
  (symbol3, opts) => runExit(
77341
77380
  () => runImpact({
77342
77381
  symbol: symbol3,
77343
77382
  ...opts.top !== void 0 ? { top: requireNonNegativeInt("--top", opts.top) } : {},
77344
77383
  ...opts.json === true ? { json: true } : {},
77345
- ...opts.excludeTests === true ? { excludeTests: true } : {}
77384
+ ...opts.excludeTests === true ? { excludeTests: true } : {},
77385
+ ...opts.grep !== void 0 ? { grep: opts.grep } : {}
77346
77386
  })
77347
77387
  )
77348
77388
  );
@@ -82179,8 +82219,8 @@ function trimCharacterEnd(str, char) {
82179
82219
  function unicodeEscape(str) {
82180
82220
  return str.replace(/[\s\S]/g, (c) => "\\u" + c.charCodeAt().toString(16).padStart(4, "0"));
82181
82221
  }
82182
- function get(obj, path69) {
82183
- for (const key of path69) {
82222
+ function get(obj, path70) {
82223
+ for (const key of path70) {
82184
82224
  if (!obj) {
82185
82225
  return void 0;
82186
82226
  }
@@ -83381,8 +83421,8 @@ function withBrackets(str, brackets) {
83381
83421
  const rbr = typeof brackets[1] === "string" ? brackets[1] : "]";
83382
83422
  return lbr + str + rbr;
83383
83423
  }
83384
- function pathRewrite(path69, rewriter, baseUrl, metadata, elem) {
83385
- const modifiedPath = typeof rewriter === "function" ? rewriter(path69, metadata, elem) : path69;
83424
+ function pathRewrite(path70, rewriter, baseUrl, metadata, elem) {
83425
+ const modifiedPath = typeof rewriter === "function" ? rewriter(path70, metadata, elem) : path70;
83386
83426
  return modifiedPath[0] === "/" && baseUrl ? trimCharacterEnd(baseUrl, "/") + modifiedPath : modifiedPath;
83387
83427
  }
83388
83428
  function formatImage(elem, walk, builder, formatOptions) {
@@ -83706,9 +83746,9 @@ function handleDeprecatedOptions(options) {
83706
83746
  options.selectors.push(...tagDefinitions);
83707
83747
  options.selectors = mergeDuplicatesPreferLast(options.selectors, (s) => s.selector);
83708
83748
  }
83709
- function set2(obj, path69, value) {
83710
- const valueKey = path69.pop();
83711
- for (const key of path69) {
83749
+ function set2(obj, path70, value) {
83750
+ const valueKey = path70.pop();
83751
+ for (const key of path70) {
83712
83752
  let nested = obj[key];
83713
83753
  if (!nested) {
83714
83754
  nested = {};
@@ -84757,8 +84797,8 @@ function detectUnbalancedShellSyntax(cmd) {
84757
84797
  }
84758
84798
  j = delimEnd;
84759
84799
  }
84760
- const delimiter2 = cmd.slice(delimStart, j).replace(/["']/g, "");
84761
- if (delimiter2) {
84800
+ const delimiter3 = cmd.slice(delimStart, j).replace(/["']/g, "");
84801
+ if (delimiter3) {
84762
84802
  let scanPos = j;
84763
84803
  let terminatorEnd = -1;
84764
84804
  while (scanPos <= cmd.length) {
@@ -84768,7 +84808,7 @@ function detectUnbalancedShellSyntax(cmd) {
84768
84808
  if (line.endsWith("\r")) {
84769
84809
  line = line.slice(0, -1);
84770
84810
  }
84771
- const isMatch = hasIndentModifier ? line.trim() === delimiter2 : line === delimiter2;
84811
+ const isMatch = hasIndentModifier ? line.trim() === delimiter3 : line === delimiter3;
84772
84812
  if (isMatch) {
84773
84813
  terminatorEnd = nl3 === -1 ? cmd.length : nl3 + 1;
84774
84814
  break;
@@ -84777,7 +84817,7 @@ function detectUnbalancedShellSyntax(cmd) {
84777
84817
  scanPos = nl3 + 1;
84778
84818
  }
84779
84819
  if (terminatorEnd === -1) {
84780
- return `an unterminated heredoc (${delimiter2} never appears on its own line)`;
84820
+ return `an unterminated heredoc (${delimiter3} never appears on its own line)`;
84781
84821
  }
84782
84822
  i = terminatorEnd;
84783
84823
  continue;