@fairfox/polly 0.82.0 → 0.83.0

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 (45) hide show
  1. package/dist/cli/polly.js +22 -1
  2. package/dist/cli/polly.js.map +3 -3
  3. package/dist/tools/bdd/src/args.d.ts +21 -0
  4. package/dist/tools/bdd/src/bus-driver.d.ts +36 -0
  5. package/dist/tools/bdd/src/check-verify.d.ts +15 -0
  6. package/dist/tools/bdd/src/cli.d.ts +2 -0
  7. package/dist/tools/bdd/src/cli.js +701 -0
  8. package/dist/tools/bdd/src/cli.js.map +19 -0
  9. package/dist/tools/bdd/src/config.d.ts +9 -0
  10. package/dist/tools/bdd/src/extract.d.ts +2 -0
  11. package/dist/tools/bdd/src/index.d.ts +19 -0
  12. package/dist/tools/bdd/src/index.js +540 -0
  13. package/dist/tools/bdd/src/index.js.map +17 -0
  14. package/dist/tools/bdd/src/parse.d.ts +3 -0
  15. package/dist/tools/bdd/src/report.d.ts +6 -0
  16. package/dist/tools/bdd/src/run.d.ts +8 -0
  17. package/dist/tools/bdd/src/scaffold.d.ts +7 -0
  18. package/dist/tools/bdd/src/steps.d.ts +55 -0
  19. package/dist/tools/bdd/src/types.d.ts +145 -0
  20. package/dist/tools/bdd/src/witness.d.ts +23 -0
  21. package/dist/tools/gallery/src/cli.js +4 -3
  22. package/dist/tools/gallery/src/cli.js.map +3 -3
  23. package/dist/tools/mutate/src/cli.js +8 -1
  24. package/dist/tools/mutate/src/cli.js.map +3 -3
  25. package/dist/tools/quality/src/cli.js +304 -15
  26. package/dist/tools/quality/src/cli.js.map +6 -4
  27. package/dist/tools/quality/src/index.d.ts +2 -0
  28. package/dist/tools/quality/src/index.js +309 -15
  29. package/dist/tools/quality/src/index.js.map +6 -4
  30. package/dist/tools/quality/src/no-fixed-waits.d.ts +52 -0
  31. package/dist/tools/quality/src/no-tautology-ensures.d.ts +67 -0
  32. package/dist/tools/quality/src/plugins/core.d.ts +1 -1
  33. package/dist/tools/test/src/coverage-policy/cli.js +5 -1
  34. package/dist/tools/test/src/coverage-policy/cli.js.map +3 -3
  35. package/dist/tools/test/src/tiers/args.d.ts +5 -0
  36. package/dist/tools/test/src/tiers/cli.js +97 -23
  37. package/dist/tools/test/src/tiers/cli.js.map +9 -8
  38. package/dist/tools/test/src/tiers/index.d.ts +2 -1
  39. package/dist/tools/test/src/tiers/order.d.ts +25 -0
  40. package/dist/tools/test/src/tiers/types.d.ts +15 -0
  41. package/dist/tools/verify/src/cli.js +540 -15
  42. package/dist/tools/verify/src/cli.js.map +8 -4
  43. package/dist/tools/visualize/src/cli.js +17 -13
  44. package/dist/tools/visualize/src/cli.js.map +3 -3
  45. package/package.json +9 -16
@@ -842,9 +842,109 @@ async function checkNoAsCasting(options) {
842
842
  }
843
843
  return { violations, print: () => printViolations(violations) };
844
844
  }
845
- // tools/quality/src/no-require.ts
845
+ // tools/quality/src/no-fixed-waits.ts
846
846
  import { readFileSync as readFileSync2 } from "node:fs";
847
847
  import { Glob as Glob2 } from "bun";
