token-goat 2.6.33 → 2.6.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/README.md +4 -0
  2. package/SECURITY.md +11 -10
  3. package/dist/{token-goat-chunk-FN6WLFIX.mjs → token-goat-chunk-D5IZEGN2.mjs} +817 -53
  4. package/dist/{token-goat-hook-chunk-HXHFLKEL.mjs → token-goat-chunk-DQIT5JIF.mjs} +7 -2
  5. package/dist/{token-goat-chunk-72R7M5H7.mjs → token-goat-chunk-DRAIYVUI.mjs} +16 -14
  6. package/dist/{token-goat-chunk-RPOXYJWK.mjs → token-goat-chunk-HW4VUKJ5.mjs} +77 -26
  7. package/dist/{token-goat-chunk-TDYTBCT4.mjs → token-goat-chunk-I2KCEGIP.mjs} +704 -138
  8. package/dist/{token-goat-chunk-WFRR2DBG.mjs → token-goat-chunk-K7W3P2TJ.mjs} +583 -343
  9. package/dist/{token-goat-chunk-OHQ7RBLL.mjs → token-goat-chunk-SIHYQCTM.mjs} +2 -2
  10. package/dist/{token-goat-chunk-77CX3MCN.mjs → token-goat-chunk-UIZVX3HN.mjs} +2 -2
  11. package/dist/{token-goat-chunk-L6FVTDPD.mjs → token-goat-chunk-Y2NH6DGZ.mjs} +564 -31
  12. package/dist/{token-goat-chunk-HPWPUBAK.mjs → token-goat-chunk-YF67EWRH.mjs} +5 -5
  13. package/dist/{token-goat-hook-chunk-E6AIPKNF.mjs → token-goat-hook-chunk-2O7P4Z6Q.mjs} +579 -339
  14. package/dist/{token-goat-hook-chunk-WBBHV6TZ.mjs → token-goat-hook-chunk-3AAH72SO.mjs} +77 -26
  15. package/dist/{token-goat-hook-chunk-QD2DX2U7.mjs → token-goat-hook-chunk-4POU6OHK.mjs} +564 -31
  16. package/dist/{token-goat-hook-chunk-ZT47M3IA.mjs → token-goat-hook-chunk-CRBMPT74.mjs} +2 -2
  17. package/dist/{token-goat-hook-chunk-26DLRODR.mjs → token-goat-hook-chunk-D6UJEFHX.mjs} +2 -2
  18. package/dist/{token-goat-hook-chunk-XBOWDNJB.mjs → token-goat-hook-chunk-J4HKWUWZ.mjs} +5 -5
  19. package/dist/{token-goat-chunk-RQQ4SY2P.mjs → token-goat-hook-chunk-NIPXIAPA.mjs} +7 -2
  20. package/dist/{token-goat-hook-chunk-VDXQXYJK.mjs → token-goat-hook-chunk-NXVT4F3S.mjs} +817 -53
  21. package/dist/{token-goat-hook-chunk-EKGDLI4D.mjs → token-goat-hook-chunk-VU6VGZBM.mjs} +16 -14
  22. package/dist/{token-goat-hook-chunk-UWV4MTYI.mjs → token-goat-hook-chunk-XM4W3WCO.mjs} +704 -138
  23. package/dist/token-goat-hook.mjs +5 -5
  24. package/dist/token-goat.core.mjs +5 -5
  25. package/package.json +11 -10