848
+ var HINT = "wait on a real condition (poll loop, web-first assertion, microtask flush) or a sanctioned delay primitive";
849
+ var RULES = [
850
+ { pattern: /\.waitForTimeout\s*\(/, message: `waitForTimeout is a fixed sleep — ${HINT}` },
851
+ { pattern: /\bBun\.sleep\s*\(/, message: `Bun.sleep is a fixed sleep — ${HINT}` },
852
+ {
853
+ pattern: /\bsetTimeout\s*\(\s*(?:resolve|r|res|done)\s*,/,
854
+ message: `setTimeout resolving a promise is a fixed sleep — ${HINT}`
855
+ },
856
+ {
857
+ pattern: /\bsetTimeout\s*\(\s*\(\s*\)\s*=>\s*(?:resolve|r|res|done)\b/,
858
+ message: `setTimeout resolving a promise is a fixed sleep — ${HINT}`
859
+ },
860
+ {
861
+ pattern: /new\s+Promise\b.*\(\s*\(?\s*([A-Za-z_$][\w$]*)\s*\)?\s*=>.*\bsetTimeout\s*\(\s*\1\b/,
862
+ message: `Promise wrapping setTimeout is a fixed sleep — ${HINT}`
863
+ }
864
+ ];
865
+ var DEFAULT_EXCLUDE = ["node_modules", "dist", ".git", ".bun", "build", "coverage"];
866
+ function skipString(text, i) {
867
+ const quote = text[i];
868
+ if (quote !== '"' && quote !== "'" && quote !== "`")
869
+ return i;
870
+ let j = i + 1;
871
+ while (j < text.length && text[j] !== quote) {
872
+ if (text[j] === "\\")
873
+ j++;
874
+ j++;
875
+ }
876
+ return j;
877
+ }
878
+ function codeOnly(line) {
879
+ let out = "";
880
+ for (let i = 0;i < line.length; i++) {
881
+ const ch = line[i];
882
+ if (ch === '"' || ch === "'" || ch === "`") {
883
+ const end = skipString(line, i);
884
+ out += " ".repeat(end - i + 1);
885
+ i = end;
886
+ continue;
887
+ }
888
+ if (ch === "/" && line[i + 1] === "/")
889
+ break;
890
+ out += ch;
891
+ }
892
+ return out;
893
+ }
894
+ function scanText(content, filePath = "<text>") {
895
+ const violations = [];
896
+ const lines = content.split(`
897
+ `);
898
+ for (let i = 0;i < lines.length; i++) {
899
+ const line = lines[i] ?? "";
900
+ const trimmed = line.trim();
901
+ if (trimmed === "" || trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*")) {
902
+ continue;
903
+ }
904
+ const code = codeOnly(line);
905
+ const rule = RULES.find((r) => r.pattern.test(code));
906
+ if (rule)
907
+ violations.push({ file: filePath, line: i + 1, content: trimmed, message: rule.message });
908
+ }
909
+ return violations;
910
+ }
911
+ function isExcluded(relative3, excludeDirs, excludeFiles) {
912
+ if (relative3.split("/").some((s) => excludeDirs.has(s)))
913
+ return true;
914
+ const normalized = relative3.replace(/\\/g, "/");
915
+ return excludeFiles.some((suffix) => normalized.endsWith(suffix));
916
+ }
917
+ function printViolations2(violations) {
918
+ if (violations.length === 0) {
919
+ logger.log("[no-fixed-waits] ✅ No violations found.");
920
+ return;
921
+ }
922
+ logger.log(`[no-fixed-waits] ❌ ${violations.length} fixed-duration wait(s) found:
923
+ `);
924
+ for (const v of violations) {
925
+ logger.log(` ${v.file}:${v.line}`);
926
+ logger.log(` ${v.content}`);
927
+ logger.log(` \uD83D\uDCA1 ${v.message}`);
928
+ logger.log("");
929
+ }
930
+ }
931
+ async function checkNoFixedWaits(options) {
932
+ const { rootDir } = options;
933
+ const excludeDirs = new Set(options.exclude ?? DEFAULT_EXCLUDE);
934
+ const excludeFiles = [...options.excludeFiles ?? [], "no-fixed-waits.ts"];
935
+ const glob = new Glob2(options.filePatterns ?? "**/*.{ts,tsx}");
936
+ const violations = [];
937
+ for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
938
+ const relative3 = file.replace(`${rootDir}/`, "");
939
+ if (isExcluded(relative3, excludeDirs, excludeFiles))
940
+ continue;
941
+ violations.push(...scanText(readFileSync2(file, "utf-8"), relative3));
942
+ }
943
+ return { violations, print: () => printViolations2(violations) };
944
+ }
945
+ // tools/quality/src/no-require.ts
946
+ import { readFileSync as readFileSync3 } from "node:fs";
947
+ import { Glob as Glob3 } from "bun";
848
948
  function isLineRequireClean(line) {
849
949
  if (!line.includes("require")) {
850
950
  return true;
@@ -912,7 +1012,7 @@ async function checkNoRequire(options) {
912
1012
  const rootDir = options.rootDir;
913
1013
  const excludeDirs = new Set(options.exclude ?? ["node_modules", "dist", ".git", ".bun"]);
914
1014
  const pattern = options.filePatterns ?? "**/*.{ts,tsx}";
915
- const glob = new Glob2(pattern);
1015
+ const glob = new Glob3(pattern);
916
1016
  const violations = [];
917
1017
  for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
918
1018
  const relative3 = file.replace(`${rootDir}/`, "");
@@ -920,7 +1020,7 @@ async function checkNoRequire(options) {
920
1020
  if (segments.some((s) => excludeDirs.has(s))) {
921
1021
  continue;
922
1022
  }
923
- const content = readFileSync2(file, "utf-8");
1023
+ const content = readFileSync3(file, "utf-8");
924
1024
  violations.push(...findRequireViolations(relative3, content));
925
1025
  }
926
1026
  return {
@@ -928,6 +1028,157 @@ async function checkNoRequire(options) {
928
1028
  print: () => printRequireViolations(violations)
929
1029
  };
930
1030
  }
1031
+ // tools/quality/src/no-tautology-ensures.ts
1032
+ import { readFileSync as readFileSync4 } from "node:fs";
1033
+ import { Glob as Glob4 } from "bun";
1034
+ var DEFAULT_PRIMITIVES = ["ensures", "requires"];
1035
+ var DEFAULT_EXCLUDE2 = [
1036
+ "node_modules",
1037
+ "dist",
1038
+ ".git",
1039
+ ".bun",
1040
+ "coverage",
1041
+ "specs",
1042
+ "tests",
1043
+ "__tests__",
1044
+ "examples"
1045
+ ];
1046
+ var LITERAL = /^(true|false|null|undefined|\d+(\.\d+)?|"[^"]*"|'[^']*'|`[^`]*`)$/;
1047
+ function tautologyReason(predicate) {
1048
+ const trimmed = predicate.trim();
1049
+ if (LITERAL.test(trimmed))
1050
+ return `literal '${trimmed}'`;
1051
+ const cmp = trimmed.match(/^(.+?)\s*(===|!==|==|!=)\s*(.+)$/);
1052
+ if (cmp) {
1053
+ const lhs = cmp[1]?.trim() ?? "";
1054
+ const rhs = cmp[3]?.trim() ?? "";
1055
+ if (LITERAL.test(lhs) && LITERAL.test(rhs))
1056
+ return `literal-vs-literal '${trimmed}'`;
1057
+ }
1058
+ return;
1059
+ }
1060
+ function skipString2(text, i) {
1061
+ const quote = text[i];
1062
+ if (quote !== '"' && quote !== "'" && quote !== "`")
1063
+ return i;
1064
+ let j = i + 1;
1065
+ while (j < text.length && text[j] !== quote) {
1066
+ if (text[j] === "\\")
1067
+ j++;
1068
+ j++;
1069
+ }
1070
+ return j;
1071
+ }
1072
+ function findClosingParen(text, openIdx) {
1073
+ let depth = 0;
1074
+ for (let i = openIdx;i < text.length; i++) {
1075
+ const ch = text[i];
1076
+ if (ch === "(") {
1077
+ depth++;
1078
+ } else if (ch === ")") {
1079
+ if (--depth === 0)
1080
+ return i;
1081
+ } else {
1082
+ i = skipString2(text, i);
1083
+ }
1084
+ }
1085
+ return -1;
1086
+ }
1087
+ function splitTopLevelArgs(args) {
1088
+ const parts = [];
1089
+ let depth = 0;
1090
+ let start = 0;
1091
+ for (let i = 0;i < args.length; i++) {
1092
+ const ch = args[i];
1093
+ if (ch === "(" || ch === "[" || ch === "{") {
1094
+ depth++;
1095
+ } else if (ch === ")" || ch === "]" || ch === "}") {
1096
+ depth--;
1097
+ } else if (ch === "," && depth === 0) {
1098
+ parts.push(args.slice(start, i));
1099
+ start = i + 1;
1100
+ } else {
1101
+ i = skipString2(args, i);
1102
+ }
1103
+ }
1104
+ parts.push(args.slice(start));
1105
+ return parts.map((p) => p.trim());
1106
+ }
1107
+ function isFileExcluded2(relative3, excludeDirs, excludeFiles) {
1108
+ const segments = relative3.split("/");
1109
+ if (segments.some((s) => excludeDirs.has(s)))
1110
+ return true;
1111
+ const basename = segments[segments.length - 1] ?? "";
1112
+ return excludeFiles.has(basename) || excludeFiles.has(relative3);
1113
+ }
1114
+ function isNonCall(line, lineBefore) {
1115
+ const isImport = /\b(import|export)\b/.test(line) && line.includes("{") && !line.includes(";");
1116
+ const isFrom = /\b(import|export)\b.*\bfrom\b/.test(line);
1117
+ return isImport || isFrom || lineBefore.includes("//");
1118
+ }
1119
+ function findViolations2(relative3, content, callPattern) {
1120
+ const results = [];
1121
+ callPattern.lastIndex = 0;
1122
+ let match = callPattern.exec(content);
1123
+ while (match !== null) {
1124
+ const current = match;
1125
+ match = callPattern.exec(content);
1126
+ const openIdx = current.index + current[0].length - 1;
1127
+ const lineStart = content.lastIndexOf(`
1128
+ `, current.index) + 1;
1129
+ const lineEnd = content.indexOf(`
1130
+ `, current.index);
1131
+ const line = content.slice(lineStart, lineEnd === -1 ? content.length : lineEnd);
1132
+ if (isNonCall(line, content.slice(lineStart, current.index)))
1133
+ continue;
1134
+ const closeIdx = findClosingParen(content, openIdx);
1135
+ if (closeIdx === -1)
1136
+ continue;
1137
+ const predicate = splitTopLevelArgs(content.slice(openIdx + 1, closeIdx))[0];
1138
+ const reason = predicate ? tautologyReason(predicate) : undefined;
1139
+ if (reason === undefined)
1140
+ continue;
1141
+ results.push({
1142
+ file: relative3,
1143
+ line: content.slice(0, current.index).split(`
1144
+ `).length,
1145
+ content: line.trim(),
1146
+ reason: `${current[1] ?? "ensures"}(...) predicate is a ${reason}`
1147
+ });
1148
+ }
1149
+ return results;
1150
+ }
1151
+ function printViolations3(violations) {
1152
+ if (violations.length === 0) {
1153
+ logger.log("[no-tautology-ensures] ✅ No violations found.");
1154
+ return;
1155
+ }
1156
+ logger.log(`[no-tautology-ensures] ❌ ${violations.length} violation(s) found:
1157
+ `);
1158
+ for (const v of violations) {
1159
+ logger.log(` ${v.file}:${v.line}`);
1160
+ logger.log(` ${v.content}`);
1161
+ logger.log(` \uD83D\uDCA1 ${v.reason}`);
1162
+ logger.log("");
1163
+ }
1164
+ logger.log("[no-tautology-ensures] A verify predicate must reference state — a literal asserts nothing.");
1165
+ }
1166
+ async function checkNoTautologyEnsures(options) {
1167
+ const { rootDir } = options;
1168
+ const excludeDirs = new Set(options.exclude ?? DEFAULT_EXCLUDE2);
1169
+ const excludeFiles = new Set([...options.excludeFiles ?? [], "no-tautology-ensures.ts"]);
1170
+ const primitives = options.primitives ?? DEFAULT_PRIMITIVES;
1171
+ const callPattern = new RegExp(`\\b(${primitives.join("|")})\\s*\\(`, "g");
1172
+ const glob = new Glob4(options.filePatterns ?? "**/*.{ts,tsx}");
1173
+ const violations = [];
1174
+ for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
1175
+ const relative3 = file.replace(`${rootDir}/`, "");
1176
+ if (isFileExcluded2(relative3, excludeDirs, excludeFiles))
1177
+ continue;
1178
+ violations.push(...findViolations2(relative3, readFileSync4(file, "utf-8"), callPattern));
1179
+ }
1180
+ return { violations, print: () => printViolations3(violations) };
1181
+ }
931
1182
  // tools/quality/src/secrets.ts
932
1183
  import { readFile } from "node:fs/promises";
933
1184
  import { join as join3 } from "node:path";
@@ -1463,7 +1714,7 @@ import { join as join11 } from "node:path";
1463
1714
 
1464
1715
  // tools/quality/src/plugins/core.ts
1465
1716
  import { join as join10 } from "node:path";
1466
- import { Glob as Glob5 } from "bun";
1717
+ import { Glob as Glob7 } from "bun";
1467
1718
 
1468
1719
  // tools/quality/src/plugins/cliche-checks.ts
1469
1720
  import { readdir as readdir3 } from "node:fs/promises";
@@ -1886,7 +2137,7 @@ var additionalCoreChecks = [
1886
2137
  // tools/quality/src/plugins/extra-checks.ts
1887
2138
  import { readdir as readdir5 } from "node:fs/promises";
1888
2139
  import { join as join8, relative as relative5 } from "node:path";
1889
- import { Glob as Glob3 } from "bun";
2140
+ import { Glob as Glob5 } from "bun";
1890
2141
  var SKIP_DIRS_DEFAULT2 = ["node_modules", ".git", "dist", ".bun", ".cache"];
1891
2142
  function isCommentLine2(trimmed) {
1892
2143
  return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
@@ -2024,7 +2275,7 @@ function buildHookRegex(banned) {
2024
2275
  }
2025
2276
  function isAllowedByGlob(rel, allowedFiles) {
2026
2277
  for (const pattern of allowedFiles) {
2027
- if (new Glob3(pattern).match(rel))
2278
+ if (new Glob5(pattern).match(rel))
2028
2279
  return true;
2029
2280
  }
2030
2281
  return false;
@@ -2091,7 +2342,7 @@ var DEFAULT_TYPOGRAPHIC = {
2091
2342
  };
2092
2343
  function fileMatchesAnyGlob(rel, globs) {
2093
2344
  for (const g of globs) {
2094
- if (new Glob3(g).match(rel))
2345
+ if (new Glob5(g).match(rel))
2095
2346
  return true;
2096
2347
  }
2097
2348
  return false;
@@ -2159,7 +2410,7 @@ var extraCoreChecks = [
2159
2410
  // tools/quality/src/plugins/import-checks.ts
2160
2411
  import { readdir as readdir6 } from "node:fs/promises";
2161
2412
  import { join as join9, relative as relative6 } from "node:path";
2162
- import { Glob as Glob4 } from "bun";
2413
+ import { Glob as Glob6 } from "bun";
2163
2414
  var SKIP_DIRS_DEFAULT3 = ["node_modules", ".git", "dist", ".bun", ".cache"];
2164
2415
  function isCommentLine3(trimmed) {
2165
2416
  return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
@@ -2186,7 +2437,7 @@ async function walkScannableFiles2(dir, skipDirs, out) {
2186
2437
  }
2187
2438
  function isAllowedByGlob2(rel, globs) {
2188
2439
  for (const g of globs) {
2189
- if (new Glob4(g).match(rel))
2440
+ if (new Glob6(g).match(rel))
2190
2441
  return true;
2191
2442
  }
2192
2443
  return false;
@@ -2414,7 +2665,7 @@ async function runTscFor(packagePath, rootDir) {
2414
2665
  async function findWorkspaces(rootDir, patterns) {
2415
2666
  const out = [];
2416
2667
  for (const pattern of patterns) {
2417
- const glob = new Glob4(`${pattern}/tsconfig.json`);
2668
+ const glob = new Glob6(`${pattern}/tsconfig.json`);
2418
2669
  for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
2419
2670
  out.push(file.replace(/\/tsconfig\.json$/, ""));
2420
2671
  }
@@ -2472,7 +2723,7 @@ async function scanFiles(rootDir, cfg) {
2472
2723
  const excludePackages = new Set(cfg.excludePackages ?? []);
2473
2724
  const excludeFiles = new Set(cfg.excludeFiles ?? []);
2474
2725
  const pattern = cfg.filePatterns ?? "**/*.{ts,tsx}";
2475
- const glob = new Glob5(pattern);
2726
+ const glob = new Glob7(pattern);
2476
2727
  const out = [];
2477
2728
  for await (const file of glob.scan({ cwd: rootDir, absolute: true })) {
2478
2729
  const rel = file.replace(`${rootDir}/`, "");
@@ -2527,6 +2778,42 @@ var noRequire = {
2527
2778
  };
2528
2779
  }
2529
2780
  };
2781
+ var noTautologyEnsures = {
2782
+ id: "polly:no-tautology-ensures",
2783
+ description: "Ban ensures/requires whose predicate is a literal (asserts nothing)",
2784
+ filesRead: (cfg, root) => scanFiles(root, resolveScanConfig(cfg)),
2785
+ run: async ({ rootDir, config }) => {
2786
+ const cfg = resolveScanConfig(config);
2787
+ const result = await checkNoTautologyEnsures({
2788
+ rootDir,
2789
+ ...cfg.exclude ? { exclude: cfg.exclude } : {},
2790
+ ...cfg.excludeFiles ? { excludeFiles: cfg.excludeFiles } : {},
2791
+ ...cfg.filePatterns ? { filePatterns: cfg.filePatterns } : {}
2792
+ });
2793
+ return {
2794
+ ok: result.violations.length === 0,
2795
+ messages: result.violations.map((v) => `${v.file}:${v.line}: ${v.content} — ${v.reason}`)
2796
+ };
2797
+ }
2798
+ };
2799
+ var noFixedWaits = {
2800
+ id: "polly:no-fixed-waits",
2801
+ description: "Ban fixed-duration sleeps (waitForTimeout / Bun.sleep / promise-wrapped setTimeout)",
2802
+ filesRead: (cfg, root) => scanFiles(root, resolveScanConfig(cfg)),
2803
+ run: async ({ rootDir, config }) => {
2804
+ const cfg = resolveScanConfig(config);
2805
+ const result = await checkNoFixedWaits({
2806
+ rootDir,
2807
+ exclude: cfg.exclude ?? DEFAULT_EXCLUDES,
2808
+ ...cfg.excludeFiles ? { excludeFiles: cfg.excludeFiles } : {},
2809
+ ...cfg.filePatterns ? { filePatterns: cfg.filePatterns } : {}
2810
+ });
2811
+ return {
2812
+ ok: result.violations.length === 0,
2813
+ messages: result.violations.map((v) => `${v.file}:${v.line}: ${v.content} — ${v.message}`)
2814
+ };
2815
+ }
2816
+ };
2530
2817
  var secrets = {
2531
2818
  id: "polly:secrets",
2532
2819
  description: "Run `gitleaks detect` against the working tree",
@@ -2588,13 +2875,15 @@ var gitignoreCrossCheck = {
2588
2875
  };
2589
2876
  }
2590
2877
  };
2591
- var POLLY_CORE_VERSION = "0.48.0";
2878
+ var POLLY_CORE_VERSION = "0.49.0";
2592
2879
  var pollyCorePlugin = {
2593
2880
  name: "polly",
2594
2881
  version: POLLY_CORE_VERSION,
2595
2882
  checks: [
2596
2883
  noAsCasting,
2597
2884
  noRequire,
2885
+ noTautologyEnsures,
2886
+ noFixedWaits,
2598
2887
  secrets,
2599
2888
  gitignoreCrossCheck,
2600
2889
  ...additionalCoreChecks,
@@ -2625,14 +2914,14 @@ async function loadQualityConfig(rootDir, explicitPath) {
2625
2914
  // tools/quality/src/plugins/polly-ui.ts
2626
2915
  import { readdir as readdir7 } from "node:fs/promises";
2627
2916
  import { join as join12, relative as relative7 } from "node:path";
2628
- import { Glob as Glob6 } from "bun";
2917
+ import { Glob as Glob8 } from "bun";
2629
2918
  var SKIP_DIRS_DEFAULT4 = ["node_modules", ".git", "dist", ".bun", ".cache"];
2630
2919
  function isCommentLine4(trimmed) {
2631
2920
  return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
2632
2921
  }
2633
2922
  function isAllowedByGlob3(rel, globs) {
2634
2923
  for (const g of globs) {
2635
- if (new Glob6(g).match(rel))
2924
+ if (new Glob8(g).match(rel))
2636
2925
  return true;
2637
2926
  }
2638
2927
  return false;
@@ -3050,4 +3339,4 @@ switch (subcommand) {
3050
3339
  }
3051
3340
  process.exit(exitCode);
3052
3341
 
3053
- //# debugId=BE14883E9B3EB87B64756E2164756E21
3342
+ //# debugId=6610E9614AC8E6B464756E2164756E21