@@ -8,7 +8,7 @@ import {
8
8
  import { createRequire } from "node:module";
9
9
  function resolveVersion() {
10
10
  if (true) {
11
- return "2.6.33";
11
+ return "2.6.35";
12
12
  }
13
13
  const require2 = createRequire(import.meta.url);
14
14
  const pkg = require2("../package.json");
@@ -288,6 +288,18 @@ function safeJoin(base, ...parts) {
288
288
  }
289
289
  return path2.join(base, ...parts);
290
290
  }
291
+ function displaySafeText(text) {
292
+ return text.replace(new RegExp("[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]|\\p{Cf}", "gu"), (ch) => {
293
+ if (ch === "\n") return "\\n";
294
+ if (ch === "\r") return "\\r";
295
+ if (ch === " ") return "\\t";
296
+ const code = ch.codePointAt(0) ?? 0;
297
+ return code <= 255 ? "\\x" + code.toString(16).padStart(2, "0") : "\\u" + code.toString(16).padStart(4, "0");
298
+ });
299
+ }
300
+ function displaySafePath(p) {
301
+ return displaySafeText(p);
302
+ }
291
303
 
292
304
  // src/util.ts
293
305
  import { spawn, spawnSync } from "node:child_process";
@@ -725,6 +737,11 @@ function countNoun(count, singular, plural = `${singular}s`) {
725
737
  function excludeTestsHiddenNote(count) {
726
738
  return `${count} in test ${count === 1 ? "file" : "files"} hidden by --exclude-tests`;
727
739
  }
740
+ function countContentLines(content) {
741
+ if (content === "") return 0;
742
+ const n = content.split("\n").length;
743
+ return content.endsWith("\n") ? n - 1 : n;
744
+ }
728
745
  function escapeRegExp(s) {
729
746
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
730
747
  }
@@ -901,6 +918,72 @@ function packageNameDistance(a, b, cap = 3) {
901
918
  function suggestPackageNames(query, names) {
902
919
  return [...new Set(names)].map((n) => ({ n, d: packageNameDistance(query.toLowerCase(), n.toLowerCase()) })).filter((x) => x.d <= 3).sort((a, b) => a.d - b.d).slice(0, 5).map((x) => x.n);
903
920
  }
921
+ function detectSourceEncoding(buf) {
922
+ if (buf.length >= 4) {
923
+ if (buf[0] === 255 && buf[1] === 254 && buf[2] === 0 && buf[3] === 0) return "utf32le";
924
+ if (buf[0] === 0 && buf[1] === 0 && buf[2] === 254 && buf[3] === 255) return "utf32be";
925
+ }
926
+ if (buf.length >= 2) {
927
+ if (buf[0] === 255 && buf[1] === 254) return "utf16le";
928
+ if (buf[0] === 254 && buf[1] === 255) return "utf16be";
929
+ }
930
+ if (buf.length >= 3 && buf[0] === 239 && buf[1] === 187 && buf[2] === 191) return "utf8-bom";
931
+ return "utf8";
932
+ }
933
+ function decodeSource(buf) {
934
+ switch (detectSourceEncoding(buf)) {
935
+ case "utf32le":
936
+ return decodeUtf32(buf.subarray(4), true);
937
+ case "utf32be":
938
+ return decodeUtf32(buf.subarray(4), false);
939
+ case "utf16le":
940
+ return buf.subarray(2).toString("utf16le");
941
+ case "utf16be":
942
+ return swap16(buf.subarray(2)).toString("utf16le");
943
+ case "utf8-bom":
944
+ return buf.subarray(3).toString("utf8");
945
+ default:
946
+ return buf.toString("utf8");
947
+ }
948
+ }
949
+ function encodeSource(text, encoding) {
950
+ switch (encoding) {
951
+ case "utf32le":
952
+ return Buffer.concat([Buffer.from([255, 254, 0, 0]), encodeUtf32(text, true)]);
953
+ case "utf32be":
954
+ return Buffer.concat([Buffer.from([0, 0, 254, 255]), encodeUtf32(text, false)]);
955
+ case "utf16le":
956
+ return Buffer.concat([Buffer.from([255, 254]), Buffer.from(text, "utf16le")]);
957
+ case "utf16be":
958
+ return Buffer.concat([Buffer.from([254, 255]), swap16(Buffer.from(text, "utf16le"))]);
959
+ case "utf8-bom":
960
+ return Buffer.concat([Buffer.from([239, 187, 191]), Buffer.from(text, "utf8")]);
961
+ default:
962
+ return Buffer.from(text, "utf8");
963
+ }
964
+ }
965
+ function swap16(buf) {
966
+ const out = Buffer.from(buf);
967
+ return out.subarray(0, out.length - out.length % 2).swap16();
968
+ }
969
+ function decodeUtf32(buf, littleEndian) {
970
+ const points = [];
971
+ for (let i = 0; i + 4 <= buf.length; i += 4) {
972
+ const cp = littleEndian ? buf.readUInt32LE(i) : buf.readUInt32BE(i);
973
+ points.push(cp > 1114111 || cp >= 55296 && cp <= 57343 ? 65533 : cp);
974
+ }
975
+ return String.fromCodePoint(...points);
976
+ }
977
+ function encodeUtf32(text, littleEndian) {
978
+ const points = [...text];
979
+ const out = Buffer.alloc(points.length * 4);
980
+ points.forEach((ch, i) => {
981
+ const cp = ch.codePointAt(0) ?? 65533;
982
+ if (littleEndian) out.writeUInt32LE(cp, i * 4);
983
+ else out.writeUInt32BE(cp, i * 4);
984
+ });
985
+ return out;
986
+ }
904
987
 
905
988
  // src/fingerprint.ts
906
989
  import { createHash } from "node:crypto";
@@ -922,6 +1005,13 @@ function fingerprintFile(filePath) {
922
1005
  }
923
1006
  return fingerprintContent(data);
924
1007
  }
1008
+ function fileIsAbsent(filePath) {
1009
+ try {
1010
+ return fs3.statSync(filePath, { throwIfNoEntry: false }) === void 0;
1011
+ } catch {
1012
+ return false;
1013
+ }
1014
+ }
925
1015
 
926
1016
  // src/project.ts
927
1017
  import * as fs4 from "node:fs";
@@ -1093,6 +1183,9 @@ function getDisplayRoot(explicitRoot) {
1093
1183
  _displayRootCache = { cwd, root };
1094
1184
  return root;
1095
1185
  }
1186
+ registerReset(() => {
1187
+ _displayRootCache = null;
1188
+ });
1096
1189
  function isUnderSystemTemp(filePath) {
1097
1190
  let sysTemp;
1098
1191
  try {
@@ -1272,57 +1365,111 @@ ${codeblock}`, options);
1272
1365
  }
1273
1366
  };
1274
1367
 
1368
+ // node_modules/smol-toml/dist/util.js
1369
+ function indexOfNewline(str, start = 0) {
1370
+ let idx = str.indexOf("\n", start);
1371
+ if (str.charCodeAt(idx - 1) === 13)
1372
+ idx--;
1373
+ return idx;
1374
+ }
1375
+ function skipComment(ctx) {
1376
+ for (; ctx.p < ctx.s.length; ctx.p++) {
1377
+ let c = ctx.s.charCodeAt(ctx.p);
1378
+ if (c === 10)
1379
+ break;
1380
+ if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) {
1381
+ ctx.p++;
1382
+ break;
1383
+ }
1384
+ if (c < 32 && c !== 9 || c === 127) {
1385
+ throw new TomlError("control characters are not allowed in comments", {
1386
+ toml: ctx.s,
1387
+ ptr: ctx.p
1388
+ });
1389
+ }
1390
+ }
1391
+ }
1392
+ function skipVoid(ctx, banNewLines, banComments) {
1393
+ let c;
1394
+ while (1) {
1395
+ while ((c = ctx.s.charCodeAt(ctx.p)) === 32 || c === 9 || !banNewLines && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10))
1396
+ ctx.p++;
1397
+ if (banComments || c !== 35)
1398
+ break;
1399
+ skipComment(ctx);
1400
+ }
1401
+ }
1402
+ function skipUntil(ctx, sep, end) {
1403
+ let ptr = ctx.p;
1404
+ if (!end) {
1405
+ ptr = indexOfNewline(ctx.s, ptr);
1406
+ ctx.p = ptr < 0 ? ctx.s.length : ptr;
1407
+ return;
1408
+ }
1409
+ for (; ctx.p < ctx.s.length; ctx.p++) {
1410
+ let c = ctx.s.charCodeAt(ctx.p);
1411
+ if (c === 35) {
1412
+ skipComment(ctx);
1413
+ } else if (c === end || c === sep) {
1414
+ return;
1415
+ }
1416
+ }
1417
+ throw new TomlError("cannot find end of structure", {
1418
+ toml: ctx.s,
1419
+ ptr
1420
+ });
1421
+ }
1422
+
1275
1423
  // node_modules/smol-toml/dist/primitive.js
1276
1424
  var INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
1277
1425
  var FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
1278
1426
  var LEADING_ZERO = /^[+-]?0[0-9_]/;
1279
- function parseString(str, ptr) {
1280
- let c = str[ptr++];
1427
+ function parseString(ctx) {
1428
+ let start = ctx.p;
1429
+ let c = ctx.s.charCodeAt(ctx.p++);
1281
1430
  let first = c;
1282
- let isLiteral = c === "'";
1283
- let isMultiline = c === str[ptr] && c === str[ptr + 1];
1431
+ let isLiteral = c === 39;
1432
+ let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);
1284
1433
  if (isMultiline) {
1285
- if (str[ptr += 2] === "\n")
1286
- ptr++;
1287
- else if (str[ptr] === "\r" && str[ptr + 1] === "\n")
1288
- ptr += 2;
1434
+ if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 10)
1435
+ ctx.p++;
1436
+ else if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)
1437
+ ctx.p += 2;
1289
1438
  }
1290
1439
  let parsed = "";
1291
- let sliceStart = ptr;
1440
+ let sliceStart = ctx.p;
1292
1441
  let state = 0;
1293
- for (let i = ptr; i < str.length; i++) {
1294
- c = str[i];
1295
- if (isMultiline && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
1442
+ for (; ctx.p < ctx.s.length; ctx.p++) {
1443
+ c = ctx.s.charCodeAt(ctx.p);
1444
+ if (isMultiline && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)) {
1296
1445
  state = state && 3;
1297
- } else if (c < " " && c !== " " || c === "\x7F") {
1446
+ } else if (c < 32 && c !== 9 || c === 127) {
1298
1447
  throw new TomlError("control characters are not allowed in strings", {
1299
- toml: str,
1300
- ptr: i
1448
+ toml: ctx.s,
1449
+ ptr: ctx.p
1301
1450
  });
1302
- } else if ((!state || state === 3) && c === first && (!isMultiline || str[i + 1] === first && str[i + 2] === first)) {
1451
+ } else if ((!state || state === 3) && c === first && (!isMultiline || ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first)) {
1303
1452
  if (isMultiline) {
1304
- if (str[i + 3] === first)
1305
- i++;
1306
- if (str[i + 3] === first)
1307
- i++;
1453
+ if (ctx.s.charCodeAt(ctx.p + 3) === first)
1454
+ ctx.p++;
1455
+ if (ctx.s.charCodeAt(ctx.p + 3) === first)
1456
+ ctx.p++;
1308
1457
  }
1309
- return [
1310
- // If we're in a newline escape still, then there's nothing to add.
1311
- // Also try to avoid concat if there's nothing to add to parsed, or nothing has been added to parsed.
1312
- state ? parsed : parsed + str.slice(sliceStart, i),
1313
- i + (isMultiline ? 3 : 1)
1314
- ];
1458
+ if (!state)
1459
+ parsed += ctx.s.slice(sliceStart, ctx.p);
1460
+ ctx.p += isMultiline ? 3 : 1;
1461
+ return parsed;
1315
1462
  } else if (!state) {
1316
- if (!isLiteral && c === "\\") {
1317
- parsed += str.slice(sliceStart, sliceStart = i);
1463
+ if (!isLiteral && c === 92) {
1464
+ parsed += ctx.s.slice(sliceStart, sliceStart = ctx.p);
1318
1465
  state = 1;
1319
1466
  }
1320
1467
  } else if (state === 1) {
1321
- if (c === "x" || c === "u" || c === "U") {
1468
+ if (c === 120 || c === 117 || c === 85) {
1322
1469
  let value = 0;
1323
- let len = c === "x" ? 2 : c === "u" ? 4 : 8;
1324
- for (let j = 0; j < len; j++, i++) {
1325
- let hex = str.charCodeAt(i + 1);
1470
+ let len = c === 120 ? 2 : c === 117 ? 4 : 8;
1471
+ for (let j = 0; j < len; j++, ctx.p++) {
1472
+ let hex = ctx.s.charCodeAt(ctx.p + 1);
1326
1473
  let digit = (
1327
1474
  /* 0-9 */
1328
1475
  hex >= 48 && hex <= 57 ? hex - 48 : (
@@ -1334,57 +1481,68 @@ function parseString(str, ptr) {
1334
1481
  )
1335
1482
  );
1336
1483
  if (digit < 0)
1337
- throw new TomlError("invalid non-hex character in unicode escape", { toml: str, ptr: i + 1 });
1484
+ throw new TomlError("invalid non-hex character in unicode escape", { toml: ctx.s, ptr: ctx.p + 1 });
1338
1485
  value = value << 4 | digit;
1339
1486
  }
1340
1487
  if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) {
1341
- throw new TomlError("invalid unicode escape", { toml: str, ptr: i });
1488
+ throw new TomlError("invalid unicode escape", { toml: ctx.s, ptr: ctx.p });
1342
1489
  }
1343
1490
  parsed += String.fromCodePoint(value);
1344
- sliceStart = i + 1;
1491
+ sliceStart = ctx.p + 1;
1345
1492
  state = 0;
1346
- } else if (c === " " || c === " ") {
1493
+ } else if (c === 32 || c === 9) {
1347
1494
  state = 2;
1348
1495
  } else {
1349
- if (c === "b")
1496
+ if (c === 98)
1350
1497
  parsed += "\b";
1351
- else if (c === "t")
1498
+ else if (c === 116)
1352
1499
  parsed += " ";
1353
- else if (c === "n")
1500
+ else if (c === 110)
1354
1501
  parsed += "\n";
1355
- else if (c === "f")
1502
+ else if (c === 102)
1356
1503
  parsed += "\f";
1357
- else if (c === "r")
1504
+ else if (c === 114)
1358
1505
  parsed += "\r";
1359
- else if (c === "e")
1506
+ else if (c === 101)
1360
1507
  parsed += "\x1B";
1361
- else if (c === '"')
1508
+ else if (c === 34)
1362
1509
  parsed += '"';
1363
- else if (c === "\\")
1510
+ else if (c === 92)
1364
1511
  parsed += "\\";
1365
1512
  else
1366
- throw new TomlError("unrecognized escape sequence", { toml: str, ptr: i });
1367
- sliceStart = i + 1;
1513
+ throw new TomlError("unrecognized escape sequence", { toml: ctx.s, ptr: ctx.p });
1514
+ sliceStart = ctx.p + 1;
1368
1515
  state = 0;
1369
1516
  }
1370
- } else if (c !== " " && c !== " ") {
1517
+ } else if (c !== 32 && c !== 9) {
1371
1518
  if (state === 2) {
1372
1519
  throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
1373
- toml: str,
1520
+ toml: ctx.s,
1374
1521
  ptr: sliceStart
1375
1522
  });
1376
1523
  }
1377
- state = !isLiteral && c === "\\" ? 1 : 0;
1378
- sliceStart = i;
1524
+ state = !isLiteral && c === 92 ? 1 : 0;
1525
+ sliceStart = ctx.p;
1379
1526
  }
1380
1527
  }
1381
- throw new TomlError("unfinished string", { toml: str, ptr });
1528
+ throw new TomlError("unfinished string", { toml: ctx.s, ptr: start });
1382
1529
  }
1383
- function parseValue(value, toml, ptr, integersAsBigInt) {
1384
- if (value === "true")
1385
- return true;
1386
- if (value === "false")
1387
- return false;
1530
+ function sliceAndTrimEndOf(ctx, start, end) {
1531
+ let value = ctx.s.slice(start, end);
1532
+ let commentIdx = value.indexOf("#");
1533
+ if (commentIdx > 0) {
1534
+ skipComment({ s: value, p: commentIdx, d: 0 });
1535
+ value = value.slice(0, commentIdx);
1536
+ }
1537
+ return value.trimEnd();
1538
+ }
1539
+ function parseValue(ctx, integersAsBigInt, end) {
1540
+ let ptr = ctx.p;
1541
+ let err = { toml: ctx.s, ptr };
1542
+ skipUntil(ctx, 44, end);
1543
+ let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);
1544
+ if (!value)
1545
+ throw new TomlError("incomplete declaration: value expected", err);
1388
1546
  if (value === "-inf")
1389
1547
  return -Infinity;
1390
1548
  if (value === "inf" || value === "+inf")
@@ -1396,25 +1554,16 @@ function parseValue(value, toml, ptr, integersAsBigInt) {
1396
1554
  let isInt = INT_REGEX.test(value);
1397
1555
  if (isInt || FLOAT_REGEX.test(value)) {
1398
1556
  if (LEADING_ZERO.test(value)) {
1399
- throw new TomlError("leading zeroes are not allowed", {
1400
- toml,
1401
- ptr
1402
- });
1557
+ throw new TomlError("leading zeroes are not allowed", err);
1403
1558
  }
1404
1559
  value = value.replace(/_/g, "");
1405
1560
  let numeric = +value;
1406
1561
  if (isNaN(numeric)) {
1407
- throw new TomlError("invalid number", {
1408
- toml,
1409
- ptr
1410
- });
1562
+ throw new TomlError("invalid number", err);
1411
1563
  }
1412
1564
  if (isInt) {
1413
1565
  if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
1414
- throw new TomlError("integer value cannot be represented losslessly", {
1415
- toml,
1416
- ptr
1417
- });
1566
+ throw new TomlError("integer value cannot be represented losslessly", err);
1418
1567
  }
1419
1568
  if (isInt || integersAsBigInt === true)
1420
1569
  numeric = BigInt(value);
@@ -1422,277 +1571,184 @@ function parseValue(value, toml, ptr, integersAsBigInt) {
1422
1571
  return numeric;
1423
1572
  }
1424
1573
  const date = new TomlDate(value);
1425
- if (!date.isValid()) {
1426
- throw new TomlError("invalid value", {
1427
- toml,
1428
- ptr
1429
- });
1430
- }
1574
+ if (!date.isValid())
1575
+ throw new TomlError("invalid value", err);
1431
1576
  return date;
1432
1577
  }
1433
1578
 
1434
- // node_modules/smol-toml/dist/util.js
1435
- function indexOfNewline(str, start = 0, end = str.length) {
1436
- let idx = str.indexOf("\n", start);
1437
- if (str[idx - 1] === "\r")
1438
- idx--;
1439
- return idx <= end ? idx : -1;
1440
- }
1441
- function skipComment(str, ptr) {
1442
- for (let i = ptr; i < str.length; i++) {
1443
- let c = str[i];
1444
- if (c === "\n")
1445
- return i;
1446
- if (c === "\r" && str[i + 1] === "\n")
1447
- return i + 1;
1448
- if (c < " " && c !== " " || c === "\x7F") {
1449
- throw new TomlError("control characters are not allowed in comments", {
1450
- toml: str,
1579
+ // node_modules/smol-toml/dist/extract.js
1580
+ function extractValue(ctx, end, integersAsBigInt) {
1581
+ let ptr = ctx.p;
1582
+ let c = ctx.s.charCodeAt(ptr);
1583
+ if (c === 91 || c === 123) {
1584
+ if (!ctx.d--) {
1585
+ throw new TomlError("document contains excessively nested structures. aborting.", {
1586
+ toml: ctx.s,
1451
1587
  ptr
1452
1588
  });
1453
1589
  }
1590
+ let value = c === 91 ? parseArray(ctx, integersAsBigInt) : parseInlineTable(ctx, integersAsBigInt);
1591
+ ctx.d++;
1592
+ return value;
1454
1593
  }
1455
- return str.length;
1456
- }
1457
- function skipVoid(str, ptr, banNewLines, banComments) {
1458
- let c;
1459
- while (1) {
1460
- while ((c = str[ptr]) === " " || c === " " || !banNewLines && (c === "\n" || c === "\r" && str[ptr + 1] === "\n"))
1461
- ptr++;
1462
- if (banComments || c !== "#")
1463
- break;
1464
- ptr = skipComment(str, ptr);
1465
- }
1466
- return ptr;
1467
- }
1468
- function skipUntil(str, ptr, sep, end, banNewLines = false) {
1469
- if (!end) {
1470
- ptr = indexOfNewline(str, ptr);
1471
- return ptr < 0 ? str.length : ptr;
1472
- }
1473
- for (let i = ptr; i < str.length; i++) {
1474
- let c = str[i];
1475
- if (c === "#") {
1476
- i = indexOfNewline(str, i);
1477
- } else if (c === sep) {
1478
- return i + 1;
1479
- } else if (c === end || banNewLines && (c === "\n" || c === "\r" && str[i + 1] === "\n")) {
1480
- return i;
1481
- }
1482
- }
1483
- throw new TomlError("cannot find end of structure", {
1484
- toml: str,
1485
- ptr
1486
- });
1487
- }
1488
-
1489
- // node_modules/smol-toml/dist/extract.js
1490
- function sliceAndTrimEndOf(str, startPtr, endPtr) {
1491
- let value = str.slice(startPtr, endPtr);
1492
- let commentIdx = value.indexOf("#");
1493
- if (commentIdx > -1) {
1494
- skipComment(str, commentIdx);
1495
- value = value.slice(0, commentIdx);
1496
- }
1497
- return [value.trimEnd(), commentIdx];
1498
- }
1499
- function extractValue(str, ptr, end, depth, integersAsBigInt) {
1500
- if (depth === 0) {
1501
- throw new TomlError("document contains excessively nested structures. aborting.", {
1502
- toml: str,
1503
- ptr
1504
- });
1505
- }
1506
- let c = str[ptr];
1507
- if (c === "[" || c === "{") {
1508
- let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
1509
- if (end) {
1510
- endPtr2 = skipVoid(str, endPtr2);
1511
- if (str[endPtr2] === ",")
1512
- endPtr2++;
1513
- else if (str[endPtr2] !== end) {
1514
- throw new TomlError("expected comma or end of structure", {
1515
- toml: str,
1516
- ptr: endPtr2
1517
- });
1518
- }
1519
- }
1520
- return [value, endPtr2];
1521
- }
1522
- if (c === '"' || c === "'") {
1523
- let [parsed, endPtr2] = parseString(str, ptr);
1524
- if (end) {
1525
- endPtr2 = skipVoid(str, endPtr2);
1526
- if (str[endPtr2] && str[endPtr2] !== "," && str[endPtr2] !== end && str[endPtr2] !== "\n" && str[endPtr2] !== "\r") {
1527
- throw new TomlError("unexpected character encountered", {
1528
- toml: str,
1529
- ptr: endPtr2
1530
- });
1531
- }
1532
- if (str[endPtr2] === ",")
1533
- endPtr2++;
1534
- }
1535
- return [parsed, endPtr2];
1594
+ if (c === 34 || c === 39) {
1595
+ return parseString(ctx);
1536
1596
  }
1537
- let endPtr = skipUntil(str, ptr, ",", end);
1538
- let slice = sliceAndTrimEndOf(str, ptr, endPtr - (str[endPtr - 1] === "," ? 1 : 0));
1539
- if (!slice[0]) {
1540
- throw new TomlError("incomplete key-value declaration: no value specified", {
1541
- toml: str,
1542
- ptr
1543
- });
1597
+ if (c === 116) {
1598
+ if (ctx.s.charCodeAt(++ctx.p) !== 114 || ctx.s.charCodeAt(++ctx.p) !== 117 || ctx.s.charCodeAt(++ctx.p) !== 101)
1599
+ throw new TomlError("invalid value", { toml: ctx.s, ptr });
1600
+ ctx.p++;
1601
+ return true;
1544
1602
  }
1545
- if (end && slice[1] > -1) {
1546
- endPtr = skipVoid(str, ptr + slice[1]);
1547
- if (str[endPtr] === ",")
1548
- endPtr++;
1603
+ if (c === 102) {
1604
+ if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 108 || ctx.s.charCodeAt(++ctx.p) !== 115 || ctx.s.charCodeAt(++ctx.p) !== 101)
1605
+ throw new TomlError("invalid value", { toml: ctx.s, ptr });
1606
+ ctx.p++;
1607
+ return false;
1549
1608
  }
1550
- return [
1551
- parseValue(slice[0], str, ptr, integersAsBigInt),
1552
- endPtr
1553
- ];
1609
+ return parseValue(ctx, integersAsBigInt, end);
1554
1610
  }
1555
1611
 
1556
1612
  // node_modules/smol-toml/dist/struct.js
1557
1613
  var KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
1558
- function parseKey(str, ptr, end = "=") {
1559
- let dot = ptr - 1;
1614
+ function parseKey(ctx, end = "=") {
1615
+ let start = ctx.p;
1616
+ let dot = start - 1;
1560
1617
  let parsed = [];
1561
- let endPtr = str.indexOf(end, ptr);
1618
+ let endPtr = ctx.s.indexOf(end, start);
1562
1619
  if (endPtr < 0) {
1563
1620
  throw new TomlError("incomplete key-value: cannot find end of key", {
1564
- toml: str,
1565
- ptr
1621
+ toml: ctx.s,
1622
+ ptr: start
1566
1623
  });
1567
1624
  }
1568
1625
  do {
1569
- let c = str[ptr = ++dot];
1570
- if (c !== " " && c !== " ") {
1571
- if (c === '"' || c === "'") {
1572
- if (c === str[ptr + 1] && c === str[ptr + 2]) {
1626
+ let c = ctx.s.charCodeAt(ctx.p = ++dot);
1627
+ if (c !== 32 && c !== 9) {
1628
+ if (c === 34 || c === 39) {
1629
+ if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) {
1573
1630
  throw new TomlError("multiline strings are not allowed in keys", {
1574
- toml: str,
1575
- ptr
1631
+ toml: ctx.s,
1632
+ ptr: ctx.p
1576
1633
  });
1577
1634
  }
1578
- let [part, eos] = parseString(str, ptr);
1579
- dot = str.indexOf(".", eos);
1580
- let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
1635
+ let part = parseString(ctx);
1636
+ dot = ctx.s.indexOf(".", ctx.p);
1637
+ let strEnd = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);
1581
1638
  let newLine = indexOfNewline(strEnd);
1582
1639
  if (newLine > -1) {
1583
1640
  throw new TomlError("newlines are not allowed in keys", {
1584
- toml: str,
1585
- ptr: ptr + dot + newLine
1641
+ toml: ctx.s,
1642
+ ptr: newLine
1586
1643
  });
1587
1644
  }
1588
1645
  if (strEnd.trimStart()) {
1589
1646
  throw new TomlError("found extra tokens after the string part", {
1590
- toml: str,
1591
- ptr: eos
1647
+ toml: ctx.s,
1648
+ ptr: ctx.p
1592
1649
  });
1593
1650
  }
1594
- if (endPtr < eos) {
1595
- endPtr = str.indexOf(end, eos);
1651
+ if (endPtr < ctx.p) {
1652
+ endPtr = ctx.s.indexOf(end, ctx.p);
1596
1653
  if (endPtr < 0) {
1597
1654
  throw new TomlError("incomplete key-value: cannot find end of key", {
1598
- toml: str,
1599
- ptr
1655
+ toml: ctx.s,
1656
+ ptr: start
1600
1657
  });
1601
1658
  }
1602
1659
  }
1603
1660
  parsed.push(part);
1604
1661
  } else {
1605
- dot = str.indexOf(".", ptr);
1606
- let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
1662
+ dot = ctx.s.indexOf(".", ctx.p);
1663
+ let part = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);
1607
1664
  if (!KEY_PART_RE.test(part)) {
1608
1665
  throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
1609
- toml: str,
1610
- ptr
1666
+ toml: ctx.s,
1667
+ ptr: ctx.p
1611
1668
  });
1612
1669
  }
1613
1670
  parsed.push(part.trimEnd());
1614
1671
  }
1615
1672
  }
1616
1673
  } while (dot + 1 && dot < endPtr);
1617
- return [parsed, skipVoid(str, endPtr + 1, true, true)];
1674
+ ctx.p = endPtr + 1;
1675
+ skipVoid(ctx, true, true);
1676
+ return parsed;
1618
1677
  }
1619
- function parseInlineTable(str, ptr, depth, integersAsBigInt) {
1678
+ function parseInlineTable(ctx, integersAsBigInt) {
1620
1679
  let res = {};
1621
1680
  let seen = /* @__PURE__ */ new Set();
1622
1681
  let c;
1623
- ptr++;
1624
- while ((c = str[ptr++]) !== "}" && c) {
1625
- if (c === ",") {
1626
- throw new TomlError("expected value, found comma", {
1627
- toml: str,
1628
- ptr: ptr - 1
1629
- });
1630
- } else if (c === "#")
1631
- ptr = skipComment(str, ptr);
1632
- else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
1633
- let k;
1634
- let t = res;
1635
- let hasOwn = false;
1636
- let [key, keyEndPtr] = parseKey(str, ptr - 1);
1637
- for (let i = 0; i < key.length; i++) {
1638
- if (i)
1639
- t = hasOwn ? t[k] : t[k] = {};
1640
- k = key[i];
1641
- if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
1642
- throw new TomlError("trying to redefine an already defined value", {
1643
- toml: str,
1644
- ptr
1645
- });
1646
- }
1647
- if (!hasOwn && k === "__proto__") {
1648
- Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
1649
- }
1650
- }
1651
- if (hasOwn) {
1682
+ ctx.p++;
1683
+ while (ctx.p < ctx.s.length) {
1684
+ skipVoid(ctx);
1685
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 125) {
1686
+ ctx.p++;
1687
+ return res;
1688
+ }
1689
+ let k;
1690
+ let t = res;
1691
+ let hasOwn = false;
1692
+ let p = ctx.p;
1693
+ let key = parseKey(ctx);
1694
+ for (let i = 0; i < key.length; i++) {
1695
+ if (i)
1696
+ t = hasOwn ? t[k] : t[k] = {};
1697
+ k = key[i];
1698
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
1652
1699
  throw new TomlError("trying to redefine an already defined value", {
1653
- toml: str,
1654
- ptr
1700
+ toml: ctx.s,
1701
+ ptr: p
1655
1702
  });
1656
1703
  }
1657
- let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
1658
- seen.add(value);
1659
- t[k] = value;
1660
- ptr = valueEndPtr;
1704
+ if (!hasOwn && k === "__proto__") {
1705
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
1706
+ }
1707
+ }
1708
+ if (hasOwn) {
1709
+ throw new TomlError("trying to redefine an already defined value", {
1710
+ toml: ctx.s,
1711
+ ptr: ctx.p
1712
+ });
1713
+ }
1714
+ let value = extractValue(ctx, 125, integersAsBigInt);
1715
+ seen.add(t[k] = value);
1716
+ skipVoid(ctx);
1717
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 125) {
1718
+ return res;
1719
+ }
1720
+ if (c !== 44) {
1721
+ throw new TomlError("expected comma or end of structure", { toml: ctx.s, ptr: ctx.p - 1 });
1661
1722
  }
1662
1723
  }
1663
- if (!c) {
1664
- throw new TomlError("unfinished table encountered", {
1665
- toml: str,
1666
- ptr
1667
- });
1668
- }
1669
- return [res, ptr];
1724
+ throw new TomlError("unfinished table encountered", {
1725
+ toml: ctx.s,
1726
+ ptr: ctx.p
1727
+ });
1670
1728
  }
1671
- function parseArray(str, ptr, depth, integersAsBigInt) {
1729
+ function parseArray(ctx, integersAsBigInt) {
1672
1730
  let res = [];
1673
1731
  let c;
1674
- ptr++;
1675
- while ((c = str[ptr++]) !== "]" && c) {
1676
- if (c === ",") {
1677
- throw new TomlError("expected value, found comma", {
1678
- toml: str,
1679
- ptr: ptr - 1
1680
- });
1681
- } else if (c === "#")
1682
- ptr = skipComment(str, ptr);
1683
- else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
1684
- let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
1685
- res.push(e[0]);
1686
- ptr = e[1];
1687
- }
1688
- }
1689
- if (!c) {
1690
- throw new TomlError("unfinished array encountered", {
1691
- toml: str,
1692
- ptr
1693
- });
1732
+ ctx.p++;
1733
+ while (ctx.p < ctx.s.length) {
1734
+ skipVoid(ctx);
1735
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 93) {
1736
+ ctx.p++;
1737
+ return res;
1738
+ }
1739
+ res.push(extractValue(ctx, 93, integersAsBigInt));
1740
+ skipVoid(ctx);
1741
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 93) {
1742
+ return res;
1743
+ }
1744
+ if (c !== 44) {
1745
+ throw new TomlError("expected comma or end of structure", { toml: ctx.s, ptr: ctx.p - 1 });
1746
+ }
1694
1747
  }
1695
- return [res, ptr];
1748
+ throw new TomlError("unfinished array encountered", {
1749
+ toml: ctx.s,
1750
+ ptr: ctx.p
1751
+ });
1696
1752
  }
1697
1753
 
1698
1754
  // node_modules/smol-toml/dist/parse.js
@@ -1756,25 +1812,29 @@ function peekTable(key, table, meta, type) {
1756
1812
  return [k, t, state.c];
1757
1813
  }
1758
1814
  function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
1815
+ let ctx = { s: toml, p: 0, d: maxDepth };
1759
1816
  let res = {};
1760
1817
  let meta = {};
1818
+ let tmp;
1761
1819
  let tbl = res;
1762
1820
  let m = meta;
1763
- for (let ptr = skipVoid(toml, 0); ptr < toml.length; ) {
1764
- if (toml[ptr] === "[") {
1765
- let isTableArray = toml[++ptr] === "[";
1766
- let k = parseKey(toml, ptr += +isTableArray, "]");
1821
+ skipVoid(ctx);
1822
+ while (ctx.p < toml.length) {
1823
+ if (toml.charCodeAt(ctx.p) === 91) {
1824
+ let isTableArray = toml.charCodeAt(++ctx.p) === 91;
1825
+ tmp = ctx.p += +isTableArray;
1826
+ let k = parseKey(ctx, "]");
1767
1827
  if (isTableArray) {
1768
- if (toml[k[1] - 1] !== "]") {
1828
+ if (toml.charCodeAt(ctx.p - 1) !== 93) {
1769
1829
  throw new TomlError("expected end of table declaration", {
1770
1830
  toml,
1771
- ptr: k[1] - 1
1831
+ ptr: ctx.p - 1
1772
1832
  });
1773
1833
  }
1774
- k[1]++;
1834
+ ctx.p++;
1775
1835
  }
1776
1836
  let p = peekTable(
1777
- k[0],
1837
+ k,
1778
1838
  res,
1779
1839
  meta,
1780
1840
  isTableArray ? 2 : 1
@@ -1783,16 +1843,16 @@ function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
1783
1843
  if (!p) {
1784
1844
  throw new TomlError("trying to redefine an already defined table or value", {
1785
1845
  toml,
1786
- ptr
1846
+ ptr: tmp
1787
1847
  });
1788
1848
  }
1789
1849
  m = p[2];
1790
1850
  tbl = p[1];
1791
- ptr = k[1];
1792
1851
  } else {
1793
- let k = parseKey(toml, ptr);
1852
+ tmp = ctx.p;
1853
+ let k = parseKey(ctx);
1794
1854
  let p = peekTable(
1795
- k[0],
1855
+ k,
1796
1856
  tbl,
1797
1857
  m,
1798
1858
  0
@@ -1801,21 +1861,19 @@ function parse(toml, { maxDepth = 1e3, integersAsBigInt } = {}) {
1801
1861
  if (!p) {
1802
1862
  throw new TomlError("trying to redefine an already defined table or value", {
1803
1863
  toml,
1804
- ptr
1864
+ ptr: tmp
1805
1865
  });
1806
1866
  }
1807
- let v = extractValue(toml, k[1], void 0, maxDepth, integersAsBigInt);
1808
- p[1][p[0]] = v[0];
1809
- ptr = v[1];
1867
+ p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);
1810
1868
  }
1811
- ptr = skipVoid(toml, ptr, true);
1812
- if (toml[ptr] && toml[ptr] !== "\n" && toml[ptr] !== "\r") {
1869
+ skipVoid(ctx, true);
1870
+ if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 10 && tmp !== 13) {
1813
1871
  throw new TomlError("each key-value declaration must be followed by an end-of-line", {
1814
1872
  toml,
1815
- ptr
1873
+ ptr: ctx.p
1816
1874
  });
1817
1875
  }
1818
- ptr = skipVoid(toml, ptr);
1876
+ skipVoid(ctx);
1819
1877
  }
1820
1878
  return res;
1821
1879
  }
@@ -1827,8 +1885,12 @@ function extendedTypeOf(obj) {
1827
1885
  if (type === "object") {
1828
1886
  if (Array.isArray(obj))
1829
1887
  return "array";
1830
- if (obj instanceof Date)
1888
+ if (typeof obj?.getUTCDate === "function" && obj instanceof Date)
1831
1889
  return "date";
1890
+ if (globalThis.Temporal && // check for the 'since' property as an early bailout that avoids running all 5 instanceof checks
1891
+ typeof obj?.since === "function" && (obj instanceof Temporal.Instant || obj instanceof Temporal.PlainDate || obj instanceof Temporal.PlainDateTime || obj instanceof Temporal.PlainTime || obj instanceof Temporal.ZonedDateTime)) {
1892
+ return "temporal";
1893
+ }
1832
1894
  }
1833
1895
  return type;
1834
1896
  }
@@ -1842,38 +1904,42 @@ function isArrayOfTables(obj) {
1842
1904
  function formatString(s) {
1843
1905
  return JSON.stringify(s).replace(/\x7f/g, "\\u007f");
1844
1906
  }
1907
+ function stringifyTemporal(temporal) {
1908
+ return temporal.toString({
1909
+ calendarName: "never",
1910
+ timeZoneName: "never"
1911
+ });
1912
+ }
1845
1913
  function stringifyValue(val, type, depth, numberAsFloat) {
1846
1914
  if (depth === 0) {
1847
1915
  throw new Error("Could not stringify the object: maximum object depth exceeded");
1848
1916
  }
1849
- if (type === "number") {
1850
- if (isNaN(val))
1851
- return "nan";
1852
- if (val === Infinity)
1853
- return "inf";
1854
- if (val === -Infinity)
1855
- return "-inf";
1856
- if (Number.isInteger(val) && (numberAsFloat || !Number.isSafeInteger(val)))
1857
- return val.toFixed(1);
1858
- return val.toString();
1859
- }
1860
- if (type === "bigint" || type === "boolean") {
1861
- return val.toString();
1862
- }
1863
- if (type === "string") {
1864
- return formatString(val);
1865
- }
1866
- if (type === "date") {
1867
- if (isNaN(val.getTime())) {
1868
- throw new TypeError("cannot serialize invalid date");
1869
- }
1870
- return val.toISOString();
1871
- }
1872
- if (type === "object") {
1873
- return stringifyInlineTable(val, depth, numberAsFloat);
1874
- }
1875
- if (type === "array") {
1876
- return stringifyArray(val, depth, numberAsFloat);
1917
+ switch (type) {
1918
+ // @ts-expect-error -- intentional fallthrough case
1919
+ case "number":
1920
+ if (isNaN(val))
1921
+ return "nan";
1922
+ if (val === Infinity)
1923
+ return "inf";
1924
+ if (val === -Infinity)
1925
+ return "-inf";
1926
+ if (Number.isInteger(val) && (numberAsFloat || !Number.isSafeInteger(val)))
1927
+ return val.toFixed(1);
1928
+ case "bigint":
1929
+ case "boolean":
1930
+ return val.toString();
1931
+ case "string":
1932
+ return formatString(val);
1933
+ case "date":
1934
+ if (isNaN(val.getTime()))
1935
+ throw new TypeError("cannot serialize invalid date");
1936
+ return val.toISOString();
1937
+ case "object":
1938
+ return stringifyInlineTable(val, depth, numberAsFloat);
1939
+ case "array":
1940
+ return stringifyArray(val, depth, numberAsFloat);
1941
+ case "temporal":
1942
+ return stringifyTemporal(val);
1877
1943
  }
1878
1944
  }
1879
1945
  function stringifyInlineTable(obj, depth, numberAsFloat) {
@@ -2432,7 +2498,7 @@ function getLastProjectConfigParseError() {
2432
2498
  return _lastProjectConfigParseError;
2433
2499
  }
2434
2500
  var PROJECT_LOCKED_SECTIONS = ["injection", "webfetch", "gdrive", "mcp", "network"];
2435
- var PROJECT_LOCKED_KEYS = ["indexing.cross_project_symbols"];
2501
+ var PROJECT_LOCKED_KEYS = ["indexing.cross_project_symbols", "worker.blocked_roots"];
2436
2502
  var _lastProjectConfigLockedKeys = [];
2437
2503
  function stripLockedProjectKeys(projectRaw) {
2438
2504
  const cleaned = {};
@@ -2604,6 +2670,9 @@ function resolveConfigProjectRoot() {
2604
2670
  _projectRootCache = { cwd, root };
2605
2671
  return root;
2606
2672
  }
2673
+ registerReset(() => {
2674
+ _projectRootCache = null;
2675
+ });
2607
2676
  function isAutoTriggerMultiplierExplicit() {
2608
2677
  const setsMultiplier = (text) => {
2609
2678
  const raw = parse(text);
@@ -4095,7 +4164,8 @@ function propagateEndLinesToSymbols(symbols, sections) {
4095
4164
  return sym;
4096
4165
  });
4097
4166
  }
4098
- function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex) {
4167
+ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex, lineCommentPrefix, opts) {
4168
+ const block = opts?.blockComment;
4099
4169
  let depth = 0;
4100
4170
  let quote = null;
4101
4171
  for (let i = openBraceIndex; i < content.length; i++) {
@@ -4108,6 +4178,15 @@ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex
4108
4178
  if (ch === quote) quote = null;
4109
4179
  continue;
4110
4180
  }
4181
+ if (block !== void 0 && content.startsWith(block[0], i)) {
4182
+ const close = content.indexOf(block[1], i + block[0].length);
4183
+ i = close === -1 ? content.length : close + block[1].length - 1;
4184
+ continue;
4185
+ }
4186
+ if (lineCommentPrefix !== void 0 && content.startsWith(lineCommentPrefix, i)) {
4187
+ while (i < content.length && content[i] !== "\n") i++;
4188
+ continue;
4189
+ }
4111
4190
  if (ch === '"' || ch === "'") {
4112
4191
  quote = ch;
4113
4192
  continue;
@@ -4120,7 +4199,106 @@ function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex
4120
4199
  }
4121
4200
  }
4122
4201
  }
4123
- return totalLines;
4202
+ return opts?.noMatchValue ?? totalLines;
4203
+ }
4204
+ function assignBraceBlockSpans(symbols, content, lineCommentPrefix) {
4205
+ if (symbols.length === 0) return [...symbols];
4206
+ const lines = content.split("\n");
4207
+ const totalLines = lines.length;
4208
+ const lineIndex = buildLineIndex(content);
4209
+ const starts = [...new Set(symbols.map((s) => s.lineStart))].sort((a, b) => a - b);
4210
+ const blockComment = lineCommentPrefix === "//" ? ["/*", "*/"] : lineCommentPrefix === "#" ? ["<#", "#>"] : void 0;
4211
+ return symbols.map((sym) => {
4212
+ if (sym.lineEnd !== sym.lineStart) return sym;
4213
+ const nextStart = starts.find((s) => s > sym.lineStart);
4214
+ const lastSearchLine = Math.min(nextStart !== void 0 ? nextStart - 1 : totalLines, sym.lineStart + BRACE_SEARCH_MAX_LINES);
4215
+ const openIndex = findBlockOpenBrace(content, lineIndex, sym.lineStart, lastSearchLine, lineCommentPrefix, blockComment);
4216
+ if (openIndex === null) return sym;
4217
+ const endLine = findMatchingBraceEndLine(
4218
+ content,
4219
+ openIndex,
4220
+ totalLines,
4221
+ lineIndex,
4222
+ lineCommentPrefix,
4223
+ blockComment === void 0 ? { noMatchValue: -1 } : { blockComment, noMatchValue: -1 }
4224
+ );
4225
+ if (endLine <= sym.lineStart) return sym;
4226
+ return { ...sym, lineEnd: endLine, body: lines.slice(sym.lineStart - 1, endLine).join("\n") };
4227
+ });
4228
+ }
4229
+ var BRACE_SEARCH_MAX_LINES = 10;
4230
+ function findBlockOpenBrace(content, lineIndex, startLine, lastSearchLine, lineCommentPrefix, blockComment) {
4231
+ const from = lineIndex[startLine - 1];
4232
+ if (from === void 0) return null;
4233
+ const to = lineIndex[lastSearchLine] ?? content.length;
4234
+ let quote = null;
4235
+ let parenDepth = 0;
4236
+ let linesSeen = 0;
4237
+ let atLineStart = false;
4238
+ for (let i = from; i < to; i++) {
4239
+ const ch = content[i];
4240
+ if (ch === void 0) break;
4241
+ if (quote !== null) {
4242
+ if (ch === "\\") {
4243
+ i++;
4244
+ continue;
4245
+ }
4246
+ if (ch === quote) quote = null;
4247
+ continue;
4248
+ }
4249
+ if (ch === "\n") {
4250
+ linesSeen++;
4251
+ atLineStart = true;
4252
+ continue;
4253
+ }
4254
+ if (blockComment !== void 0 && content.startsWith(blockComment[0], i)) {
4255
+ const close = content.indexOf(blockComment[1], i + blockComment[0].length);
4256
+ if (close === -1) return null;
4257
+ i = close + blockComment[1].length - 1;
4258
+ continue;
4259
+ }
4260
+ if (lineCommentPrefix !== void 0 && content.startsWith(lineCommentPrefix, i)) {
4261
+ while (i + 1 < to && content[i + 1] !== "\n") i++;
4262
+ continue;
4263
+ }
4264
+ if (atLineStart && !/\s/.test(ch)) {
4265
+ atLineStart = false;
4266
+ if (parenDepth === 0 && linesSeen >= 1 && startsWithBlockKeyword(content, i, to)) return null;
4267
+ }
4268
+ if (ch === '"' || ch === "'") {
4269
+ quote = ch;
4270
+ continue;
4271
+ }
4272
+ if (ch === "(" || ch === "[") parenDepth++;
4273
+ else if (ch === ")" || ch === "]") {
4274
+ if (parenDepth > 0) parenDepth--;
4275
+ } else if (ch === ";") return null;
4276
+ else if (ch === "{") return i;
4277
+ }
4278
+ return null;
4279
+ }
4280
+ var BLOCK_OPENING_KEYWORDS = /* @__PURE__ */ new Set([
4281
+ "if",
4282
+ "for",
4283
+ "while",
4284
+ "do",
4285
+ "switch",
4286
+ "when",
4287
+ "match",
4288
+ "try",
4289
+ "foreach",
4290
+ "loop",
4291
+ "guard",
4292
+ "repeat",
4293
+ "unless",
4294
+ "until"
4295
+ ]);
4296
+ function startsWithBlockKeyword(content, i, to) {
4297
+ const first = content[i];
4298
+ if (first === void 0 || !/[A-Za-z_]/.test(first)) return false;
4299
+ let j = i + 1;
4300
+ while (j < to && /[A-Za-z0-9_]/.test(content[j])) j++;
4301
+ return BLOCK_OPENING_KEYWORDS.has(content.slice(i, j));
4124
4302
  }
4125
4303
 
4126
4304
  // src/languages/ini_idx.ts
@@ -4134,7 +4312,7 @@ function extractIni(content, filePath) {
4134
4312
  const sections = [];
4135
4313
  const seen = /* @__PURE__ */ new Set();
4136
4314
  const lines = content.split(/\r?\n/);
4137
- const totalLines = lines.length;
4315
+ const totalLines = countContentLines(content);
4138
4316
  for (let i = 0; i < lines.length; i++) {
4139
4317
  if (symbols.length >= MAX_SECTIONS) break;
4140
4318
  const line = lines[i] ?? "";
@@ -5436,6 +5614,8 @@ var KIND_TO_SOURCE = {
5436
5614
  json_outline: SOURCE_READ,
5437
5615
  yaml_query: SOURCE_READ,
5438
5616
  yaml_outline: SOURCE_READ,
5617
+ xml_query: SOURCE_READ,
5618
+ xml_outline: SOURCE_READ,
5439
5619
  openapi_op: SOURCE_READ,
5440
5620
  openapi_outline: SOURCE_READ,
5441
5621
  zip_list: SOURCE_READ,
@@ -5521,6 +5701,8 @@ var COMMAND_KINDS = {
5521
5701
  "json-outline": /* @__PURE__ */ new Set(["json_outline"]),
5522
5702
  "yaml-query": /* @__PURE__ */ new Set(["yaml_query"]),
5523
5703
  "yaml-outline": /* @__PURE__ */ new Set(["yaml_outline"]),
5704
+ "xml-query": /* @__PURE__ */ new Set(["xml_query"]),
5705
+ "xml-outline": /* @__PURE__ */ new Set(["xml_outline"]),
5524
5706
  "openapi-op": /* @__PURE__ */ new Set(["openapi_op"]),
5525
5707
  "openapi-outline": /* @__PURE__ */ new Set(["openapi_outline"]),
5526
5708
  "zip-list": /* @__PURE__ */ new Set(["zip_list"]),
@@ -5855,13 +6037,42 @@ var SECRET_PATTERNS = [
5855
6037
  // contain '_' and could otherwise partially match the classic pattern.
5856
6038
  ["github_token", /github_pat_[A-Za-z0-9_]{22,}/g],
5857
6039
  ["github_token", /gh[oprsu]_[A-Za-z0-9]{36,}/g],
6040
+ // xapp- is Slack's app-level token (Socket Mode), a bearer credential in its own right that
6041
+ // the xox[baprs]- prefix does not cover. It gets its own entry rather than joining the
6042
+ // alternation above because it needs the full segmented shape (xapp-<ver>-<app id>-<digits>-
6043
+ // <hex>) to be safe: a bare /xapp-[A-Za-z0-9-]+/ redacted ordinary identifiers like
6044
+ // "xapp-config" and the css class "xapp-container", mangling normal source. The xox* prefixes
6045
+ // are distinctive enough on their own; "xapp-" is not.
5858
6046
  ["slack_token", /xox[baprs]-[A-Za-z0-9-]+/g],
6047
+ ["slack_token", /xapp-\d-[A-Za-z0-9]{6,}-\d{8,}-[A-Za-z0-9]{16,}/g],
5859
6048
  // Matches the full block (BEGIN marker through its matching END marker), not just the
5860
6049
  // header -- the actual secret material is the base64 body between them, so redacting only
5861
6050
  // the header line would leave the key bytes themselves fully readable in the cached blob.
5862
- // The lazy [\s\S]*? is bounded by the very next END marker (private key blocks don't nest),
5863
- // so this stays linear in practice despite the lazy quantifier.
5864
- ["private_key_block", /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g],
6051
+ // The body is lazy and additionally refuses to cross a following BEGIN marker. Both halves
6052
+ // matter. The laziness bounds a successful match at the very next END marker; the negative
6053
+ // lookahead bounds a *failing* one, because a BEGIN with no END of its own would otherwise
6054
+ // scan to end-of-input, and a blob full of such markers made the pass quadratic -- 6 ms, 20 ms
6055
+ // and 78 ms for 2000, 4000 and 8000 of them, four times the work for twice the input, the same
6056
+ // shape as the lookbehind incident described above. Private key blocks do not nest, so
6057
+ // refusing to cross a BEGIN costs nothing in correctness.
6058
+ // The algorithm and ` BLOCK` groups are backreferenced in the END marker rather than repeated,
6059
+ // so a BEGIN only ever pairs with its own END spelling. Written as two independent optional
6060
+ // groups, `BEGIN PGP PRIVATE KEY` would happily close on a distant `END RSA PRIVATE KEY BLOCK`
6061
+ // and redact everything in between. A non-participating group backreferences as the empty
6062
+ // string in JS, which is exactly what the unprefixed `BEGIN PRIVATE KEY` form needs.
6063
+ // The algorithm list covers every armored private-key header openssl, ssh-keygen and gpg
6064
+ // actually emit, not just the ones a first draft happened to think of. ENCRYPTED is the
6065
+ // PKCS#8 passphrase-protected form (`openssl genpkey -aes256`, `ssh-keygen -m PKCS8`) and is
6066
+ // the most common shape of all; DSA is legacy but still written verbatim; PGP carries the
6067
+ // ` BLOCK` suffix, which is why that suffix is optional here. All three used to fall through
6068
+ // to disk in full. An encrypted key is still key material: the passphrase can be attacked
6069
+ // offline once the bytes are cached, so it is redacted like any other.
6070
+ // PuTTY `.ppk` files are deliberately not matched. They have no END marker -- the private
6071
+ // section is a `Private-Lines: N` count followed by exactly N base64 lines -- so bounding a
6072
+ // match would take a stateful parse rather than a regex, on a path that runs over every
6073
+ // command output. A regex guess at where the body ends is exactly the over-eager match this
6074
+ // module's header warns against.
6075
+ ["private_key_block", /-----BEGIN (RSA |DSA |EC |OPENSSH |ENCRYPTED |PGP )?PRIVATE KEY( BLOCK)?-----(?:(?!-----BEGIN )[\s\S])*?-----END \1PRIVATE KEY\2-----/g],
5865
6076
  // Redacts only the token itself, not the "Authorization: Bearer " prefix -- the lookbehind
5866
6077
  // anchors on the header name and scheme so the surrounding request-log line stays readable,
5867
6078
  // matching how AWS_ACCESS_KEY_ID=... above keeps its own prefix intact.
@@ -5870,7 +6081,13 @@ var SECRET_PATTERNS = [
5870
6081
  // directly against the header name and the scheme directly against the space, so a body like
5871
6082
  // {"Authorization": "Bearer <token>"} -- the shape any logged fetch or MCP result arrives in
5872
6083
  // -- matched nothing and the token was cached verbatim.
5873
- ["auth_bearer_token", /(?<=Authorization["']?[ \t]{0,8}:[ \t]{0,8}["']?[ \t]{0,8}Bearer[ \t])[A-Za-z0-9\-._~+/]{10,}=*/gi],
6084
+ // `token` is the second scheme spelling in wide use -- it is what curl and gh examples pass for
6085
+ // GitHub and many other APIs -- and an opaque value behind it carries exactly the same authority
6086
+ // as one behind `Bearer`. The trailing gap is `{1,8}` rather than a single space for the same
6087
+ // reason every other gap in this lookbehind already is: a hand-aligned or reformatted header
6088
+ // ("Authorization: Bearer <token>") is ordinary, and demanding exactly one space there made
6089
+ // this the one position in the pattern that a second space defeated.
6090
+ ["auth_bearer_token", /(?<=Authorization["']?[ \t]{0,8}:[ \t]{0,8}["']?[ \t]{0,8}(?:Bearer|token)[ \t]{1,8})[A-Za-z0-9\-._~+/]{10,}=*/gi],
5874
6091
  ["auth_basic_token", /(?<=Authorization["']?[ \t]{0,8}:[ \t]{0,8}["']?[ \t]{0,8}Basic[ \t])[A-Za-z0-9+/]{6,}=*/gi],
5875
6092
  // JWTs have no distinctive prefix of their own, but the base64url encoding of the smallest
5876
6093
  // realistic header ('{"alg":' or similar) always starts with "eyJ", so that's the practical
@@ -5924,7 +6141,22 @@ var SECRET_PATTERNS = [
5924
6141
  // SECRET_KEY=, and DB_PASSWORD_HASH= all passed through in full. That class matches
5925
6142
  // identifier characters only, so prose that merely mentions a keyword still never reaches
5926
6143
  // a separator and stays unredacted. api[_-]?key covers the apikey and api-key spellings too.
5927
- ["generic_secret_assignment", /(?<=(?:password|passwd|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|id[_-]?token)[a-z0-9_-]{0,64}["']?[ \t]{0,8}[:=][ \t]{0,8}["']?)(?:\\[^\n]|[^\s\\&;#'"[\],{}:]){4,}/gi]
6144
+ // `& ; # , :` play two incompatible roles. They separate one field from the next (a query
6145
+ // string, a cookie header, an inline env list), and they are also perfectly ordinary password
6146
+ // characters. Rejecting them outright got the first role right and the second badly wrong: the
6147
+ // match stopped at the first one and left everything after it in plain text, so
6148
+ // `password=corr&horse&battery` redacted four characters and printed the rest, and
6149
+ // `DB_PASSWORD=Aa1:xyz` matched nothing at all because the run before the `:` was under the
6150
+ // four-character floor. A tail left sitting in the open is the outcome this module's header
6151
+ // calls worse than no redaction, because it reads as handled.
6152
+ //
6153
+ // So the separator role is decided by what follows rather than assumed: one of these characters
6154
+ // ends the value only when the next thing along is another `name=` / `name:` pair, which is what
6155
+ // an actual field separator is always followed by. `,OTHER=public` and `; other=1` still end it;
6156
+ // the `&` in the middle of a passphrase does not. Whitespace, quotes and brackets are unchanged
6157
+ // -- they end a value unconditionally, which is also what keeps this pattern from re-matching
6158
+ // the `[REDACTED:...]` placeholder it just wrote.
6159
+ ["generic_secret_assignment", /(?<=(?:password|passwd|secret|api[_-]?key|access[_-]?token|refresh[_-]?token|id[_-]?token)[a-z0-9_-]{0,64}["']?[ \t]{0,8}[:=][ \t]{0,8}["']?)(?:\\[^\n]|[^\s\\&;#,:'"[\]{}]|[&;#,:](?![ \t]*[A-Za-z_][A-Za-z0-9_.-]*[ \t]*[:=])){4,}/gi]
5928
6160
  ];
5929
6161
  function redactSecrets(text) {
5930
6162
  let count = 0;
@@ -6018,6 +6250,8 @@ export {
6018
6250
  normalizeDarwinSystemAlias,
6019
6251
  resolveIndexPath,
6020
6252
  toDisplayPath,
6253
+ displaySafeText,
6254
+ displaySafePath,
6021
6255
  sleepSync,
6022
6256
  isWindows,
6023
6257
  isCaseInsensitiveFs,
@@ -6049,6 +6283,7 @@ export {
6049
6283
  grepFilteredToEmptyNotice,
6050
6284
  countNoun,
6051
6285
  excludeTestsHiddenNote,
6286
+ countContentLines,
6052
6287
  escapeRegExp,
6053
6288
  windowsCmdQuoteArg,
6054
6289
  redactUrlQuery,
@@ -6067,9 +6302,13 @@ export {
6067
6302
  isWithinQuietHours,
6068
6303
  hookCommandFor,
6069
6304
  suggestPackageNames,
6305
+ detectSourceEncoding,
6306
+ decodeSource,
6307
+ encodeSource,
6070
6308
  fingerprintContent,
6071
6309
  shortFingerprint,
6072
6310
  fingerprintFile,
6311
+ fileIsAbsent,
6073
6312
  canonicalize,
6074
6313
  makeProjectAt,
6075
6314
  findProject,
@@ -6114,6 +6353,7 @@ export {
6114
6353
  assignFlatEndLines,
6115
6354
  propagateEndLinesToSymbols,
6116
6355
  findMatchingBraceEndLine,
6356
+ assignBraceBlockSpans,
6117
6357
  extractIni,
6118
6358
  _lineClosesQuote,
6119
6359
  _detectOpenQuote,
@@ -6142,8 +6382,8 @@ export {
6142
6382
 
6143
6383
  smol-toml/dist/date.js:
6144
6384
  smol-toml/dist/error.js:
6145
- smol-toml/dist/primitive.js:
6146
6385
  smol-toml/dist/util.js:
6386
+ smol-toml/dist/primitive.js:
6147
6387
  smol-toml/dist/extract.js:
6148
6388
  smol-toml/dist/struct.js:
6149
6389
  smol-toml/dist/parse.js: