truecourse 0.7.0-next.7 → 0.7.0-next.9

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.
package/server.mjs CHANGED
@@ -109,8 +109,8 @@ var require_package = __commonJS({
109
109
  // node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
110
110
  var require_main = __commonJS({
111
111
  "node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
112
- var fs67 = __require("fs");
113
- var path74 = __require("path");
112
+ var fs68 = __require("fs");
113
+ var path75 = __require("path");
114
114
  var os10 = __require("os");
115
115
  var crypto6 = __require("crypto");
116
116
  var packageJson = require_package();
@@ -218,7 +218,7 @@ var require_main = __commonJS({
218
218
  if (options && options.path && options.path.length > 0) {
219
219
  if (Array.isArray(options.path)) {
220
220
  for (const filepath of options.path) {
221
- if (fs67.existsSync(filepath)) {
221
+ if (fs68.existsSync(filepath)) {
222
222
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
223
223
  }
224
224
  }
@@ -226,15 +226,15 @@ var require_main = __commonJS({
226
226
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
227
227
  }
228
228
  } else {
229
- possibleVaultPath = path74.resolve(process.cwd(), ".env.vault");
229
+ possibleVaultPath = path75.resolve(process.cwd(), ".env.vault");
230
230
  }
231
- if (fs67.existsSync(possibleVaultPath)) {
231
+ if (fs68.existsSync(possibleVaultPath)) {
232
232
  return possibleVaultPath;
233
233
  }
234
234
  return null;
235
235
  }
236
236
  function _resolveHome(envPath) {
237
- return envPath[0] === "~" ? path74.join(os10.homedir(), envPath.slice(1)) : envPath;
237
+ return envPath[0] === "~" ? path75.join(os10.homedir(), envPath.slice(1)) : envPath;
238
238
  }
239
239
  function _configVault(options) {
240
240
  const debug2 = Boolean(options && options.debug);
@@ -251,7 +251,7 @@ var require_main = __commonJS({
251
251
  return { parsed };
252
252
  }
253
253
  function configDotenv(options) {
254
- const dotenvPath = path74.resolve(process.cwd(), ".env");
254
+ const dotenvPath = path75.resolve(process.cwd(), ".env");
255
255
  let encoding = "utf8";
256
256
  const debug2 = Boolean(options && options.debug);
257
257
  const quiet = options && "quiet" in options ? options.quiet : true;
@@ -275,13 +275,13 @@ var require_main = __commonJS({
275
275
  }
276
276
  let lastError;
277
277
  const parsedAll = {};
278
- for (const path75 of optionPaths) {
278
+ for (const path76 of optionPaths) {
279
279
  try {
280
- const parsed = DotenvModule.parse(fs67.readFileSync(path75, { encoding }));
280
+ const parsed = DotenvModule.parse(fs68.readFileSync(path76, { encoding }));
281
281
  DotenvModule.populate(parsedAll, parsed, options);
282
282
  } catch (e) {
283
283
  if (debug2) {
284
- _debug(`Failed to load ${path75} ${e.message}`);
284
+ _debug(`Failed to load ${path76} ${e.message}`);
285
285
  }
286
286
  lastError = e;
287
287
  }
@@ -296,7 +296,7 @@ var require_main = __commonJS({
296
296
  const shortPaths = [];
297
297
  for (const filePath of optionPaths) {
298
298
  try {
299
- const relative2 = path74.relative(process.cwd(), filePath);
299
+ const relative2 = path75.relative(process.cwd(), filePath);
300
300
  shortPaths.push(relative2);
301
301
  } catch (e) {
302
302
  if (debug2) {
@@ -9509,11 +9509,11 @@ var require_mime_types = __commonJS({
9509
9509
  }
9510
9510
  return exts[0];
9511
9511
  }
9512
- function lookup(path74) {
9513
- if (!path74 || typeof path74 !== "string") {
9512
+ function lookup(path75) {
9513
+ if (!path75 || typeof path75 !== "string") {
9514
9514
  return false;
9515
9515
  }
9516
- var extension2 = extname("x." + path74).toLowerCase().substr(1);
9516
+ var extension2 = extname("x." + path75).toLowerCase().substr(1);
9517
9517
  if (!extension2) {
9518
9518
  return false;
9519
9519
  }
@@ -16491,11 +16491,11 @@ var require_server = __commonJS({
16491
16491
  * @protected
16492
16492
  */
16493
16493
  _computePath(options) {
16494
- let path74 = (options.path || "/engine.io").replace(/\/$/, "");
16494
+ let path75 = (options.path || "/engine.io").replace(/\/$/, "");
16495
16495
  if (options.addTrailingSlash !== false) {
16496
- path74 += "/";
16496
+ path75 += "/";
16497
16497
  }
16498
- return path74;
16498
+ return path75;
16499
16499
  }
16500
16500
  /**
16501
16501
  * Returns a list of available transports for upgrade given a certain transport.
@@ -16994,10 +16994,10 @@ var require_server = __commonJS({
16994
16994
  * @param {Object} options
16995
16995
  */
16996
16996
  attach(server, options = {}) {
16997
- const path74 = this._computePath(options);
16997
+ const path75 = this._computePath(options);
16998
16998
  const destroyUpgradeTimeout = options.destroyUpgradeTimeout || 1e3;
16999
16999
  function check(req) {
17000
- return path74 === req.url.slice(0, path74.length);
17000
+ return path75 === req.url.slice(0, path75.length);
17001
17001
  }
17002
17002
  const listeners = server.listeners("request").slice(0);
17003
17003
  server.removeAllListeners("request");
@@ -17005,7 +17005,7 @@ var require_server = __commonJS({
17005
17005
  server.on("listening", this.init.bind(this));
17006
17006
  server.on("request", (req, res) => {
17007
17007
  if (check(req)) {
17008
- debug2('intercepting request for path "%s"', path74);
17008
+ debug2('intercepting request for path "%s"', path75);
17009
17009
  this.handleRequest(req, res);
17010
17010
  } else {
17011
17011
  let i = 0;
@@ -17844,8 +17844,8 @@ var require_userver = __commonJS({
17844
17844
  * @param options
17845
17845
  */
17846
17846
  attach(app, options = {}) {
17847
- const path74 = this._computePath(options);
17848
- app.any(path74, this.handleRequest.bind(this)).ws(path74, {
17847
+ const path75 = this._computePath(options);
17848
+ app.any(path75, this.handleRequest.bind(this)).ws(path75, {
17849
17849
  compression: options.compression,
17850
17850
  idleTimeout: options.idleTimeout,
17851
17851
  maxBackpressure: options.maxBackpressure,
@@ -22270,7 +22270,7 @@ var require_dist2 = __commonJS({
22270
22270
  var zlib_1 = __require("zlib");
22271
22271
  var accepts = require_accepts();
22272
22272
  var stream_1 = __require("stream");
22273
- var path74 = __require("path");
22273
+ var path75 = __require("path");
22274
22274
  var engine_io_1 = require_engine_io();
22275
22275
  var client_1 = require_client();
22276
22276
  var events_1 = __require("events");
@@ -22465,7 +22465,7 @@ var require_dist2 = __commonJS({
22465
22465
  res.writeHeader("cache-control", "public, max-age=0");
22466
22466
  res.writeHeader("content-type", "application/" + (isMap ? "json" : "javascript") + "; charset=utf-8");
22467
22467
  res.writeHeader("etag", expectedEtag);
22468
- const filepath = path74.join(__dirname, "../client-dist/", filename);
22468
+ const filepath = path75.join(__dirname, "../client-dist/", filename);
22469
22469
  (0, uws_1.serveFile)(res, filepath);
22470
22470
  });
22471
22471
  }
@@ -22547,7 +22547,7 @@ var require_dist2 = __commonJS({
22547
22547
  * @private
22548
22548
  */
22549
22549
  static sendFile(filename, req, res) {
22550
- const readStream = (0, fs_1.createReadStream)(path74.join(__dirname, "../client-dist/", filename));
22550
+ const readStream = (0, fs_1.createReadStream)(path75.join(__dirname, "../client-dist/", filename));
22551
22551
  const encoding = accepts(req).encodings(["br", "gzip", "deflate"]);
22552
22552
  const onError2 = (err) => {
22553
22553
  if (err) {
@@ -23506,8 +23506,8 @@ var init_parseUtil = __esm({
23506
23506
  init_errors();
23507
23507
  init_en();
23508
23508
  makeIssue = (params) => {
23509
- const { data, path: path74, errorMaps, issueData } = params;
23510
- const fullPath = [...path74, ...issueData.path || []];
23509
+ const { data, path: path75, errorMaps, issueData } = params;
23510
+ const fullPath = [...path75, ...issueData.path || []];
23511
23511
  const fullIssue = {
23512
23512
  ...issueData,
23513
23513
  path: fullPath
@@ -23815,11 +23815,11 @@ var init_types = __esm({
23815
23815
  init_parseUtil();
23816
23816
  init_util();
23817
23817
  ParseInputLazyPath = class {
23818
- constructor(parent, value, path74, key4) {
23818
+ constructor(parent, value, path75, key4) {
23819
23819
  this._cachedPath = [];
23820
23820
  this.parent = parent;
23821
23821
  this.data = value;
23822
- this._path = path74;
23822
+ this._path = path75;
23823
23823
  this._key = key4;
23824
23824
  }
23825
23825
  get path() {
@@ -28410,11 +28410,8 @@ var init_guard = __esm({
28410
28410
  });
28411
28411
 
28412
28412
  // packages/shared/dist/spec/overlap-resolution.js
28413
- function coveringRelationInAreas(relations, a, b, areas) {
28414
- return relations.find((r) => {
28415
- const samePair = r.older === a && r.newer === b || r.older === b && r.newer === a;
28416
- return samePair && (r.scope === void 0 || areas.includes(r.scope));
28417
- });
28413
+ function normalizeQuote(text4) {
28414
+ return text4.replace(/[`*_~]/g, "").toLowerCase().replace(/\s+/g, " ").trim();
28418
28415
  }
28419
28416
  function dedupeCrossAreaOverlaps(entries) {
28420
28417
  const byPair = /* @__PURE__ */ new Map();
@@ -28488,9 +28485,23 @@ function dedupeCrossAreaOverlaps(entries) {
28488
28485
  });
28489
28486
  return merged;
28490
28487
  }
28488
+ function resolutionMatchesConflict(r, a, b, sections) {
28489
+ if (!samePair(r.docA, r.docB, a, b))
28490
+ return false;
28491
+ const rSide = (doc) => doc === r.docA ? { anchor: r.anchorA, quote: r.quoteA } : { anchor: r.anchorB, quote: r.quoteB };
28492
+ const cSide = (doc) => (sections ?? []).find((s) => s.doc === doc);
28493
+ const bothHaveQuotes = !!r.quoteA && !!r.quoteB && !!cSide(a)?.quote && !!cSide(b)?.quote;
28494
+ if (bothHaveQuotes) {
28495
+ const quoteMatch = (doc) => normalizeQuote(rSide(doc).quote ?? "") === normalizeQuote(cSide(doc)?.quote ?? "");
28496
+ return quoteMatch(a) && quoteMatch(b);
28497
+ }
28498
+ const anchorMatch = (doc) => anchorKey(rSide(doc).anchor) === anchorKey(cSide(doc)?.heading);
28499
+ return anchorMatch(a) && anchorMatch(b);
28500
+ }
28501
+ function matchResolution(decisions, a, b, sections) {
28502
+ return (decisions.conflictResolutions ?? []).find((r) => resolutionMatchesConflict(r, a, b, sections));
28503
+ }
28491
28504
  function buildCorpusConflicts(corpus, decisions) {
28492
- const userRelations = decisions.relations ?? [];
28493
- const effectiveRels = [...corpus.relations, ...userRelations];
28494
28505
  const excludes = new Set(decisions.manualExcludes ?? []);
28495
28506
  const entries = [];
28496
28507
  for (const area of corpus.areas)
@@ -28500,43 +28511,39 @@ function buildCorpusConflicts(corpus, decisions) {
28500
28511
  const flagged = [];
28501
28512
  for (const m of mergedOverlaps) {
28502
28513
  const [a, b] = m.overlap.docs;
28503
- const relation = coveringRelationInAreas(effectiveRels, a, b, m.areas);
28504
- const userRelation = coveringRelationInAreas(userRelations, a, b, m.areas);
28514
+ const sections = m.overlap.sections ? [...m.overlap.sections] : void 0;
28505
28515
  const excludedRef = excludes.has(a) ? a : excludes.has(b) ? b : void 0;
28516
+ const resolution = matchResolution(decisions, a, b, sections);
28506
28517
  flagged.push({
28507
28518
  area: m.area,
28508
28519
  areas: m.areas,
28509
28520
  a,
28510
28521
  b,
28511
28522
  note: m.overlap.note ?? "",
28512
- resolved: relation !== void 0 || excludedRef !== void 0,
28513
- synthesized: false,
28514
- ...relation ? { relation } : {},
28515
- ...userRelation ? { userRelation } : {},
28516
- ...excludedRef ? { excludedRef } : {}
28523
+ ...sections ? { sections } : {},
28524
+ resolved: excludedRef !== void 0 || resolution !== void 0,
28525
+ ...excludedRef ? { excludedRef } : {},
28526
+ ...resolution ? { resolution } : {}
28517
28527
  });
28518
28528
  }
28519
- const coversFlagged = (r) => flagged.some((o) => {
28520
- const samePair = o.a === r.older && o.b === r.newer || o.a === r.newer && o.b === r.older;
28521
- return samePair && (r.scope === void 0 || o.areas.includes(r.scope));
28522
- });
28523
- const synthesized = userRelations.filter((r) => !coversFlagged(r)).map((r) => ({
28524
- area: r.scope ?? "",
28525
- areas: r.scope ? [r.scope] : [],
28526
- a: r.older,
28527
- b: r.newer,
28528
- note: r.note ?? "",
28529
- resolved: true,
28530
- synthesized: true,
28531
- relation: r,
28532
- userRelation: r
28533
- }));
28534
- return [...flagged, ...synthesized];
28529
+ return flagged;
28535
28530
  }
28536
28531
  function openConflicts(corpus, decisions) {
28537
28532
  return buildCorpusConflicts(corpus, decisions).filter((c) => !c.resolved);
28538
28533
  }
28539
- var PREAMBLE_PTR, NUL, unorderedPairKey, sectionPointerKeys, preambleCount;
28534
+ function suppressedClaims(corpus, decisions) {
28535
+ const out = [];
28536
+ for (const c of buildCorpusConflicts(corpus, decisions)) {
28537
+ const r = c.resolution;
28538
+ if (!r || r.verdict === "dismissed")
28539
+ continue;
28540
+ const loser = r.verdict === "a" ? { doc: r.docB, anchor: r.anchorB, quote: r.quoteB } : { doc: r.docA, anchor: r.anchorA, quote: r.quoteA };
28541
+ if (loser.quote && loser.quote.trim())
28542
+ out.push({ doc: loser.doc, anchor: loser.anchor, quote: loser.quote });
28543
+ }
28544
+ return out;
28545
+ }
28546
+ var PREAMBLE_PTR, NUL, unorderedPairKey, sectionPointerKeys, preambleCount, samePair, anchorKey;
28540
28547
  var init_overlap_resolution = __esm({
28541
28548
  "packages/shared/dist/spec/overlap-resolution.js"() {
28542
28549
  "use strict";
@@ -28545,6 +28552,8 @@ var init_overlap_resolution = __esm({
28545
28552
  unorderedPairKey = (a, b) => a < b ? `${a}${NUL}${b}` : `${b}${NUL}${a}`;
28546
28553
  sectionPointerKeys = (ov) => (ov.sections ?? []).map((s) => `${s.doc}${NUL}${s.heading ?? PREAMBLE_PTR}`);
28547
28554
  preambleCount = (ov) => (ov.sections ?? []).filter((s) => s.heading === null || s.heading === void 0).length;
28555
+ samePair = (a1, b1, a2, b2) => a1 === a2 && b1 === b2 || a1 === b2 && b1 === a2;
28556
+ anchorKey = (h) => h === null || h === void 0 ? null : h.replace(/[`*_~]/g, "").trim().toLowerCase();
28548
28557
  }
28549
28558
  });
28550
28559
 
@@ -28853,7 +28862,7 @@ var require_ignore = __commonJS({
28853
28862
  // path matching.
28854
28863
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
28855
28864
  // @returns {TestResult} true if a file is ignored
28856
- test(path74, checkUnignored, mode) {
28865
+ test(path75, checkUnignored, mode) {
28857
28866
  let ignored = false;
28858
28867
  let unignored = false;
28859
28868
  let matchedRule;
@@ -28862,7 +28871,7 @@ var require_ignore = __commonJS({
28862
28871
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
28863
28872
  return;
28864
28873
  }
28865
- const matched = rule[mode].test(path74);
28874
+ const matched = rule[mode].test(path75);
28866
28875
  if (!matched) {
28867
28876
  return;
28868
28877
  }
@@ -28883,17 +28892,17 @@ var require_ignore = __commonJS({
28883
28892
  var throwError2 = (message, Ctor) => {
28884
28893
  throw new Ctor(message);
28885
28894
  };
28886
- var checkPath = (path74, originalPath, doThrow) => {
28887
- if (!isString(path74)) {
28895
+ var checkPath = (path75, originalPath, doThrow) => {
28896
+ if (!isString(path75)) {
28888
28897
  return doThrow(
28889
28898
  `path must be a string, but got \`${originalPath}\``,
28890
28899
  TypeError
28891
28900
  );
28892
28901
  }
28893
- if (!path74) {
28902
+ if (!path75) {
28894
28903
  return doThrow(`path must not be empty`, TypeError);
28895
28904
  }
28896
- if (checkPath.isNotRelative(path74)) {
28905
+ if (checkPath.isNotRelative(path75)) {
28897
28906
  const r = "`path.relative()`d";
28898
28907
  return doThrow(
28899
28908
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -28902,7 +28911,7 @@ var require_ignore = __commonJS({
28902
28911
  }
28903
28912
  return true;
28904
28913
  };
28905
- var isNotRelative = (path74) => REGEX_TEST_INVALID_PATH.test(path74);
28914
+ var isNotRelative = (path75) => REGEX_TEST_INVALID_PATH.test(path75);
28906
28915
  checkPath.isNotRelative = isNotRelative;
28907
28916
  checkPath.convert = (p) => p;
28908
28917
  var Ignore = class {
@@ -28932,19 +28941,19 @@ var require_ignore = __commonJS({
28932
28941
  }
28933
28942
  // @returns {TestResult}
28934
28943
  _test(originalPath, cache3, checkUnignored, slices) {
28935
- const path74 = originalPath && checkPath.convert(originalPath);
28944
+ const path75 = originalPath && checkPath.convert(originalPath);
28936
28945
  checkPath(
28937
- path74,
28946
+ path75,
28938
28947
  originalPath,
28939
28948
  this._strictPathCheck ? throwError2 : RETURN_FALSE
28940
28949
  );
28941
- return this._t(path74, cache3, checkUnignored, slices);
28950
+ return this._t(path75, cache3, checkUnignored, slices);
28942
28951
  }
28943
- checkIgnore(path74) {
28944
- if (!REGEX_TEST_TRAILING_SLASH.test(path74)) {
28945
- return this.test(path74);
28952
+ checkIgnore(path75) {
28953
+ if (!REGEX_TEST_TRAILING_SLASH.test(path75)) {
28954
+ return this.test(path75);
28946
28955
  }
28947
- const slices = path74.split(SLASH).filter(Boolean);
28956
+ const slices = path75.split(SLASH).filter(Boolean);
28948
28957
  slices.pop();
28949
28958
  if (slices.length) {
28950
28959
  const parent = this._t(
@@ -28957,18 +28966,18 @@ var require_ignore = __commonJS({
28957
28966
  return parent;
28958
28967
  }
28959
28968
  }
28960
- return this._rules.test(path74, false, MODE_CHECK_IGNORE);
28969
+ return this._rules.test(path75, false, MODE_CHECK_IGNORE);
28961
28970
  }
28962
- _t(path74, cache3, checkUnignored, slices) {
28963
- if (path74 in cache3) {
28964
- return cache3[path74];
28971
+ _t(path75, cache3, checkUnignored, slices) {
28972
+ if (path75 in cache3) {
28973
+ return cache3[path75];
28965
28974
  }
28966
28975
  if (!slices) {
28967
- slices = path74.split(SLASH).filter(Boolean);
28976
+ slices = path75.split(SLASH).filter(Boolean);
28968
28977
  }
28969
28978
  slices.pop();
28970
28979
  if (!slices.length) {
28971
- return cache3[path74] = this._rules.test(path74, checkUnignored, MODE_IGNORE);
28980
+ return cache3[path75] = this._rules.test(path75, checkUnignored, MODE_IGNORE);
28972
28981
  }
28973
28982
  const parent = this._t(
28974
28983
  slices.join(SLASH) + SLASH,
@@ -28976,29 +28985,29 @@ var require_ignore = __commonJS({
28976
28985
  checkUnignored,
28977
28986
  slices
28978
28987
  );
28979
- return cache3[path74] = parent.ignored ? parent : this._rules.test(path74, checkUnignored, MODE_IGNORE);
28988
+ return cache3[path75] = parent.ignored ? parent : this._rules.test(path75, checkUnignored, MODE_IGNORE);
28980
28989
  }
28981
- ignores(path74) {
28982
- return this._test(path74, this._ignoreCache, false).ignored;
28990
+ ignores(path75) {
28991
+ return this._test(path75, this._ignoreCache, false).ignored;
28983
28992
  }
28984
28993
  createFilter() {
28985
- return (path74) => !this.ignores(path74);
28994
+ return (path75) => !this.ignores(path75);
28986
28995
  }
28987
28996
  filter(paths) {
28988
28997
  return makeArray(paths).filter(this.createFilter());
28989
28998
  }
28990
28999
  // @returns {TestResult}
28991
- test(path74) {
28992
- return this._test(path74, this._testCache, true);
29000
+ test(path75) {
29001
+ return this._test(path75, this._testCache, true);
28993
29002
  }
28994
29003
  };
28995
29004
  var factory = (options) => new Ignore(options);
28996
- var isPathValid = (path74) => checkPath(path74 && checkPath.convert(path74), path74, RETURN_FALSE);
29005
+ var isPathValid = (path75) => checkPath(path75 && checkPath.convert(path75), path75, RETURN_FALSE);
28997
29006
  var setupWindows = () => {
28998
29007
  const makePosix = (str2) => /^\\\\\?\\/.test(str2) || /["<>|\u0000-\u001F]+/u.test(str2) ? str2 : str2.replace(/\\/g, "/");
28999
29008
  checkPath.convert = makePosix;
29000
29009
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
29001
- checkPath.isNotRelative = (path74) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path74) || isNotRelative(path74);
29010
+ checkPath.isNotRelative = (path75) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path75) || isNotRelative(path75);
29002
29011
  };
29003
29012
  if (
29004
29013
  // Detect `process` so that it can run in browsers.
@@ -30415,8 +30424,8 @@ var require_node2 = __commonJS({
30415
30424
  }
30416
30425
  break;
30417
30426
  case "FILE":
30418
- var fs67 = __require("fs");
30419
- stream2 = new fs67.SyncWriteStream(fd2, { autoClose: false });
30427
+ var fs68 = __require("fs");
30428
+ stream2 = new fs68.SyncWriteStream(fd2, { autoClose: false });
30420
30429
  stream2._type = "fs";
30421
30430
  break;
30422
30431
  case "PIPE":
@@ -38100,7 +38109,7 @@ var require_path_to_regexp = __commonJS({
38100
38109
  "node_modules/.pnpm/path-to-regexp@0.1.12/node_modules/path-to-regexp/index.js"(exports, module) {
38101
38110
  module.exports = pathToRegexp;
38102
38111
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
38103
- function pathToRegexp(path74, keys, options) {
38112
+ function pathToRegexp(path75, keys, options) {
38104
38113
  options = options || {};
38105
38114
  keys = keys || [];
38106
38115
  var strict = options.strict;
@@ -38114,8 +38123,8 @@ var require_path_to_regexp = __commonJS({
38114
38123
  var pos = 0;
38115
38124
  var backtrack = "";
38116
38125
  var m;
38117
- if (path74 instanceof RegExp) {
38118
- while (m = MATCHING_GROUP_REGEXP.exec(path74.source)) {
38126
+ if (path75 instanceof RegExp) {
38127
+ while (m = MATCHING_GROUP_REGEXP.exec(path75.source)) {
38119
38128
  if (m[0][0] === "\\") continue;
38120
38129
  keys.push({
38121
38130
  name: m[1] || name++,
@@ -38123,18 +38132,18 @@ var require_path_to_regexp = __commonJS({
38123
38132
  offset: m.index
38124
38133
  });
38125
38134
  }
38126
- return path74;
38135
+ return path75;
38127
38136
  }
38128
- if (Array.isArray(path74)) {
38129
- path74 = path74.map(function(value) {
38137
+ if (Array.isArray(path75)) {
38138
+ path75 = path75.map(function(value) {
38130
38139
  return pathToRegexp(value, keys, options).source;
38131
38140
  });
38132
- return new RegExp(path74.join("|"), flags);
38141
+ return new RegExp(path75.join("|"), flags);
38133
38142
  }
38134
- if (typeof path74 !== "string") {
38143
+ if (typeof path75 !== "string") {
38135
38144
  throw new TypeError("path must be a string, array of strings, or regular expression");
38136
38145
  }
38137
- path74 = path74.replace(
38146
+ path75 = path75.replace(
38138
38147
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
38139
38148
  function(match4, slash, format, key4, capture, star3, optional, offset) {
38140
38149
  if (match4[0] === "\\") {
@@ -38151,7 +38160,7 @@ var require_path_to_regexp = __commonJS({
38151
38160
  if (slash || format) {
38152
38161
  backtrack = "";
38153
38162
  } else {
38154
- backtrack += path74.slice(pos, offset);
38163
+ backtrack += path75.slice(pos, offset);
38155
38164
  }
38156
38165
  pos = offset + match4.length;
38157
38166
  if (match4 === "*") {
@@ -38179,7 +38188,7 @@ var require_path_to_regexp = __commonJS({
38179
38188
  return result;
38180
38189
  }
38181
38190
  );
38182
- while (m = MATCHING_GROUP_REGEXP.exec(path74)) {
38191
+ while (m = MATCHING_GROUP_REGEXP.exec(path75)) {
38183
38192
  if (m[0][0] === "\\") continue;
38184
38193
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
38185
38194
  keys.splice(keysOffset + i, 0, {
@@ -38191,13 +38200,13 @@ var require_path_to_regexp = __commonJS({
38191
38200
  }
38192
38201
  i++;
38193
38202
  }
38194
- path74 += strict ? "" : path74[path74.length - 1] === "/" ? "?" : "/?";
38203
+ path75 += strict ? "" : path75[path75.length - 1] === "/" ? "?" : "/?";
38195
38204
  if (end2) {
38196
- path74 += "$";
38197
- } else if (path74[path74.length - 1] !== "/") {
38198
- path74 += lookahead ? "(?=/|$)" : "(?:/|$)";
38205
+ path75 += "$";
38206
+ } else if (path75[path75.length - 1] !== "/") {
38207
+ path75 += lookahead ? "(?=/|$)" : "(?:/|$)";
38199
38208
  }
38200
- return new RegExp("^" + path74, flags);
38209
+ return new RegExp("^" + path75, flags);
38201
38210
  }
38202
38211
  }
38203
38212
  });
@@ -38210,19 +38219,19 @@ var require_layer = __commonJS({
38210
38219
  var debug2 = require_src2()("express:router:layer");
38211
38220
  var hasOwnProperty2 = Object.prototype.hasOwnProperty;
38212
38221
  module.exports = Layer;
38213
- function Layer(path74, options, fn) {
38222
+ function Layer(path75, options, fn) {
38214
38223
  if (!(this instanceof Layer)) {
38215
- return new Layer(path74, options, fn);
38224
+ return new Layer(path75, options, fn);
38216
38225
  }
38217
- debug2("new %o", path74);
38226
+ debug2("new %o", path75);
38218
38227
  var opts = options || {};
38219
38228
  this.handle = fn;
38220
38229
  this.name = fn.name || "<anonymous>";
38221
38230
  this.params = void 0;
38222
38231
  this.path = void 0;
38223
- this.regexp = pathRegexp(path74, this.keys = [], opts);
38224
- this.regexp.fast_star = path74 === "*";
38225
- this.regexp.fast_slash = path74 === "/" && opts.end === false;
38232
+ this.regexp = pathRegexp(path75, this.keys = [], opts);
38233
+ this.regexp.fast_star = path75 === "*";
38234
+ this.regexp.fast_slash = path75 === "/" && opts.end === false;
38226
38235
  }
38227
38236
  Layer.prototype.handle_error = function handle_error(error, req, res, next) {
38228
38237
  var fn = this.handle;
@@ -38246,20 +38255,20 @@ var require_layer = __commonJS({
38246
38255
  next(err);
38247
38256
  }
38248
38257
  };
38249
- Layer.prototype.match = function match4(path74) {
38258
+ Layer.prototype.match = function match4(path75) {
38250
38259
  var match5;
38251
- if (path74 != null) {
38260
+ if (path75 != null) {
38252
38261
  if (this.regexp.fast_slash) {
38253
38262
  this.params = {};
38254
38263
  this.path = "";
38255
38264
  return true;
38256
38265
  }
38257
38266
  if (this.regexp.fast_star) {
38258
- this.params = { "0": decode_param(path74) };
38259
- this.path = path74;
38267
+ this.params = { "0": decode_param(path75) };
38268
+ this.path = path75;
38260
38269
  return true;
38261
38270
  }
38262
- match5 = this.regexp.exec(path74);
38271
+ match5 = this.regexp.exec(path75);
38263
38272
  }
38264
38273
  if (!match5) {
38265
38274
  this.params = void 0;
@@ -38352,10 +38361,10 @@ var require_route = __commonJS({
38352
38361
  var slice5 = Array.prototype.slice;
38353
38362
  var toString2 = Object.prototype.toString;
38354
38363
  module.exports = Route;
38355
- function Route(path74) {
38356
- this.path = path74;
38364
+ function Route(path75) {
38365
+ this.path = path75;
38357
38366
  this.stack = [];
38358
- debug2("new %o", path74);
38367
+ debug2("new %o", path75);
38359
38368
  this.methods = {};
38360
38369
  }
38361
38370
  Route.prototype._handles_method = function _handles_method(method) {
@@ -38567,8 +38576,8 @@ var require_router = __commonJS({
38567
38576
  if (++sync > 100) {
38568
38577
  return setImmediate(next, err);
38569
38578
  }
38570
- var path74 = getPathname(req);
38571
- if (path74 == null) {
38579
+ var path75 = getPathname(req);
38580
+ if (path75 == null) {
38572
38581
  return done(layerError);
38573
38582
  }
38574
38583
  var layer;
@@ -38576,7 +38585,7 @@ var require_router = __commonJS({
38576
38585
  var route;
38577
38586
  while (match4 !== true && idx < stack2.length) {
38578
38587
  layer = stack2[idx++];
38579
- match4 = matchLayer(layer, path74);
38588
+ match4 = matchLayer(layer, path75);
38580
38589
  route = layer.route;
38581
38590
  if (typeof match4 !== "boolean") {
38582
38591
  layerError = layerError || match4;
@@ -38614,18 +38623,18 @@ var require_router = __commonJS({
38614
38623
  } else if (route) {
38615
38624
  layer.handle_request(req, res, next);
38616
38625
  } else {
38617
- trim_prefix(layer, layerError, layerPath, path74);
38626
+ trim_prefix(layer, layerError, layerPath, path75);
38618
38627
  }
38619
38628
  sync = 0;
38620
38629
  });
38621
38630
  }
38622
- function trim_prefix(layer, layerError, layerPath, path74) {
38631
+ function trim_prefix(layer, layerError, layerPath, path75) {
38623
38632
  if (layerPath.length !== 0) {
38624
- if (layerPath !== path74.slice(0, layerPath.length)) {
38633
+ if (layerPath !== path75.slice(0, layerPath.length)) {
38625
38634
  next(layerError);
38626
38635
  return;
38627
38636
  }
38628
- var c = path74[layerPath.length];
38637
+ var c = path75[layerPath.length];
38629
38638
  if (c && c !== "/" && c !== ".") return next(layerError);
38630
38639
  debug2("trim prefix (%s) from url %s", layerPath, req.url);
38631
38640
  removed = layerPath;
@@ -38703,7 +38712,7 @@ var require_router = __commonJS({
38703
38712
  };
38704
38713
  proto.use = function use(fn) {
38705
38714
  var offset = 0;
38706
- var path74 = "/";
38715
+ var path75 = "/";
38707
38716
  if (typeof fn !== "function") {
38708
38717
  var arg = fn;
38709
38718
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -38711,7 +38720,7 @@ var require_router = __commonJS({
38711
38720
  }
38712
38721
  if (typeof arg !== "function") {
38713
38722
  offset = 1;
38714
- path74 = fn;
38723
+ path75 = fn;
38715
38724
  }
38716
38725
  }
38717
38726
  var callbacks = flatten(slice5.call(arguments, offset));
@@ -38723,8 +38732,8 @@ var require_router = __commonJS({
38723
38732
  if (typeof fn !== "function") {
38724
38733
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
38725
38734
  }
38726
- debug2("use %o %s", path74, fn.name || "<anonymous>");
38727
- var layer = new Layer(path74, {
38735
+ debug2("use %o %s", path75, fn.name || "<anonymous>");
38736
+ var layer = new Layer(path75, {
38728
38737
  sensitive: this.caseSensitive,
38729
38738
  strict: false,
38730
38739
  end: false
@@ -38734,9 +38743,9 @@ var require_router = __commonJS({
38734
38743
  }
38735
38744
  return this;
38736
38745
  };
38737
- proto.route = function route(path74) {
38738
- var route2 = new Route(path74);
38739
- var layer = new Layer(path74, {
38746
+ proto.route = function route(path75) {
38747
+ var route2 = new Route(path75);
38748
+ var layer = new Layer(path75, {
38740
38749
  sensitive: this.caseSensitive,
38741
38750
  strict: this.strict,
38742
38751
  end: true
@@ -38746,8 +38755,8 @@ var require_router = __commonJS({
38746
38755
  return route2;
38747
38756
  };
38748
38757
  methods.concat("all").forEach(function(method) {
38749
- proto[method] = function(path74) {
38750
- var route = this.route(path74);
38758
+ proto[method] = function(path75) {
38759
+ var route = this.route(path75);
38751
38760
  route[method].apply(route, slice5.call(arguments, 1));
38752
38761
  return this;
38753
38762
  };
@@ -38783,9 +38792,9 @@ var require_router = __commonJS({
38783
38792
  }
38784
38793
  return toString2.call(obj).replace(objectRegExp, "$1");
38785
38794
  }
38786
- function matchLayer(layer, path74) {
38795
+ function matchLayer(layer, path75) {
38787
38796
  try {
38788
- return layer.match(path74);
38797
+ return layer.match(path75);
38789
38798
  } catch (err) {
38790
38799
  return err;
38791
38800
  }
@@ -38903,13 +38912,13 @@ var require_view = __commonJS({
38903
38912
  "node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports, module) {
38904
38913
  "use strict";
38905
38914
  var debug2 = require_src2()("express:view");
38906
- var path74 = __require("path");
38907
- var fs67 = __require("fs");
38908
- var dirname10 = path74.dirname;
38909
- var basename2 = path74.basename;
38910
- var extname = path74.extname;
38911
- var join11 = path74.join;
38912
- var resolve11 = path74.resolve;
38915
+ var path75 = __require("path");
38916
+ var fs68 = __require("fs");
38917
+ var dirname10 = path75.dirname;
38918
+ var basename2 = path75.basename;
38919
+ var extname = path75.extname;
38920
+ var join11 = path75.join;
38921
+ var resolve11 = path75.resolve;
38913
38922
  module.exports = View;
38914
38923
  function View(name, options) {
38915
38924
  var opts = options || {};
@@ -38938,17 +38947,17 @@ var require_view = __commonJS({
38938
38947
  this.path = this.lookup(fileName);
38939
38948
  }
38940
38949
  View.prototype.lookup = function lookup(name) {
38941
- var path75;
38950
+ var path76;
38942
38951
  var roots = [].concat(this.root);
38943
38952
  debug2('lookup "%s"', name);
38944
- for (var i = 0; i < roots.length && !path75; i++) {
38953
+ for (var i = 0; i < roots.length && !path76; i++) {
38945
38954
  var root = roots[i];
38946
38955
  var loc = resolve11(root, name);
38947
38956
  var dir = dirname10(loc);
38948
38957
  var file = basename2(loc);
38949
- path75 = this.resolve(dir, file);
38958
+ path76 = this.resolve(dir, file);
38950
38959
  }
38951
- return path75;
38960
+ return path76;
38952
38961
  };
38953
38962
  View.prototype.render = function render(options, callback) {
38954
38963
  debug2('render "%s"', this.path);
@@ -38956,21 +38965,21 @@ var require_view = __commonJS({
38956
38965
  };
38957
38966
  View.prototype.resolve = function resolve12(dir, file) {
38958
38967
  var ext2 = this.ext;
38959
- var path75 = join11(dir, file);
38960
- var stat = tryStat(path75);
38968
+ var path76 = join11(dir, file);
38969
+ var stat = tryStat(path76);
38961
38970
  if (stat && stat.isFile()) {
38962
- return path75;
38971
+ return path76;
38963
38972
  }
38964
- path75 = join11(dir, basename2(file, ext2), "index" + ext2);
38965
- stat = tryStat(path75);
38973
+ path76 = join11(dir, basename2(file, ext2), "index" + ext2);
38974
+ stat = tryStat(path76);
38966
38975
  if (stat && stat.isFile()) {
38967
- return path75;
38976
+ return path76;
38968
38977
  }
38969
38978
  };
38970
- function tryStat(path75) {
38971
- debug2('stat "%s"', path75);
38979
+ function tryStat(path76) {
38980
+ debug2('stat "%s"', path76);
38972
38981
  try {
38973
- return fs67.statSync(path75);
38982
+ return fs68.statSync(path76);
38974
38983
  } catch (e) {
38975
38984
  return void 0;
38976
38985
  }
@@ -39324,8 +39333,8 @@ var require_types = __commonJS({
39324
39333
  // node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js
39325
39334
  var require_mime = __commonJS({
39326
39335
  "node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports, module) {
39327
- var path74 = __require("path");
39328
- var fs67 = __require("fs");
39336
+ var path75 = __require("path");
39337
+ var fs68 = __require("fs");
39329
39338
  function Mime() {
39330
39339
  this.types = /* @__PURE__ */ Object.create(null);
39331
39340
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -39346,7 +39355,7 @@ var require_mime = __commonJS({
39346
39355
  };
39347
39356
  Mime.prototype.load = function(file) {
39348
39357
  this._loading = file;
39349
- var map2 = {}, content = fs67.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
39358
+ var map2 = {}, content = fs68.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
39350
39359
  lines.forEach(function(line) {
39351
39360
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
39352
39361
  map2[fields.shift()] = fields;
@@ -39354,8 +39363,8 @@ var require_mime = __commonJS({
39354
39363
  this.define(map2);
39355
39364
  this._loading = null;
39356
39365
  };
39357
- Mime.prototype.lookup = function(path75, fallback) {
39358
- var ext2 = path75.replace(/^.*[\.\/\\]/, "").toLowerCase();
39366
+ Mime.prototype.lookup = function(path76, fallback) {
39367
+ var ext2 = path76.replace(/^.*[\.\/\\]/, "").toLowerCase();
39359
39368
  return this.types[ext2] || fallback || this.default_type;
39360
39369
  };
39361
39370
  Mime.prototype.extension = function(mimeType) {
@@ -39468,33 +39477,33 @@ var require_send = __commonJS({
39468
39477
  var escapeHtml = require_escape_html();
39469
39478
  var etag = require_etag();
39470
39479
  var fresh = require_fresh();
39471
- var fs67 = __require("fs");
39480
+ var fs68 = __require("fs");
39472
39481
  var mime = require_mime();
39473
39482
  var ms = require_ms();
39474
39483
  var onFinished = require_on_finished();
39475
39484
  var parseRange = require_range_parser();
39476
- var path74 = __require("path");
39485
+ var path75 = __require("path");
39477
39486
  var statuses = require_statuses();
39478
39487
  var Stream = __require("stream");
39479
39488
  var util2 = __require("util");
39480
- var extname = path74.extname;
39481
- var join11 = path74.join;
39482
- var normalize8 = path74.normalize;
39483
- var resolve11 = path74.resolve;
39484
- var sep3 = path74.sep;
39489
+ var extname = path75.extname;
39490
+ var join11 = path75.join;
39491
+ var normalize8 = path75.normalize;
39492
+ var resolve11 = path75.resolve;
39493
+ var sep3 = path75.sep;
39485
39494
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
39486
39495
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
39487
39496
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
39488
39497
  module.exports = send;
39489
39498
  module.exports.mime = mime;
39490
- function send(req, path75, options) {
39491
- return new SendStream(req, path75, options);
39499
+ function send(req, path76, options) {
39500
+ return new SendStream(req, path76, options);
39492
39501
  }
39493
- function SendStream(req, path75, options) {
39502
+ function SendStream(req, path76, options) {
39494
39503
  Stream.call(this);
39495
39504
  var opts = options || {};
39496
39505
  this.options = opts;
39497
- this.path = path75;
39506
+ this.path = path76;
39498
39507
  this.req = req;
39499
39508
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
39500
39509
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -39540,8 +39549,8 @@ var require_send = __commonJS({
39540
39549
  this._index = index2;
39541
39550
  return this;
39542
39551
  }, "send.index: pass index as option");
39543
- SendStream.prototype.root = function root(path75) {
39544
- this._root = resolve11(String(path75));
39552
+ SendStream.prototype.root = function root(path76) {
39553
+ this._root = resolve11(String(path76));
39545
39554
  debug2("root %s", this._root);
39546
39555
  return this;
39547
39556
  };
@@ -39654,10 +39663,10 @@ var require_send = __commonJS({
39654
39663
  var lastModified = this.res.getHeader("Last-Modified");
39655
39664
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
39656
39665
  };
39657
- SendStream.prototype.redirect = function redirect(path75) {
39666
+ SendStream.prototype.redirect = function redirect(path76) {
39658
39667
  var res = this.res;
39659
39668
  if (hasListeners(this, "directory")) {
39660
- this.emit("directory", res, path75);
39669
+ this.emit("directory", res, path76);
39661
39670
  return;
39662
39671
  }
39663
39672
  if (this.hasTrailingSlash()) {
@@ -39677,42 +39686,42 @@ var require_send = __commonJS({
39677
39686
  SendStream.prototype.pipe = function pipe(res) {
39678
39687
  var root = this._root;
39679
39688
  this.res = res;
39680
- var path75 = decode(this.path);
39681
- if (path75 === -1) {
39689
+ var path76 = decode(this.path);
39690
+ if (path76 === -1) {
39682
39691
  this.error(400);
39683
39692
  return res;
39684
39693
  }
39685
- if (~path75.indexOf("\0")) {
39694
+ if (~path76.indexOf("\0")) {
39686
39695
  this.error(400);
39687
39696
  return res;
39688
39697
  }
39689
39698
  var parts;
39690
39699
  if (root !== null) {
39691
- if (path75) {
39692
- path75 = normalize8("." + sep3 + path75);
39700
+ if (path76) {
39701
+ path76 = normalize8("." + sep3 + path76);
39693
39702
  }
39694
- if (UP_PATH_REGEXP.test(path75)) {
39695
- debug2('malicious path "%s"', path75);
39703
+ if (UP_PATH_REGEXP.test(path76)) {
39704
+ debug2('malicious path "%s"', path76);
39696
39705
  this.error(403);
39697
39706
  return res;
39698
39707
  }
39699
- parts = path75.split(sep3);
39700
- path75 = normalize8(join11(root, path75));
39708
+ parts = path76.split(sep3);
39709
+ path76 = normalize8(join11(root, path76));
39701
39710
  } else {
39702
- if (UP_PATH_REGEXP.test(path75)) {
39703
- debug2('malicious path "%s"', path75);
39711
+ if (UP_PATH_REGEXP.test(path76)) {
39712
+ debug2('malicious path "%s"', path76);
39704
39713
  this.error(403);
39705
39714
  return res;
39706
39715
  }
39707
- parts = normalize8(path75).split(sep3);
39708
- path75 = resolve11(path75);
39716
+ parts = normalize8(path76).split(sep3);
39717
+ path76 = resolve11(path76);
39709
39718
  }
39710
39719
  if (containsDotFile(parts)) {
39711
39720
  var access = this._dotfiles;
39712
39721
  if (access === void 0) {
39713
39722
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
39714
39723
  }
39715
- debug2('%s dotfile "%s"', access, path75);
39724
+ debug2('%s dotfile "%s"', access, path76);
39716
39725
  switch (access) {
39717
39726
  case "allow":
39718
39727
  break;
@@ -39726,13 +39735,13 @@ var require_send = __commonJS({
39726
39735
  }
39727
39736
  }
39728
39737
  if (this._index.length && this.hasTrailingSlash()) {
39729
- this.sendIndex(path75);
39738
+ this.sendIndex(path76);
39730
39739
  return res;
39731
39740
  }
39732
- this.sendFile(path75);
39741
+ this.sendFile(path76);
39733
39742
  return res;
39734
39743
  };
39735
- SendStream.prototype.send = function send2(path75, stat) {
39744
+ SendStream.prototype.send = function send2(path76, stat) {
39736
39745
  var len = stat.size;
39737
39746
  var options = this.options;
39738
39747
  var opts = {};
@@ -39744,9 +39753,9 @@ var require_send = __commonJS({
39744
39753
  this.headersAlreadySent();
39745
39754
  return;
39746
39755
  }
39747
- debug2('pipe "%s"', path75);
39748
- this.setHeader(path75, stat);
39749
- this.type(path75);
39756
+ debug2('pipe "%s"', path76);
39757
+ this.setHeader(path76, stat);
39758
+ this.type(path76);
39750
39759
  if (this.isConditionalGET()) {
39751
39760
  if (this.isPreconditionFailure()) {
39752
39761
  this.error(412);
@@ -39795,28 +39804,28 @@ var require_send = __commonJS({
39795
39804
  res.end();
39796
39805
  return;
39797
39806
  }
39798
- this.stream(path75, opts);
39807
+ this.stream(path76, opts);
39799
39808
  };
39800
- SendStream.prototype.sendFile = function sendFile(path75) {
39809
+ SendStream.prototype.sendFile = function sendFile(path76) {
39801
39810
  var i = 0;
39802
39811
  var self2 = this;
39803
- debug2('stat "%s"', path75);
39804
- fs67.stat(path75, function onstat(err, stat) {
39805
- if (err && err.code === "ENOENT" && !extname(path75) && path75[path75.length - 1] !== sep3) {
39812
+ debug2('stat "%s"', path76);
39813
+ fs68.stat(path76, function onstat(err, stat) {
39814
+ if (err && err.code === "ENOENT" && !extname(path76) && path76[path76.length - 1] !== sep3) {
39806
39815
  return next(err);
39807
39816
  }
39808
39817
  if (err) return self2.onStatError(err);
39809
- if (stat.isDirectory()) return self2.redirect(path75);
39810
- self2.emit("file", path75, stat);
39811
- self2.send(path75, stat);
39818
+ if (stat.isDirectory()) return self2.redirect(path76);
39819
+ self2.emit("file", path76, stat);
39820
+ self2.send(path76, stat);
39812
39821
  });
39813
39822
  function next(err) {
39814
39823
  if (self2._extensions.length <= i) {
39815
39824
  return err ? self2.onStatError(err) : self2.error(404);
39816
39825
  }
39817
- var p = path75 + "." + self2._extensions[i++];
39826
+ var p = path76 + "." + self2._extensions[i++];
39818
39827
  debug2('stat "%s"', p);
39819
- fs67.stat(p, function(err2, stat) {
39828
+ fs68.stat(p, function(err2, stat) {
39820
39829
  if (err2) return next(err2);
39821
39830
  if (stat.isDirectory()) return next();
39822
39831
  self2.emit("file", p, stat);
@@ -39824,7 +39833,7 @@ var require_send = __commonJS({
39824
39833
  });
39825
39834
  }
39826
39835
  };
39827
- SendStream.prototype.sendIndex = function sendIndex(path75) {
39836
+ SendStream.prototype.sendIndex = function sendIndex(path76) {
39828
39837
  var i = -1;
39829
39838
  var self2 = this;
39830
39839
  function next(err) {
@@ -39832,9 +39841,9 @@ var require_send = __commonJS({
39832
39841
  if (err) return self2.onStatError(err);
39833
39842
  return self2.error(404);
39834
39843
  }
39835
- var p = join11(path75, self2._index[i]);
39844
+ var p = join11(path76, self2._index[i]);
39836
39845
  debug2('stat "%s"', p);
39837
- fs67.stat(p, function(err2, stat) {
39846
+ fs68.stat(p, function(err2, stat) {
39838
39847
  if (err2) return next(err2);
39839
39848
  if (stat.isDirectory()) return next();
39840
39849
  self2.emit("file", p, stat);
@@ -39843,10 +39852,10 @@ var require_send = __commonJS({
39843
39852
  }
39844
39853
  next();
39845
39854
  };
39846
- SendStream.prototype.stream = function stream(path75, options) {
39855
+ SendStream.prototype.stream = function stream(path76, options) {
39847
39856
  var self2 = this;
39848
39857
  var res = this.res;
39849
- var stream2 = fs67.createReadStream(path75, options);
39858
+ var stream2 = fs68.createReadStream(path76, options);
39850
39859
  this.emit("stream", stream2);
39851
39860
  stream2.pipe(res);
39852
39861
  function cleanup() {
@@ -39861,10 +39870,10 @@ var require_send = __commonJS({
39861
39870
  self2.emit("end");
39862
39871
  });
39863
39872
  };
39864
- SendStream.prototype.type = function type2(path75) {
39873
+ SendStream.prototype.type = function type2(path76) {
39865
39874
  var res = this.res;
39866
39875
  if (res.getHeader("Content-Type")) return;
39867
- var type3 = mime.lookup(path75);
39876
+ var type3 = mime.lookup(path76);
39868
39877
  if (!type3) {
39869
39878
  debug2("no content-type");
39870
39879
  return;
@@ -39873,9 +39882,9 @@ var require_send = __commonJS({
39873
39882
  debug2("content-type %s", type3);
39874
39883
  res.setHeader("Content-Type", type3 + (charset ? "; charset=" + charset : ""));
39875
39884
  };
39876
- SendStream.prototype.setHeader = function setHeader(path75, stat) {
39885
+ SendStream.prototype.setHeader = function setHeader(path76, stat) {
39877
39886
  var res = this.res;
39878
- this.emit("headers", res, path75, stat);
39887
+ this.emit("headers", res, path76, stat);
39879
39888
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
39880
39889
  debug2("accept ranges");
39881
39890
  res.setHeader("Accept-Ranges", "bytes");
@@ -39934,9 +39943,9 @@ var require_send = __commonJS({
39934
39943
  }
39935
39944
  return err instanceof Error ? createError2(status, err, { expose: false }) : createError2(status, err);
39936
39945
  }
39937
- function decode(path75) {
39946
+ function decode(path76) {
39938
39947
  try {
39939
- return decodeURIComponent(path75);
39948
+ return decodeURIComponent(path76);
39940
39949
  } catch (err) {
39941
39950
  return -1;
39942
39951
  }
@@ -40845,10 +40854,10 @@ var require_utils2 = __commonJS({
40845
40854
  var querystring = __require("querystring");
40846
40855
  exports.etag = createETagGenerator({ weak: false });
40847
40856
  exports.wetag = createETagGenerator({ weak: true });
40848
- exports.isAbsolute = function(path74) {
40849
- if ("/" === path74[0]) return true;
40850
- if (":" === path74[1] && ("\\" === path74[2] || "/" === path74[2])) return true;
40851
- if ("\\\\" === path74.substring(0, 2)) return true;
40857
+ exports.isAbsolute = function(path75) {
40858
+ if ("/" === path75[0]) return true;
40859
+ if (":" === path75[1] && ("\\" === path75[2] || "/" === path75[2])) return true;
40860
+ if ("\\\\" === path75.substring(0, 2)) return true;
40852
40861
  };
40853
40862
  exports.flatten = deprecate.function(
40854
40863
  flatten,
@@ -41059,7 +41068,7 @@ var require_application = __commonJS({
41059
41068
  };
41060
41069
  app.use = function use(fn) {
41061
41070
  var offset = 0;
41062
- var path74 = "/";
41071
+ var path75 = "/";
41063
41072
  if (typeof fn !== "function") {
41064
41073
  var arg = fn;
41065
41074
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -41067,7 +41076,7 @@ var require_application = __commonJS({
41067
41076
  }
41068
41077
  if (typeof arg !== "function") {
41069
41078
  offset = 1;
41070
- path74 = fn;
41079
+ path75 = fn;
41071
41080
  }
41072
41081
  }
41073
41082
  var fns = flatten(slice5.call(arguments, offset));
@@ -41078,12 +41087,12 @@ var require_application = __commonJS({
41078
41087
  var router16 = this._router;
41079
41088
  fns.forEach(function(fn2) {
41080
41089
  if (!fn2 || !fn2.handle || !fn2.set) {
41081
- return router16.use(path74, fn2);
41090
+ return router16.use(path75, fn2);
41082
41091
  }
41083
- debug2(".use app under %s", path74);
41084
- fn2.mountpath = path74;
41092
+ debug2(".use app under %s", path75);
41093
+ fn2.mountpath = path75;
41085
41094
  fn2.parent = this;
41086
- router16.use(path74, function mounted_app(req, res, next) {
41095
+ router16.use(path75, function mounted_app(req, res, next) {
41087
41096
  var orig = req.app;
41088
41097
  fn2.handle(req, res, function(err) {
41089
41098
  setPrototypeOf(req, orig.request);
@@ -41095,9 +41104,9 @@ var require_application = __commonJS({
41095
41104
  }, this);
41096
41105
  return this;
41097
41106
  };
41098
- app.route = function route(path74) {
41107
+ app.route = function route(path75) {
41099
41108
  this.lazyrouter();
41100
- return this._router.route(path74);
41109
+ return this._router.route(path75);
41101
41110
  };
41102
41111
  app.engine = function engine(ext2, fn) {
41103
41112
  if (typeof fn !== "function") {
@@ -41148,7 +41157,7 @@ var require_application = __commonJS({
41148
41157
  }
41149
41158
  return this;
41150
41159
  };
41151
- app.path = function path74() {
41160
+ app.path = function path75() {
41152
41161
  return this.parent ? this.parent.path() + this.mountpath : "";
41153
41162
  };
41154
41163
  app.enabled = function enabled(setting) {
@@ -41164,19 +41173,19 @@ var require_application = __commonJS({
41164
41173
  return this.set(setting, false);
41165
41174
  };
41166
41175
  methods.forEach(function(method) {
41167
- app[method] = function(path74) {
41176
+ app[method] = function(path75) {
41168
41177
  if (method === "get" && arguments.length === 1) {
41169
- return this.set(path74);
41178
+ return this.set(path75);
41170
41179
  }
41171
41180
  this.lazyrouter();
41172
- var route = this._router.route(path74);
41181
+ var route = this._router.route(path75);
41173
41182
  route[method].apply(route, slice5.call(arguments, 1));
41174
41183
  return this;
41175
41184
  };
41176
41185
  });
41177
- app.all = function all(path74) {
41186
+ app.all = function all(path75) {
41178
41187
  this.lazyrouter();
41179
- var route = this._router.route(path74);
41188
+ var route = this._router.route(path75);
41180
41189
  var args = slice5.call(arguments, 1);
41181
41190
  for (var i = 0; i < methods.length; i++) {
41182
41191
  route[methods[i]].apply(route, args);
@@ -41357,7 +41366,7 @@ var require_request = __commonJS({
41357
41366
  var subdomains2 = !isIP(hostname) ? hostname.split(".").reverse() : [hostname];
41358
41367
  return subdomains2.slice(offset);
41359
41368
  });
41360
- defineGetter(req, "path", function path74() {
41369
+ defineGetter(req, "path", function path75() {
41361
41370
  return parse2(this).pathname;
41362
41371
  });
41363
41372
  defineGetter(req, "hostname", function hostname() {
@@ -41440,7 +41449,7 @@ var require_response = __commonJS({
41440
41449
  var http = __require("http");
41441
41450
  var isAbsolute = require_utils2().isAbsolute;
41442
41451
  var onFinished = require_on_finished();
41443
- var path74 = __require("path");
41452
+ var path75 = __require("path");
41444
41453
  var statuses = require_statuses();
41445
41454
  var merge2 = require_utils_merge();
41446
41455
  var sign = require_cookie_signature().sign;
@@ -41449,9 +41458,9 @@ var require_response = __commonJS({
41449
41458
  var setCharset = require_utils2().setCharset;
41450
41459
  var cookie = require_cookie();
41451
41460
  var send = require_send();
41452
- var extname = path74.extname;
41461
+ var extname = path75.extname;
41453
41462
  var mime = send.mime;
41454
- var resolve11 = path74.resolve;
41463
+ var resolve11 = path75.resolve;
41455
41464
  var vary = require_vary();
41456
41465
  var res = Object.create(http.ServerResponse.prototype);
41457
41466
  module.exports = res;
@@ -41628,26 +41637,26 @@ var require_response = __commonJS({
41628
41637
  this.type("txt");
41629
41638
  return this.send(body);
41630
41639
  };
41631
- res.sendFile = function sendFile(path75, options, callback) {
41640
+ res.sendFile = function sendFile(path76, options, callback) {
41632
41641
  var done = callback;
41633
41642
  var req = this.req;
41634
41643
  var res2 = this;
41635
41644
  var next = req.next;
41636
41645
  var opts = options || {};
41637
- if (!path75) {
41646
+ if (!path76) {
41638
41647
  throw new TypeError("path argument is required to res.sendFile");
41639
41648
  }
41640
- if (typeof path75 !== "string") {
41649
+ if (typeof path76 !== "string") {
41641
41650
  throw new TypeError("path must be a string to res.sendFile");
41642
41651
  }
41643
41652
  if (typeof options === "function") {
41644
41653
  done = options;
41645
41654
  opts = {};
41646
41655
  }
41647
- if (!opts.root && !isAbsolute(path75)) {
41656
+ if (!opts.root && !isAbsolute(path76)) {
41648
41657
  throw new TypeError("path must be absolute or specify root to res.sendFile");
41649
41658
  }
41650
- var pathname = encodeURI(path75);
41659
+ var pathname = encodeURI(path76);
41651
41660
  var file = send(req, pathname, opts);
41652
41661
  sendfile(res2, file, opts, function(err) {
41653
41662
  if (done) return done(err);
@@ -41657,7 +41666,7 @@ var require_response = __commonJS({
41657
41666
  }
41658
41667
  });
41659
41668
  };
41660
- res.sendfile = function(path75, options, callback) {
41669
+ res.sendfile = function(path76, options, callback) {
41661
41670
  var done = callback;
41662
41671
  var req = this.req;
41663
41672
  var res2 = this;
@@ -41667,7 +41676,7 @@ var require_response = __commonJS({
41667
41676
  done = options;
41668
41677
  opts = {};
41669
41678
  }
41670
- var file = send(req, path75, opts);
41679
+ var file = send(req, path76, opts);
41671
41680
  sendfile(res2, file, opts, function(err) {
41672
41681
  if (done) return done(err);
41673
41682
  if (err && err.code === "EISDIR") return next();
@@ -41680,7 +41689,7 @@ var require_response = __commonJS({
41680
41689
  res.sendfile,
41681
41690
  "res.sendfile: Use res.sendFile instead"
41682
41691
  );
41683
- res.download = function download(path75, filename, options, callback) {
41692
+ res.download = function download(path76, filename, options, callback) {
41684
41693
  var done = callback;
41685
41694
  var name = filename;
41686
41695
  var opts = options || null;
@@ -41697,7 +41706,7 @@ var require_response = __commonJS({
41697
41706
  opts = filename;
41698
41707
  }
41699
41708
  var headers = {
41700
- "Content-Disposition": contentDisposition(name || path75)
41709
+ "Content-Disposition": contentDisposition(name || path76)
41701
41710
  };
41702
41711
  if (opts && opts.headers) {
41703
41712
  var keys = Object.keys(opts.headers);
@@ -41710,7 +41719,7 @@ var require_response = __commonJS({
41710
41719
  }
41711
41720
  opts = Object.create(opts);
41712
41721
  opts.headers = headers;
41713
- var fullPath = !opts.root ? resolve11(path75) : path75;
41722
+ var fullPath = !opts.root ? resolve11(path76) : path76;
41714
41723
  return this.sendFile(fullPath, opts, done);
41715
41724
  };
41716
41725
  res.contentType = res.type = function contentType(type2) {
@@ -42011,11 +42020,11 @@ var require_serve_static = __commonJS({
42011
42020
  }
42012
42021
  var forwardError = !fallthrough;
42013
42022
  var originalUrl = parseUrl.original(req);
42014
- var path74 = parseUrl(req).pathname;
42015
- if (path74 === "/" && originalUrl.pathname.substr(-1) !== "/") {
42016
- path74 = "";
42023
+ var path75 = parseUrl(req).pathname;
42024
+ if (path75 === "/" && originalUrl.pathname.substr(-1) !== "/") {
42025
+ path75 = "";
42017
42026
  }
42018
- var stream = send(req, path74, opts);
42027
+ var stream = send(req, path75, opts);
42019
42028
  stream.on("directory", onDirectory);
42020
42029
  if (setHeaders) {
42021
42030
  stream.on("headers", setHeaders);
@@ -42162,10 +42171,10 @@ var require_src3 = __commonJS({
42162
42171
  var fs_1 = __require("fs");
42163
42172
  var debug_1 = __importDefault(require_src());
42164
42173
  var log2 = debug_1.default("@kwsites/file-exists");
42165
- function check(path74, isFile, isDirectory) {
42166
- log2(`checking %s`, path74);
42174
+ function check(path75, isFile, isDirectory) {
42175
+ log2(`checking %s`, path75);
42167
42176
  try {
42168
- const stat = fs_1.statSync(path74);
42177
+ const stat = fs_1.statSync(path75);
42169
42178
  if (stat.isFile() && isFile) {
42170
42179
  log2(`[OK] path represents a file`);
42171
42180
  return true;
@@ -42185,8 +42194,8 @@ var require_src3 = __commonJS({
42185
42194
  throw e;
42186
42195
  }
42187
42196
  }
42188
- function exists2(path74, type2 = exports.READABLE) {
42189
- return check(path74, (type2 & exports.FILE) > 0, (type2 & exports.FOLDER) > 0);
42197
+ function exists2(path75, type2 = exports.READABLE) {
42198
+ return check(path75, (type2 & exports.FILE) > 0, (type2 & exports.FOLDER) > 0);
42190
42199
  }
42191
42200
  exports.exists = exists2;
42192
42201
  exports.FILE = 1;
@@ -46039,18 +46048,18 @@ function extractRouterMount(callNode, filePath) {
46039
46048
  const routerName = args[0]?.type === "identifier" ? args[0].text : null;
46040
46049
  if (!routerName)
46041
46050
  return null;
46042
- let path74 = "/";
46051
+ let path75 = "/";
46043
46052
  for (const arg of args) {
46044
46053
  if (arg.type === "keyword_argument") {
46045
46054
  const key4 = arg.childForFieldName("name")?.text;
46046
46055
  const value = arg.childForFieldName("value");
46047
46056
  if ((key4 === "url_prefix" || key4 === "prefix") && value) {
46048
- path74 = value.text.replace(/^["']|["']$/g, "");
46057
+ path75 = value.text.replace(/^["']|["']$/g, "");
46049
46058
  }
46050
46059
  }
46051
46060
  }
46052
46061
  return {
46053
- path: path74,
46062
+ path: path75,
46054
46063
  routerName,
46055
46064
  location: {
46056
46065
  filePath,
@@ -46074,11 +46083,11 @@ function extractChainedRoute(outerCall, filePath) {
46074
46083
  const innerArgs = innerCall.childForFieldName("arguments");
46075
46084
  if (!innerArgs)
46076
46085
  return null;
46077
- let path74 = null;
46086
+ let path75 = null;
46078
46087
  let httpMethod = methodName3 === "route" ? "GET" : methodName3.toUpperCase();
46079
46088
  for (const arg of innerArgs.namedChildren) {
46080
- if (!path74 && arg.type === "string") {
46081
- path74 = arg.text.replace(/^["']|["']$/g, "");
46089
+ if (!path75 && arg.type === "string") {
46090
+ path75 = arg.text.replace(/^["']|["']$/g, "");
46082
46091
  }
46083
46092
  if (arg.type === "keyword_argument") {
46084
46093
  const key4 = arg.childForFieldName("name")?.text;
@@ -46090,14 +46099,14 @@ function extractChainedRoute(outerCall, filePath) {
46090
46099
  }
46091
46100
  }
46092
46101
  }
46093
- if (!path74)
46102
+ if (!path75)
46094
46103
  return null;
46095
46104
  const outerArgs = outerCall.childForFieldName("arguments");
46096
46105
  const handlerArg = outerArgs?.namedChildren[0];
46097
46106
  const handlerName = handlerArg?.type === "identifier" ? handlerArg.text : "anonymous";
46098
46107
  return {
46099
46108
  httpMethod,
46100
- path: path74,
46109
+ path: path75,
46101
46110
  handlerName,
46102
46111
  location: {
46103
46112
  filePath,
@@ -46159,11 +46168,11 @@ function collectGroupPrefixes(root) {
46159
46168
  const fn = child.childForFieldName("function");
46160
46169
  if (fn?.type === "member_access_expression" && fn.childForFieldName("name")?.text === "MapGroup") {
46161
46170
  const args = child.childForFieldName("arguments");
46162
- const path74 = args ? extractFirstStringArg(args) : null;
46163
- if (name && path74) {
46171
+ const path75 = args ? extractFirstStringArg(args) : null;
46172
+ if (name && path75) {
46164
46173
  const receiver = fn.childForFieldName("expression")?.text ?? "";
46165
46174
  const parentPrefix = prefixes.get(receiver) ?? "";
46166
- prefixes.set(name, joinRoute(parentPrefix, path74));
46175
+ prefixes.set(name, joinRoute(parentPrefix, path75));
46167
46176
  }
46168
46177
  }
46169
46178
  }
@@ -46187,9 +46196,9 @@ function extractClassRoutePrefix(classNode) {
46187
46196
  continue;
46188
46197
  const args = childOfType(attr, "attribute_argument_list");
46189
46198
  if (args) {
46190
- const path74 = extractFirstStringArg(args);
46191
- if (path74)
46192
- return path74;
46199
+ const path75 = extractFirstStringArg(args);
46200
+ if (path75)
46201
+ return path75;
46193
46202
  }
46194
46203
  }
46195
46204
  }
@@ -46212,16 +46221,16 @@ function extractAttributeRoute(methodNode, filePath, classContext) {
46212
46221
  httpMethod = method;
46213
46222
  const args = childOfType(attr, "attribute_argument_list");
46214
46223
  if (args) {
46215
- const path74 = extractFirstStringArg(args);
46216
- if (path74)
46217
- routePath = path74;
46224
+ const path75 = extractFirstStringArg(args);
46225
+ if (path75)
46226
+ routePath = path75;
46218
46227
  }
46219
46228
  } else if (name === "Route" && !routePath) {
46220
46229
  const args = childOfType(attr, "attribute_argument_list");
46221
46230
  if (args) {
46222
- const path74 = extractFirstStringArg(args);
46223
- if (path74)
46224
- routePath = path74;
46231
+ const path75 = extractFirstStringArg(args);
46232
+ if (path75)
46233
+ routePath = path75;
46225
46234
  }
46226
46235
  }
46227
46236
  }
@@ -46255,12 +46264,12 @@ function extractMinimalApiRoute(callNode, filePath, groupPrefixes) {
46255
46264
  const argsNode = callNode.childForFieldName("arguments");
46256
46265
  if (!argsNode)
46257
46266
  return null;
46258
- const path74 = extractFirstStringArg(argsNode);
46259
- if (path74 === null)
46267
+ const path75 = extractFirstStringArg(argsNode);
46268
+ if (path75 === null)
46260
46269
  return null;
46261
46270
  const receiver = funcNode.childForFieldName("expression")?.text ?? "";
46262
46271
  const prefix = groupPrefixes.get(receiver) ?? "";
46263
- let fullPath = joinRoute(prefix, path74);
46272
+ let fullPath = joinRoute(prefix, path75);
46264
46273
  if (!fullPath.startsWith("/"))
46265
46274
  fullPath = "/" + fullPath;
46266
46275
  let handlerName = "anonymous";
@@ -46287,11 +46296,11 @@ function childOfType(node2, type2) {
46287
46296
  }
46288
46297
  return null;
46289
46298
  }
46290
- function joinRoute(prefix, path74) {
46299
+ function joinRoute(prefix, path75) {
46291
46300
  const p = prefix.replace(/\/$/, "");
46292
- const s = path74.replace(/^\//, "");
46301
+ const s = path75.replace(/^\//, "");
46293
46302
  if (!p)
46294
- return path74;
46303
+ return path75;
46295
46304
  if (!s)
46296
46305
  return p;
46297
46306
  return `${p}/${s}`;
@@ -46400,8 +46409,8 @@ function extractRoute(methodName3, argsNode, filePath, callNode) {
46400
46409
  const firstArg = argsNode.namedChild(0);
46401
46410
  if (!firstArg)
46402
46411
  return null;
46403
- const path74 = extractStringLiteral(firstArg);
46404
- if (!path74)
46412
+ const path75 = extractStringLiteral(firstArg);
46413
+ if (!path75)
46405
46414
  return null;
46406
46415
  const argCount = argsNode.namedChildCount;
46407
46416
  if (argCount < 2)
@@ -46414,7 +46423,7 @@ function extractRoute(methodName3, argsNode, filePath, callNode) {
46414
46423
  return null;
46415
46424
  return {
46416
46425
  httpMethod: methodName3.toUpperCase(),
46417
- path: path74,
46426
+ path: path75,
46418
46427
  handlerName,
46419
46428
  location: {
46420
46429
  filePath,
@@ -46431,8 +46440,8 @@ function extractMount(argsNode, filePath, callNode) {
46431
46440
  const firstArg = argsNode.namedChild(0);
46432
46441
  if (!firstArg)
46433
46442
  return null;
46434
- const path74 = extractStringLiteral(firstArg);
46435
- if (!path74)
46443
+ const path75 = extractStringLiteral(firstArg);
46444
+ if (!path75)
46436
46445
  return null;
46437
46446
  const secondArg = argsNode.namedChild(1);
46438
46447
  if (!secondArg)
@@ -46441,7 +46450,7 @@ function extractMount(argsNode, filePath, callNode) {
46441
46450
  if (!routerName)
46442
46451
  return null;
46443
46452
  return {
46444
- path: path74,
46453
+ path: path75,
46445
46454
  routerName,
46446
46455
  location: {
46447
46456
  filePath,
@@ -48972,11 +48981,11 @@ function buildCSharpSymbolIndex(files, rootPath) {
48972
48981
  byFullName.get(full).push(decl);
48973
48982
  }
48974
48983
  const stats = { resolvedRefs: 0, ambiguousRefs: 0 };
48975
- function resolveQualified(path74) {
48976
- const exact = byFullName.get(path74);
48984
+ function resolveQualified(path75) {
48985
+ const exact = byFullName.get(path75);
48977
48986
  if (exact)
48978
48987
  return exact;
48979
- const parts = path74.split(".");
48988
+ const parts = path75.split(".");
48980
48989
  for (let i = parts.length - 1; i > 0; i--) {
48981
48990
  const prefix = parts.slice(0, i).join(".");
48982
48991
  const found = byFullName.get(prefix);
@@ -48990,8 +48999,8 @@ function buildCSharpSymbolIndex(files, rootPath) {
48990
48999
  const firstDot = ref.name.indexOf(".");
48991
49000
  const head = ref.name.slice(0, firstDot);
48992
49001
  const aliasTarget2 = aliases.get(head);
48993
- const path74 = aliasTarget2 ? `${aliasTarget2}${ref.name.slice(firstDot)}` : ref.name;
48994
- return resolveQualified(path74).filter((d) => isDeclVisibleFrom(d, ctx.project, fileProjects.get(d.filePath)));
49002
+ const path75 = aliasTarget2 ? `${aliasTarget2}${ref.name.slice(firstDot)}` : ref.name;
49003
+ return resolveQualified(path75).filter((d) => isDeclVisibleFrom(d, ctx.project, fileProjects.get(d.filePath)));
48995
49004
  }
48996
49005
  const aliasTarget = aliases.get(ref.name);
48997
49006
  if (aliasTarget) {
@@ -52112,9 +52121,9 @@ function detectDockerComposeServices(rootPath, allFiles) {
52112
52121
  ];
52113
52122
  let composePath2 = null;
52114
52123
  for (const file of composeFiles) {
52115
- const path74 = join8(rootPath, file);
52116
- if (existsSync6(path74)) {
52117
- composePath2 = path74;
52124
+ const path75 = join8(rootPath, file);
52125
+ if (existsSync6(path75)) {
52126
+ composePath2 = path75;
52118
52127
  break;
52119
52128
  }
52120
52129
  }
@@ -55334,9 +55343,9 @@ function findSimpleCycles(component, componentSet, adjacency) {
55334
55343
  for (const next of successors) {
55335
55344
  if (!componentSet.has(next))
55336
55345
  continue;
55337
- if (next === start && path74.length >= 2) {
55338
- const chain = [...path74, start];
55339
- const minNode = path74.reduce((a, b) => a < b ? a : b);
55346
+ if (next === start && path75.length >= 2) {
55347
+ const chain = [...path75, start];
55348
+ const minNode = path75.reduce((a, b) => a < b ? a : b);
55340
55349
  if (minNode === start) {
55341
55350
  cycles.push(chain);
55342
55351
  }
@@ -55344,15 +55353,15 @@ function findSimpleCycles(component, componentSet, adjacency) {
55344
55353
  }
55345
55354
  if (!visited.has(next) && !seen.has(next)) {
55346
55355
  visited.add(next);
55347
- path74.push(next);
55356
+ path75.push(next);
55348
55357
  dfs2(next);
55349
- path74.pop();
55358
+ path75.pop();
55350
55359
  visited.delete(next);
55351
55360
  }
55352
55361
  }
55353
55362
  };
55354
55363
  var dfs = dfs2;
55355
- const path74 = [start];
55364
+ const path75 = [start];
55356
55365
  const visited = /* @__PURE__ */ new Set([start]);
55357
55366
  dfs2(start);
55358
55367
  seen.add(start);
@@ -55374,7 +55383,7 @@ function findShortestCycle(start, componentSet, adjacency) {
55374
55383
  visited.add(next);
55375
55384
  }
55376
55385
  while (queue.length > 0) {
55377
- const { node: node2, path: path74 } = queue.shift();
55386
+ const { node: node2, path: path75 } = queue.shift();
55378
55387
  const nexts = adjacency.get(node2);
55379
55388
  if (!nexts)
55380
55389
  continue;
@@ -55382,11 +55391,11 @@ function findShortestCycle(start, componentSet, adjacency) {
55382
55391
  if (!componentSet.has(next))
55383
55392
  continue;
55384
55393
  if (next === start) {
55385
- return [...path74, start];
55394
+ return [...path75, start];
55386
55395
  }
55387
55396
  if (!visited.has(next)) {
55388
55397
  visited.add(next);
55389
- queue.push({ node: next, path: [...path74, next] });
55398
+ queue.push({ node: next, path: [...path75, next] });
55390
55399
  }
55391
55400
  }
55392
55401
  }
@@ -82898,11 +82907,11 @@ var init_entropy = __esm({
82898
82907
  });
82899
82908
 
82900
82909
  // packages/analyzer/dist/rules/security/stopwords.js
82901
- var STOPWORDS;
82910
+ var STOPWORDS2;
82902
82911
  var init_stopwords = __esm({
82903
82912
  "packages/analyzer/dist/rules/security/stopwords.js"() {
82904
82913
  "use strict";
82905
- STOPWORDS = [
82914
+ STOPWORDS2 = [
82906
82915
  // Programming concepts
82907
82916
  "abstract",
82908
82917
  "accessor",
@@ -85637,7 +85646,7 @@ function scanForSecrets(value, context) {
85637
85646
  }
85638
85647
  if (rule.useStopwords) {
85639
85648
  const secretLower = secretValue.toLowerCase();
85640
- if (STOPWORDS.some((sw) => secretLower.includes(sw)))
85649
+ if (STOPWORDS2.some((sw) => secretLower.includes(sw)))
85641
85650
  continue;
85642
85651
  }
85643
85652
  if (rule.allowlist) {
@@ -138154,14 +138163,14 @@ var init_missing_error_status_code = __esm({
138154
138163
  });
138155
138164
 
138156
138165
  // packages/analyzer/dist/rules/architecture/visitors/javascript/route-without-auth-middleware.js
138157
- function isPublicPath(path74) {
138158
- return PUBLIC_PATH_PATTERNS.some((re) => re.test(path74));
138166
+ function isPublicPath(path75) {
138167
+ return PUBLIC_PATH_PATTERNS.some((re) => re.test(path75));
138159
138168
  }
138160
- function isUrlCredentialAuthedPath(path74) {
138161
- return URL_CREDENTIAL_PARAMS.test(path74);
138169
+ function isUrlCredentialAuthedPath(path75) {
138170
+ return URL_CREDENTIAL_PARAMS.test(path75);
138162
138171
  }
138163
- function isApiDocsPath(path74) {
138164
- return API_DOCS_PATH.test(path74);
138172
+ function isApiDocsPath(path75) {
138173
+ return API_DOCS_PATH.test(path75);
138165
138174
  }
138166
138175
  function isFrameworkRequestHandler(arg) {
138167
138176
  if (!arg)
@@ -138310,14 +138319,14 @@ var init_route_without_auth_middleware = __esm({
138310
138319
  return null;
138311
138320
  const firstArg = args.namedChildren[0];
138312
138321
  if (firstArg?.type === "string" || firstArg?.type === "template_string") {
138313
- const path74 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
138314
- if (isPublicPath(path74))
138322
+ const path75 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
138323
+ if (isPublicPath(path75))
138315
138324
  return null;
138316
- if (isUrlCredentialAuthedPath(path74))
138325
+ if (isUrlCredentialAuthedPath(path75))
138317
138326
  return null;
138318
- if (isApiDocsPath(path74))
138327
+ if (isApiDocsPath(path75))
138319
138328
  return null;
138320
- if (path74 === "*" || path74 === "(.*)" || path74 === "/*") {
138329
+ if (path75 === "*" || path75 === "(.*)" || path75 === "/*") {
138321
138330
  if (isFrameworkRequestHandler(args.namedChildren[args.namedChildren.length - 1])) {
138322
138331
  return null;
138323
138332
  }
@@ -173216,11 +173225,11 @@ var require_form_data = __commonJS({
173216
173225
  "use strict";
173217
173226
  var CombinedStream = require_combined_stream();
173218
173227
  var util2 = __require("util");
173219
- var path74 = __require("path");
173228
+ var path75 = __require("path");
173220
173229
  var http = __require("http");
173221
173230
  var https = __require("https");
173222
173231
  var parseUrl = __require("url").parse;
173223
- var fs67 = __require("fs");
173232
+ var fs68 = __require("fs");
173224
173233
  var Stream = __require("stream").Stream;
173225
173234
  var crypto6 = __require("crypto");
173226
173235
  var mime = require_mime_types();
@@ -173287,7 +173296,7 @@ var require_form_data = __commonJS({
173287
173296
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
173288
173297
  callback(null, value.end + 1 - (value.start ? value.start : 0));
173289
173298
  } else {
173290
- fs67.stat(value.path, function(err, stat) {
173299
+ fs68.stat(value.path, function(err, stat) {
173291
173300
  if (err) {
173292
173301
  callback(err);
173293
173302
  return;
@@ -173344,11 +173353,11 @@ var require_form_data = __commonJS({
173344
173353
  FormData2.prototype._getContentDisposition = function(value, options) {
173345
173354
  var filename;
173346
173355
  if (typeof options.filepath === "string") {
173347
- filename = path74.normalize(options.filepath).replace(/\\/g, "/");
173356
+ filename = path75.normalize(options.filepath).replace(/\\/g, "/");
173348
173357
  } else if (options.filename || value && (value.name || value.path)) {
173349
- filename = path74.basename(options.filename || value && (value.name || value.path));
173358
+ filename = path75.basename(options.filename || value && (value.name || value.path));
173350
173359
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
173351
- filename = path74.basename(value.client._httpMessage.path || "");
173360
+ filename = path75.basename(value.client._httpMessage.path || "");
173352
173361
  }
173353
173362
  if (filename) {
173354
173363
  return 'filename="' + filename + '"';
@@ -174578,9 +174587,9 @@ var require_axios = __commonJS({
174578
174587
  function removeBrackets(key4) {
174579
174588
  return utils$1.endsWith(key4, "[]") ? key4.slice(0, -2) : key4;
174580
174589
  }
174581
- function renderKey(path74, key4, dots) {
174582
- if (!path74) return key4;
174583
- return path74.concat(key4).map(function each(token, i) {
174590
+ function renderKey(path75, key4, dots) {
174591
+ if (!path75) return key4;
174592
+ return path75.concat(key4).map(function each(token, i) {
174584
174593
  token = removeBrackets(token);
174585
174594
  return !dots && i ? "[" + token + "]" : token;
174586
174595
  }).join(dots ? "." : "");
@@ -174628,13 +174637,13 @@ var require_axios = __commonJS({
174628
174637
  }
174629
174638
  return value;
174630
174639
  }
174631
- function defaultVisitor(value, key4, path74) {
174640
+ function defaultVisitor(value, key4, path75) {
174632
174641
  let arr = value;
174633
174642
  if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
174634
- formData.append(renderKey(path74, key4, dots), convertValue(value));
174643
+ formData.append(renderKey(path75, key4, dots), convertValue(value));
174635
174644
  return false;
174636
174645
  }
174637
- if (value && !path74 && typeof value === "object") {
174646
+ if (value && !path75 && typeof value === "object") {
174638
174647
  if (utils$1.endsWith(key4, "{}")) {
174639
174648
  key4 = metaTokens ? key4 : key4.slice(0, -2);
174640
174649
  value = JSON.stringify(value);
@@ -174653,7 +174662,7 @@ var require_axios = __commonJS({
174653
174662
  if (isVisitable(value)) {
174654
174663
  return true;
174655
174664
  }
174656
- formData.append(renderKey(path74, key4, dots), convertValue(value));
174665
+ formData.append(renderKey(path75, key4, dots), convertValue(value));
174657
174666
  return false;
174658
174667
  }
174659
174668
  const stack2 = [];
@@ -174662,16 +174671,16 @@ var require_axios = __commonJS({
174662
174671
  convertValue,
174663
174672
  isVisitable
174664
174673
  });
174665
- function build8(value, path74) {
174674
+ function build8(value, path75) {
174666
174675
  if (utils$1.isUndefined(value)) return;
174667
174676
  if (stack2.indexOf(value) !== -1) {
174668
- throw Error("Circular reference detected in " + path74.join("."));
174677
+ throw Error("Circular reference detected in " + path75.join("."));
174669
174678
  }
174670
174679
  stack2.push(value);
174671
174680
  utils$1.forEach(value, function each(el, key4) {
174672
- const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4, path74, exposedHelpers);
174681
+ const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4, path75, exposedHelpers);
174673
174682
  if (result === true) {
174674
- build8(el, path74 ? path74.concat(key4) : [key4]);
174683
+ build8(el, path75 ? path75.concat(key4) : [key4]);
174675
174684
  }
174676
174685
  });
174677
174686
  stack2.pop();
@@ -174860,7 +174869,7 @@ var require_axios = __commonJS({
174860
174869
  };
174861
174870
  function toURLEncodedForm(data, options) {
174862
174871
  return toFormData(data, new platform.classes.URLSearchParams(), {
174863
- visitor: function(value, key4, path74, helpers) {
174872
+ visitor: function(value, key4, path75, helpers) {
174864
174873
  if (platform.isNode && utils$1.isBuffer(value)) {
174865
174874
  this.append(key4, value.toString("base64"));
174866
174875
  return false;
@@ -174888,11 +174897,11 @@ var require_axios = __commonJS({
174888
174897
  return obj;
174889
174898
  }
174890
174899
  function formDataToJSON(formData) {
174891
- function buildPath(path74, value, target, index) {
174892
- let name = path74[index++];
174900
+ function buildPath(path75, value, target, index) {
174901
+ let name = path75[index++];
174893
174902
  if (name === "__proto__") return true;
174894
174903
  const isNumericKey = Number.isFinite(+name);
174895
- const isLast = index >= path74.length;
174904
+ const isLast = index >= path75.length;
174896
174905
  name = !name && utils$1.isArray(target) ? target.length : name;
174897
174906
  if (isLast) {
174898
174907
  if (utils$1.hasOwnProp(target, name)) {
@@ -174905,7 +174914,7 @@ var require_axios = __commonJS({
174905
174914
  if (!target[name] || !utils$1.isObject(target[name])) {
174906
174915
  target[name] = [];
174907
174916
  }
174908
- const result = buildPath(path74, value, target[name], index);
174917
+ const result = buildPath(path75, value, target[name], index);
174909
174918
  if (result && utils$1.isArray(target[name])) {
174910
174919
  target[name] = arrayToObject(target[name]);
174911
174920
  }
@@ -176223,9 +176232,9 @@ var require_axios = __commonJS({
176223
176232
  auth = urlUsername + ":" + urlPassword;
176224
176233
  }
176225
176234
  auth && headers.delete("authorization");
176226
- let path74;
176235
+ let path75;
176227
176236
  try {
176228
- path74 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
176237
+ path75 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
176229
176238
  } catch (err) {
176230
176239
  const customErr = new Error(err.message);
176231
176240
  customErr.config = config2;
@@ -176235,7 +176244,7 @@ var require_axios = __commonJS({
176235
176244
  }
176236
176245
  headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
176237
176246
  const options = {
176238
- path: path74,
176247
+ path: path75,
176239
176248
  method,
176240
176249
  headers: headers.toJSON(),
176241
176250
  agents: {
@@ -176441,14 +176450,14 @@ var require_axios = __commonJS({
176441
176450
  var cookies = platform.hasStandardBrowserEnv ? (
176442
176451
  // Standard browser envs support document.cookie
176443
176452
  {
176444
- write(name, value, expires, path74, domain, secure, sameSite) {
176453
+ write(name, value, expires, path75, domain, secure, sameSite) {
176445
176454
  if (typeof document === "undefined") return;
176446
176455
  const cookie = [`${name}=${encodeURIComponent(value)}`];
176447
176456
  if (utils$1.isNumber(expires)) {
176448
176457
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
176449
176458
  }
176450
- if (utils$1.isString(path74)) {
176451
- cookie.push(`path=${path74}`);
176459
+ if (utils$1.isString(path75)) {
176460
+ cookie.push(`path=${path75}`);
176452
176461
  }
176453
176462
  if (utils$1.isString(domain)) {
176454
176463
  cookie.push(`domain=${domain}`);
@@ -177600,8 +177609,8 @@ var require_windows = __commonJS({
177600
177609
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
177601
177610
  module.exports = isexe;
177602
177611
  isexe.sync = sync;
177603
- var fs67 = __require("fs");
177604
- function checkPathExt(path74, options) {
177612
+ var fs68 = __require("fs");
177613
+ function checkPathExt(path75, options) {
177605
177614
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
177606
177615
  if (!pathext) {
177607
177616
  return true;
@@ -177612,25 +177621,25 @@ var require_windows = __commonJS({
177612
177621
  }
177613
177622
  for (var i = 0; i < pathext.length; i++) {
177614
177623
  var p = pathext[i].toLowerCase();
177615
- if (p && path74.substr(-p.length).toLowerCase() === p) {
177624
+ if (p && path75.substr(-p.length).toLowerCase() === p) {
177616
177625
  return true;
177617
177626
  }
177618
177627
  }
177619
177628
  return false;
177620
177629
  }
177621
- function checkStat(stat, path74, options) {
177630
+ function checkStat(stat, path75, options) {
177622
177631
  if (!stat.isSymbolicLink() && !stat.isFile()) {
177623
177632
  return false;
177624
177633
  }
177625
- return checkPathExt(path74, options);
177634
+ return checkPathExt(path75, options);
177626
177635
  }
177627
- function isexe(path74, options, cb) {
177628
- fs67.stat(path74, function(er, stat) {
177629
- cb(er, er ? false : checkStat(stat, path74, options));
177636
+ function isexe(path75, options, cb) {
177637
+ fs68.stat(path75, function(er, stat) {
177638
+ cb(er, er ? false : checkStat(stat, path75, options));
177630
177639
  });
177631
177640
  }
177632
- function sync(path74, options) {
177633
- return checkStat(fs67.statSync(path74), path74, options);
177641
+ function sync(path75, options) {
177642
+ return checkStat(fs68.statSync(path75), path75, options);
177634
177643
  }
177635
177644
  }
177636
177645
  });
@@ -177640,14 +177649,14 @@ var require_mode = __commonJS({
177640
177649
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
177641
177650
  module.exports = isexe;
177642
177651
  isexe.sync = sync;
177643
- var fs67 = __require("fs");
177644
- function isexe(path74, options, cb) {
177645
- fs67.stat(path74, function(er, stat) {
177652
+ var fs68 = __require("fs");
177653
+ function isexe(path75, options, cb) {
177654
+ fs68.stat(path75, function(er, stat) {
177646
177655
  cb(er, er ? false : checkStat(stat, options));
177647
177656
  });
177648
177657
  }
177649
- function sync(path74, options) {
177650
- return checkStat(fs67.statSync(path74), options);
177658
+ function sync(path75, options) {
177659
+ return checkStat(fs68.statSync(path75), options);
177651
177660
  }
177652
177661
  function checkStat(stat, options) {
177653
177662
  return stat.isFile() && checkMode(stat, options);
@@ -177671,7 +177680,7 @@ var require_mode = __commonJS({
177671
177680
  // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
177672
177681
  var require_isexe = __commonJS({
177673
177682
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
177674
- var fs67 = __require("fs");
177683
+ var fs68 = __require("fs");
177675
177684
  var core2;
177676
177685
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
177677
177686
  core2 = require_windows();
@@ -177680,7 +177689,7 @@ var require_isexe = __commonJS({
177680
177689
  }
177681
177690
  module.exports = isexe;
177682
177691
  isexe.sync = sync;
177683
- function isexe(path74, options, cb) {
177692
+ function isexe(path75, options, cb) {
177684
177693
  if (typeof options === "function") {
177685
177694
  cb = options;
177686
177695
  options = {};
@@ -177690,7 +177699,7 @@ var require_isexe = __commonJS({
177690
177699
  throw new TypeError("callback not provided");
177691
177700
  }
177692
177701
  return new Promise(function(resolve11, reject) {
177693
- isexe(path74, options || {}, function(er, is) {
177702
+ isexe(path75, options || {}, function(er, is) {
177694
177703
  if (er) {
177695
177704
  reject(er);
177696
177705
  } else {
@@ -177699,7 +177708,7 @@ var require_isexe = __commonJS({
177699
177708
  });
177700
177709
  });
177701
177710
  }
177702
- core2(path74, options || {}, function(er, is) {
177711
+ core2(path75, options || {}, function(er, is) {
177703
177712
  if (er) {
177704
177713
  if (er.code === "EACCES" || options && options.ignoreErrors) {
177705
177714
  er = null;
@@ -177709,9 +177718,9 @@ var require_isexe = __commonJS({
177709
177718
  cb(er, is);
177710
177719
  });
177711
177720
  }
177712
- function sync(path74, options) {
177721
+ function sync(path75, options) {
177713
177722
  try {
177714
- return core2.sync(path74, options || {});
177723
+ return core2.sync(path75, options || {});
177715
177724
  } catch (er) {
177716
177725
  if (options && options.ignoreErrors || er.code === "EACCES") {
177717
177726
  return false;
@@ -177727,7 +177736,7 @@ var require_isexe = __commonJS({
177727
177736
  var require_which = __commonJS({
177728
177737
  "node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
177729
177738
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
177730
- var path74 = __require("path");
177739
+ var path75 = __require("path");
177731
177740
  var COLON = isWindows ? ";" : ":";
177732
177741
  var isexe = require_isexe();
177733
177742
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -177765,7 +177774,7 @@ var require_which = __commonJS({
177765
177774
  return opt.all && found.length ? resolve11(found) : reject(getNotFoundError(cmd));
177766
177775
  const ppRaw = pathEnv[i];
177767
177776
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
177768
- const pCmd = path74.join(pathPart, cmd);
177777
+ const pCmd = path75.join(pathPart, cmd);
177769
177778
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
177770
177779
  resolve11(subStep(p, i, 0));
177771
177780
  });
@@ -177792,7 +177801,7 @@ var require_which = __commonJS({
177792
177801
  for (let i = 0; i < pathEnv.length; i++) {
177793
177802
  const ppRaw = pathEnv[i];
177794
177803
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
177795
- const pCmd = path74.join(pathPart, cmd);
177804
+ const pCmd = path75.join(pathPart, cmd);
177796
177805
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
177797
177806
  for (let j = 0; j < pathExt.length; j++) {
177798
177807
  const cur = p + pathExt[j];
@@ -177840,7 +177849,7 @@ var require_path_key = __commonJS({
177840
177849
  var require_resolveCommand = __commonJS({
177841
177850
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
177842
177851
  "use strict";
177843
- var path74 = __require("path");
177852
+ var path75 = __require("path");
177844
177853
  var which = require_which();
177845
177854
  var getPathKey = require_path_key();
177846
177855
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -177858,7 +177867,7 @@ var require_resolveCommand = __commonJS({
177858
177867
  try {
177859
177868
  resolved = which.sync(parsed.command, {
177860
177869
  path: env[getPathKey({ env })],
177861
- pathExt: withoutPathExt ? path74.delimiter : void 0
177870
+ pathExt: withoutPathExt ? path75.delimiter : void 0
177862
177871
  });
177863
177872
  } catch (e) {
177864
177873
  } finally {
@@ -177867,7 +177876,7 @@ var require_resolveCommand = __commonJS({
177867
177876
  }
177868
177877
  }
177869
177878
  if (resolved) {
177870
- resolved = path74.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
177879
+ resolved = path75.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
177871
177880
  }
177872
177881
  return resolved;
177873
177882
  }
@@ -177921,8 +177930,8 @@ var require_shebang_command = __commonJS({
177921
177930
  if (!match4) {
177922
177931
  return null;
177923
177932
  }
177924
- const [path74, argument] = match4[0].replace(/#! ?/, "").split(" ");
177925
- const binary2 = path74.split("/").pop();
177933
+ const [path75, argument] = match4[0].replace(/#! ?/, "").split(" ");
177934
+ const binary2 = path75.split("/").pop();
177926
177935
  if (binary2 === "env") {
177927
177936
  return argument;
177928
177937
  }
@@ -177935,16 +177944,16 @@ var require_shebang_command = __commonJS({
177935
177944
  var require_readShebang = __commonJS({
177936
177945
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
177937
177946
  "use strict";
177938
- var fs67 = __require("fs");
177947
+ var fs68 = __require("fs");
177939
177948
  var shebangCommand = require_shebang_command();
177940
177949
  function readShebang(command) {
177941
177950
  const size = 150;
177942
177951
  const buffer = Buffer.alloc(size);
177943
177952
  let fd;
177944
177953
  try {
177945
- fd = fs67.openSync(command, "r");
177946
- fs67.readSync(fd, buffer, 0, size, 0);
177947
- fs67.closeSync(fd);
177954
+ fd = fs68.openSync(command, "r");
177955
+ fs68.readSync(fd, buffer, 0, size, 0);
177956
+ fs68.closeSync(fd);
177948
177957
  } catch (e) {
177949
177958
  }
177950
177959
  return shebangCommand(buffer.toString());
@@ -177957,7 +177966,7 @@ var require_readShebang = __commonJS({
177957
177966
  var require_parse2 = __commonJS({
177958
177967
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
177959
177968
  "use strict";
177960
- var path74 = __require("path");
177969
+ var path75 = __require("path");
177961
177970
  var resolveCommand = require_resolveCommand();
177962
177971
  var escape3 = require_escape();
177963
177972
  var readShebang = require_readShebang();
@@ -177982,7 +177991,7 @@ var require_parse2 = __commonJS({
177982
177991
  const needsShell = !isExecutableRegExp.test(commandFile);
177983
177992
  if (parsed.options.forceShell || needsShell) {
177984
177993
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
177985
- parsed.command = path74.normalize(parsed.command);
177994
+ parsed.command = path75.normalize(parsed.command);
177986
177995
  parsed.command = escape3.command(parsed.command);
177987
177996
  parsed.args = parsed.args.map((arg) => escape3.argument(arg, needsDoubleEscapeMetaChars));
177988
177997
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -178873,8 +178882,8 @@ var init_cli_provider = __esm({
178873
178882
  this._repoId = repoId;
178874
178883
  }
178875
178884
  /** Set target repo path — used as cwd when spawning CLI so Read tool accesses the right files. */
178876
- setRepoPath(path74) {
178877
- this._repoPath = path74;
178885
+ setRepoPath(path75) {
178886
+ this._repoPath = path75;
178878
178887
  }
178879
178888
  flushUsage() {
178880
178889
  if (this._usageRecords.length === 0)
@@ -182166,11 +182175,11 @@ var require_baseGet = __commonJS({
182166
182175
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/_baseGet.js"(exports, module) {
182167
182176
  var castPath = require_castPath();
182168
182177
  var toKey = require_toKey();
182169
- function baseGet(object, path74) {
182170
- path74 = castPath(path74, object);
182171
- var index = 0, length = path74.length;
182178
+ function baseGet(object, path75) {
182179
+ path75 = castPath(path75, object);
182180
+ var index = 0, length = path75.length;
182172
182181
  while (object != null && index < length) {
182173
- object = object[toKey(path74[index++])];
182182
+ object = object[toKey(path75[index++])];
182174
182183
  }
182175
182184
  return index && index == length ? object : void 0;
182176
182185
  }
@@ -182182,8 +182191,8 @@ var require_baseGet = __commonJS({
182182
182191
  var require_get2 = __commonJS({
182183
182192
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/get.js"(exports, module) {
182184
182193
  var baseGet = require_baseGet();
182185
- function get(object, path74, defaultValue) {
182186
- var result = object == null ? void 0 : baseGet(object, path74);
182194
+ function get(object, path75, defaultValue) {
182195
+ var result = object == null ? void 0 : baseGet(object, path75);
182187
182196
  return result === void 0 ? defaultValue : result;
182188
182197
  }
182189
182198
  module.exports = get;
@@ -182209,11 +182218,11 @@ var require_hasPath = __commonJS({
182209
182218
  var isIndex = require_isIndex();
182210
182219
  var isLength = require_isLength();
182211
182220
  var toKey = require_toKey();
182212
- function hasPath(object, path74, hasFunc) {
182213
- path74 = castPath(path74, object);
182214
- var index = -1, length = path74.length, result = false;
182221
+ function hasPath(object, path75, hasFunc) {
182222
+ path75 = castPath(path75, object);
182223
+ var index = -1, length = path75.length, result = false;
182215
182224
  while (++index < length) {
182216
- var key4 = toKey(path74[index]);
182225
+ var key4 = toKey(path75[index]);
182217
182226
  if (!(result = object != null && hasFunc(object, key4))) {
182218
182227
  break;
182219
182228
  }
@@ -182234,8 +182243,8 @@ var require_hasIn = __commonJS({
182234
182243
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/hasIn.js"(exports, module) {
182235
182244
  var baseHasIn = require_baseHasIn();
182236
182245
  var hasPath = require_hasPath();
182237
- function hasIn(object, path74) {
182238
- return object != null && hasPath(object, path74, baseHasIn);
182246
+ function hasIn(object, path75) {
182247
+ return object != null && hasPath(object, path75, baseHasIn);
182239
182248
  }
182240
182249
  module.exports = hasIn;
182241
182250
  }
@@ -182253,13 +182262,13 @@ var require_baseMatchesProperty = __commonJS({
182253
182262
  var toKey = require_toKey();
182254
182263
  var COMPARE_PARTIAL_FLAG = 1;
182255
182264
  var COMPARE_UNORDERED_FLAG = 2;
182256
- function baseMatchesProperty(path74, srcValue) {
182257
- if (isKey(path74) && isStrictComparable(srcValue)) {
182258
- return matchesStrictComparable(toKey(path74), srcValue);
182265
+ function baseMatchesProperty(path75, srcValue) {
182266
+ if (isKey(path75) && isStrictComparable(srcValue)) {
182267
+ return matchesStrictComparable(toKey(path75), srcValue);
182259
182268
  }
182260
182269
  return function(object) {
182261
- var objValue = get(object, path74);
182262
- return objValue === void 0 && objValue === srcValue ? hasIn(object, path74) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
182270
+ var objValue = get(object, path75);
182271
+ return objValue === void 0 && objValue === srcValue ? hasIn(object, path75) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
182263
182272
  };
182264
182273
  }
182265
182274
  module.exports = baseMatchesProperty;
@@ -182282,9 +182291,9 @@ var require_baseProperty = __commonJS({
182282
182291
  var require_basePropertyDeep = __commonJS({
182283
182292
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/_basePropertyDeep.js"(exports, module) {
182284
182293
  var baseGet = require_baseGet();
182285
- function basePropertyDeep(path74) {
182294
+ function basePropertyDeep(path75) {
182286
182295
  return function(object) {
182287
- return baseGet(object, path74);
182296
+ return baseGet(object, path75);
182288
182297
  };
182289
182298
  }
182290
182299
  module.exports = basePropertyDeep;
@@ -182298,8 +182307,8 @@ var require_property = __commonJS({
182298
182307
  var basePropertyDeep = require_basePropertyDeep();
182299
182308
  var isKey = require_isKey();
182300
182309
  var toKey = require_toKey();
182301
- function property(path74) {
182302
- return isKey(path74) ? baseProperty(toKey(path74)) : basePropertyDeep(path74);
182310
+ function property(path75) {
182311
+ return isKey(path75) ? baseProperty(toKey(path75)) : basePropertyDeep(path75);
182303
182312
  }
182304
182313
  module.exports = property;
182305
182314
  }
@@ -182361,8 +182370,8 @@ var require_has = __commonJS({
182361
182370
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/has.js"(exports, module) {
182362
182371
  var baseHas = require_baseHas();
182363
182372
  var hasPath = require_hasPath();
182364
- function has(object, path74) {
182365
- return object != null && hasPath(object, path74, baseHas);
182373
+ function has(object, path75) {
182374
+ return object != null && hasPath(object, path75, baseHas);
182366
182375
  }
182367
182376
  module.exports = has;
182368
182377
  }
@@ -184636,14 +184645,14 @@ var require_baseSet = __commonJS({
184636
184645
  var isIndex = require_isIndex();
184637
184646
  var isObject2 = require_isObject();
184638
184647
  var toKey = require_toKey();
184639
- function baseSet(object, path74, value, customizer) {
184648
+ function baseSet(object, path75, value, customizer) {
184640
184649
  if (!isObject2(object)) {
184641
184650
  return object;
184642
184651
  }
184643
- path74 = castPath(path74, object);
184644
- var index = -1, length = path74.length, lastIndex = length - 1, nested = object;
184652
+ path75 = castPath(path75, object);
184653
+ var index = -1, length = path75.length, lastIndex = length - 1, nested = object;
184645
184654
  while (nested != null && ++index < length) {
184646
- var key4 = toKey(path74[index]), newValue = value;
184655
+ var key4 = toKey(path75[index]), newValue = value;
184647
184656
  if (key4 === "__proto__" || key4 === "constructor" || key4 === "prototype") {
184648
184657
  return object;
184649
184658
  }
@@ -184651,7 +184660,7 @@ var require_baseSet = __commonJS({
184651
184660
  var objValue = nested[key4];
184652
184661
  newValue = customizer ? customizer(objValue, key4, nested) : void 0;
184653
184662
  if (newValue === void 0) {
184654
- newValue = isObject2(objValue) ? objValue : isIndex(path74[index + 1]) ? [] : {};
184663
+ newValue = isObject2(objValue) ? objValue : isIndex(path75[index + 1]) ? [] : {};
184655
184664
  }
184656
184665
  }
184657
184666
  assignValue(nested, key4, newValue);
@@ -184672,9 +184681,9 @@ var require_basePickBy = __commonJS({
184672
184681
  function basePickBy(object, paths, predicate) {
184673
184682
  var index = -1, length = paths.length, result = {};
184674
184683
  while (++index < length) {
184675
- var path74 = paths[index], value = baseGet(object, path74);
184676
- if (predicate(value, path74)) {
184677
- baseSet(result, castPath(path74, object), value);
184684
+ var path75 = paths[index], value = baseGet(object, path75);
184685
+ if (predicate(value, path75)) {
184686
+ baseSet(result, castPath(path75, object), value);
184678
184687
  }
184679
184688
  }
184680
184689
  return result;
@@ -184689,8 +184698,8 @@ var require_basePick = __commonJS({
184689
184698
  var basePickBy = require_basePickBy();
184690
184699
  var hasIn = require_hasIn();
184691
184700
  function basePick(object, paths) {
184692
- return basePickBy(object, paths, function(value, path74) {
184693
- return hasIn(object, path74);
184701
+ return basePickBy(object, paths, function(value, path75) {
184702
+ return hasIn(object, path75);
184694
184703
  });
184695
184704
  }
184696
184705
  module.exports = basePick;
@@ -185744,15 +185753,15 @@ var require_parent_dummy_chains = __commonJS({
185744
185753
  var node2 = g.node(v);
185745
185754
  var edgeObj = node2.edgeObj;
185746
185755
  var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w);
185747
- var path74 = pathData.path;
185756
+ var path75 = pathData.path;
185748
185757
  var lca = pathData.lca;
185749
185758
  var pathIdx = 0;
185750
- var pathV = path74[pathIdx];
185759
+ var pathV = path75[pathIdx];
185751
185760
  var ascending = true;
185752
185761
  while (v !== edgeObj.w) {
185753
185762
  node2 = g.node(v);
185754
185763
  if (ascending) {
185755
- while ((pathV = path74[pathIdx]) !== lca && g.node(pathV).maxRank < node2.rank) {
185764
+ while ((pathV = path75[pathIdx]) !== lca && g.node(pathV).maxRank < node2.rank) {
185756
185765
  pathIdx++;
185757
185766
  }
185758
185767
  if (pathV === lca) {
@@ -185760,10 +185769,10 @@ var require_parent_dummy_chains = __commonJS({
185760
185769
  }
185761
185770
  }
185762
185771
  if (!ascending) {
185763
- while (pathIdx < path74.length - 1 && g.node(pathV = path74[pathIdx + 1]).minRank <= node2.rank) {
185772
+ while (pathIdx < path75.length - 1 && g.node(pathV = path75[pathIdx + 1]).minRank <= node2.rank) {
185764
185773
  pathIdx++;
185765
185774
  }
185766
- pathV = path74[pathIdx];
185775
+ pathV = path75[pathIdx];
185767
185776
  }
185768
185777
  g.setParent(v, pathV);
185769
185778
  v = g.successors(v)[0];
@@ -187265,7 +187274,7 @@ var require_dagre = __commonJS({
187265
187274
  // apps/dashboard/server/src/index.ts
187266
187275
  init_env();
187267
187276
  import { createServer } from "http";
187268
- import path73 from "node:path";
187277
+ import path74 from "node:path";
187269
187278
 
187270
187279
  // node_modules/.pnpm/socket.io@4.8.3/node_modules/socket.io/wrapper.mjs
187271
187280
  var import_dist = __toESM(require_dist2(), 1);
@@ -187550,9 +187559,9 @@ function getIO() {
187550
187559
  // apps/dashboard/server/src/app.ts
187551
187560
  var import_express16 = __toESM(require_express2(), 1);
187552
187561
  var import_cors = __toESM(require_lib(), 1);
187553
- import fs66 from "node:fs";
187562
+ import fs67 from "node:fs";
187554
187563
  import { fileURLToPath as fileURLToPath6 } from "node:url";
187555
- import path72 from "node:path";
187564
+ import path73 from "node:path";
187556
187565
 
187557
187566
  // apps/dashboard/server/src/middleware/error.ts
187558
187567
  init_logger();
@@ -187760,7 +187769,7 @@ async function projectResolver(req, res, next) {
187760
187769
  // apps/dashboard/server/src/routes/repos.ts
187761
187770
  var import_express = __toESM(require_express2(), 1);
187762
187771
  init_dist();
187763
- import * as fs60 from "fs";
187772
+ import * as fs61 from "fs";
187764
187773
 
187765
187774
  // packages/core/dist/lib/errors.js
187766
187775
  function createAppError(message, statusCode) {
@@ -187806,8 +187815,8 @@ function pathspec(...paths) {
187806
187815
  cache.set(key4, paths);
187807
187816
  return key4;
187808
187817
  }
187809
- function isPathSpec(path74) {
187810
- return path74 instanceof String && cache.has(path74);
187818
+ function isPathSpec(path75) {
187819
+ return path75 instanceof String && cache.has(path75);
187811
187820
  }
187812
187821
  function toPaths(pathSpec) {
187813
187822
  return cache.get(pathSpec) || [];
@@ -187896,8 +187905,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
187896
187905
  function forEachLineWithContent(input, callback) {
187897
187906
  return toLinesWithContent(input, true).map((line) => callback(line));
187898
187907
  }
187899
- function folderExists(path74) {
187900
- return (0, import_file_exists.exists)(path74, import_file_exists.FOLDER);
187908
+ function folderExists(path75) {
187909
+ return (0, import_file_exists.exists)(path75, import_file_exists.FOLDER);
187901
187910
  }
187902
187911
  function append(target, item) {
187903
187912
  if (Array.isArray(target)) {
@@ -188301,8 +188310,8 @@ function checkIsRepoRootTask() {
188301
188310
  commands,
188302
188311
  format: "utf-8",
188303
188312
  onError,
188304
- parser(path74) {
188305
- return /^\.(git)?$/.test(path74.trim());
188313
+ parser(path75) {
188314
+ return /^\.(git)?$/.test(path75.trim());
188306
188315
  }
188307
188316
  };
188308
188317
  }
@@ -188736,11 +188745,11 @@ function parseGrep(grep) {
188736
188745
  const paths = /* @__PURE__ */ new Set();
188737
188746
  const results = {};
188738
188747
  forEachLineWithContent(grep, (input) => {
188739
- const [path74, line, preview] = input.split(NULL);
188740
- paths.add(path74);
188741
- (results[path74] = results[path74] || []).push({
188748
+ const [path75, line, preview] = input.split(NULL);
188749
+ paths.add(path75);
188750
+ (results[path75] = results[path75] || []).push({
188742
188751
  line: asNumber(line),
188743
- path: path74,
188752
+ path: path75,
188744
188753
  preview
188745
188754
  });
188746
188755
  });
@@ -189505,14 +189514,14 @@ var init_hash_object = __esm2({
189505
189514
  init_task();
189506
189515
  }
189507
189516
  });
189508
- function parseInit(bare, path74, text4) {
189517
+ function parseInit(bare, path75, text4) {
189509
189518
  const response = String(text4).trim();
189510
189519
  let result;
189511
189520
  if (result = initResponseRegex.exec(response)) {
189512
- return new InitSummary(bare, path74, false, result[1]);
189521
+ return new InitSummary(bare, path75, false, result[1]);
189513
189522
  }
189514
189523
  if (result = reInitResponseRegex.exec(response)) {
189515
- return new InitSummary(bare, path74, true, result[1]);
189524
+ return new InitSummary(bare, path75, true, result[1]);
189516
189525
  }
189517
189526
  let gitDir = "";
189518
189527
  const tokens = response.split(" ");
@@ -189523,7 +189532,7 @@ function parseInit(bare, path74, text4) {
189523
189532
  break;
189524
189533
  }
189525
189534
  }
189526
- return new InitSummary(bare, path74, /^re/i.test(response), gitDir);
189535
+ return new InitSummary(bare, path75, /^re/i.test(response), gitDir);
189527
189536
  }
189528
189537
  var InitSummary;
189529
189538
  var initResponseRegex;
@@ -189532,9 +189541,9 @@ var init_InitSummary = __esm2({
189532
189541
  "src/lib/responses/InitSummary.ts"() {
189533
189542
  "use strict";
189534
189543
  InitSummary = class {
189535
- constructor(bare, path74, existing, gitDir) {
189544
+ constructor(bare, path75, existing, gitDir) {
189536
189545
  this.bare = bare;
189537
- this.path = path74;
189546
+ this.path = path75;
189538
189547
  this.existing = existing;
189539
189548
  this.gitDir = gitDir;
189540
189549
  }
@@ -189546,7 +189555,7 @@ var init_InitSummary = __esm2({
189546
189555
  function hasBareCommand(command) {
189547
189556
  return command.includes(bareCommand);
189548
189557
  }
189549
- function initTask(bare = false, path74, customArgs) {
189558
+ function initTask(bare = false, path75, customArgs) {
189550
189559
  const commands = ["init", ...customArgs];
189551
189560
  if (bare && !hasBareCommand(commands)) {
189552
189561
  commands.splice(1, 0, bareCommand);
@@ -189555,7 +189564,7 @@ function initTask(bare = false, path74, customArgs) {
189555
189564
  commands,
189556
189565
  format: "utf-8",
189557
189566
  parser(text4) {
189558
- return parseInit(commands.includes("--bare"), path74, text4);
189567
+ return parseInit(commands.includes("--bare"), path75, text4);
189559
189568
  }
189560
189569
  };
189561
189570
  }
@@ -190371,12 +190380,12 @@ var init_FileStatusSummary = __esm2({
190371
190380
  "use strict";
190372
190381
  fromPathRegex = /^(.+)\0(.+)$/;
190373
190382
  FileStatusSummary = class {
190374
- constructor(path74, index, working_dir) {
190375
- this.path = path74;
190383
+ constructor(path75, index, working_dir) {
190384
+ this.path = path75;
190376
190385
  this.index = index;
190377
190386
  this.working_dir = working_dir;
190378
190387
  if (index === "R" || working_dir === "R") {
190379
- const detail = fromPathRegex.exec(path74) || [null, path74, path74];
190388
+ const detail = fromPathRegex.exec(path75) || [null, path75, path75];
190380
190389
  this.from = detail[2] || "";
190381
190390
  this.path = detail[1] || "";
190382
190391
  }
@@ -190407,14 +190416,14 @@ function splitLine(result, lineStr) {
190407
190416
  default:
190408
190417
  return;
190409
190418
  }
190410
- function data(index, workingDir, path74) {
190419
+ function data(index, workingDir, path75) {
190411
190420
  const raw = `${index}${workingDir}`;
190412
190421
  const handler = parsers6.get(raw);
190413
190422
  if (handler) {
190414
- handler(result, path74);
190423
+ handler(result, path75);
190415
190424
  }
190416
190425
  if (raw !== "##" && raw !== "!!") {
190417
- result.files.push(new FileStatusSummary(path74, index, workingDir));
190426
+ result.files.push(new FileStatusSummary(path75, index, workingDir));
190418
190427
  }
190419
190428
  }
190420
190429
  }
@@ -190766,9 +190775,9 @@ var init_simple_git_api = __esm2({
190766
190775
  next
190767
190776
  );
190768
190777
  }
190769
- hashObject(path74, write) {
190778
+ hashObject(path75, write) {
190770
190779
  return this._runTask(
190771
- hashObjectTask(path74, write === true),
190780
+ hashObjectTask(path75, write === true),
190772
190781
  trailingFunctionArgument(arguments)
190773
190782
  );
190774
190783
  }
@@ -191122,8 +191131,8 @@ var init_branch = __esm2({
191122
191131
  }
191123
191132
  });
191124
191133
  function toPath(input) {
191125
- const path74 = input.trim().replace(/^["']|["']$/g, "");
191126
- return path74 && normalize(path74);
191134
+ const path75 = input.trim().replace(/^["']|["']$/g, "");
191135
+ return path75 && normalize(path75);
191127
191136
  }
191128
191137
  var parseCheckIgnore;
191129
191138
  var init_CheckIgnore = __esm2({
@@ -191408,8 +191417,8 @@ __export2(sub_module_exports, {
191408
191417
  subModuleTask: () => subModuleTask,
191409
191418
  updateSubModuleTask: () => updateSubModuleTask
191410
191419
  });
191411
- function addSubModuleTask(repo, path74) {
191412
- return subModuleTask(["add", repo, path74]);
191420
+ function addSubModuleTask(repo, path75) {
191421
+ return subModuleTask(["add", repo, path75]);
191413
191422
  }
191414
191423
  function initSubModuleTask(customArgs) {
191415
191424
  return subModuleTask(["init", ...customArgs]);
@@ -191723,8 +191732,8 @@ var require_git = __commonJS2({
191723
191732
  }
191724
191733
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
191725
191734
  };
191726
- Git2.prototype.submoduleAdd = function(repo, path74, then) {
191727
- return this._runTask(addSubModuleTask2(repo, path74), trailingFunctionArgument2(arguments));
191735
+ Git2.prototype.submoduleAdd = function(repo, path75, then) {
191736
+ return this._runTask(addSubModuleTask2(repo, path75), trailingFunctionArgument2(arguments));
191728
191737
  };
191729
191738
  Git2.prototype.submoduleUpdate = function(args, then) {
191730
191739
  return this._runTask(
@@ -196995,6 +197004,26 @@ var RelationSchema = external_exports.object({
196995
197004
  /** Optional human-readable rationale. */
196996
197005
  note: external_exports.string().optional()
196997
197006
  });
197007
+ var ConflictResolutionSchema = external_exports.object({
197008
+ /** Repo-relative path / DocRef of the first doc in the dispute. */
197009
+ docA: external_exports.string(),
197010
+ /** docA's conflicting section heading, or `null` for its preamble/lead. */
197011
+ anchorA: external_exports.string().nullable(),
197012
+ /** docA's verbatim disputed sentence, when the detector captured one. */
197013
+ quoteA: external_exports.string().optional(),
197014
+ /** Repo-relative path / DocRef of the second doc in the dispute. */
197015
+ docB: external_exports.string(),
197016
+ /** docB's conflicting section heading, or `null` for its preamble/lead. */
197017
+ anchorB: external_exports.string().nullable(),
197018
+ /** docB's verbatim disputed sentence, when the detector captured one. */
197019
+ quoteB: external_exports.string().optional(),
197020
+ /** Which side wins, or `dismissed` (not a real conflict). */
197021
+ verdict: external_exports.enum(["a", "b", "dismissed"]),
197022
+ /** ISO timestamp the resolution was recorded. */
197023
+ resolvedAt: external_exports.string(),
197024
+ /** Optional human-readable rationale. */
197025
+ note: external_exports.string().optional()
197026
+ });
196998
197027
  var ManualAreaSchema = external_exports.object({
196999
197028
  /** Repo-relative path / DocRef of the doc. */
197000
197029
  doc: external_exports.string(),
@@ -197019,7 +197048,13 @@ var DecisionsFileSchema = external_exports.object({
197019
197048
  /** User-authored doc→doc relations (replace/precedence/keep-both). */
197020
197049
  relations: external_exports.array(RelationSchema).default([]),
197021
197050
  /** User overrides of a doc's auto-assigned area tags. */
197022
- manualAreas: external_exports.array(ManualAreaSchema).default([])
197051
+ manualAreas: external_exports.array(ManualAreaSchema).default([]),
197052
+ /**
197053
+ * SECTION-scoped conflict verdicts (plan item 31) — pick-a-side / dismissal on
197054
+ * one flagged disagreement, keyed by dispute identity. Optional with a `[]`
197055
+ * default so a decisions.json written before item 31 still parses.
197056
+ */
197057
+ conflictResolutions: external_exports.array(ConflictResolutionSchema).default([])
197023
197058
  });
197024
197059
 
197025
197060
  // packages/spec-consolidator/dist/corpus-types.js
@@ -197154,7 +197189,17 @@ var OverlapSectionSchema = external_exports.object({
197154
197189
  * from older corpora still parses; `null` is the preamble marker the viewer
197155
197190
  * bands as the pre-first-heading block.
197156
197191
  */
197157
- heading: external_exports.string().nullable()
197192
+ heading: external_exports.string().nullable(),
197193
+ /**
197194
+ * A short verbatim excerpt (≤ ~25 words) of the disputed sentence, copied from
197195
+ * the doc — the model's evidence for the heading it picked. Persisted (optional,
197196
+ * so older corpora without it still parse) for verification transparency and so
197197
+ * the viewer can later highlight the exact disputed sentence, not just band the
197198
+ * section. Consumed at assembly by `verifyOverlapSections` to anchor the pointer
197199
+ * by exact location; NOT part of the cross-area dedup identity (that stays
197200
+ * doc + heading).
197201
+ */
197202
+ quote: external_exports.string().optional()
197158
197203
  });
197159
197204
  var OverlapSchema = external_exports.object({
197160
197205
  /** The two docs that overlap, by ref. */
@@ -197947,13 +197992,241 @@ import { createHash as createHash6 } from "node:crypto";
197947
197992
  import fs28 from "node:fs";
197948
197993
  init_transport();
197949
197994
  init_dist();
197995
+
197996
+ // packages/spec-consolidator/dist/pointer-verifier.js
197997
+ init_dist();
197998
+ var MIN_MEANINGFUL_SCORE = 1.5;
197999
+ var NEGLIGIBLE_RATIO = 0.25;
198000
+ var STOPWORDS = /* @__PURE__ */ new Set([
198001
+ "the",
198002
+ "a",
198003
+ "an",
198004
+ "and",
198005
+ "or",
198006
+ "but",
198007
+ "if",
198008
+ "then",
198009
+ "else",
198010
+ "of",
198011
+ "to",
198012
+ "in",
198013
+ "on",
198014
+ "at",
198015
+ "by",
198016
+ "for",
198017
+ "with",
198018
+ "as",
198019
+ "is",
198020
+ "are",
198021
+ "was",
198022
+ "were",
198023
+ "be",
198024
+ "been",
198025
+ "being",
198026
+ "it",
198027
+ "its",
198028
+ "this",
198029
+ "that",
198030
+ "these",
198031
+ "those",
198032
+ "they",
198033
+ "them",
198034
+ "their",
198035
+ "there",
198036
+ "here",
198037
+ "no",
198038
+ "not",
198039
+ "yes",
198040
+ "so",
198041
+ "than",
198042
+ "too",
198043
+ "very",
198044
+ "can",
198045
+ "could",
198046
+ "will",
198047
+ "would",
198048
+ "shall",
198049
+ "should",
198050
+ "may",
198051
+ "might",
198052
+ "must",
198053
+ "do",
198054
+ "does",
198055
+ "did",
198056
+ "done",
198057
+ "has",
198058
+ "have",
198059
+ "had",
198060
+ "from",
198061
+ "up",
198062
+ "out",
198063
+ "down",
198064
+ "over",
198065
+ "under",
198066
+ "again",
198067
+ "we",
198068
+ "you",
198069
+ "your",
198070
+ "our",
198071
+ "us",
198072
+ "i",
198073
+ "he",
198074
+ "she",
198075
+ "his",
198076
+ "her",
198077
+ "each",
198078
+ "any",
198079
+ "all",
198080
+ "both",
198081
+ "some",
198082
+ "such",
198083
+ "only",
198084
+ "own",
198085
+ "same",
198086
+ "more",
198087
+ "most",
198088
+ "other",
198089
+ "into",
198090
+ "about",
198091
+ "when",
198092
+ "where",
198093
+ "which",
198094
+ "who",
198095
+ "whom",
198096
+ "what",
198097
+ "how",
198098
+ "why",
198099
+ "per",
198100
+ "via",
198101
+ "also"
198102
+ ]);
198103
+ function tokenize(text4, drop) {
198104
+ const lowered = text4.toLowerCase().replace(/[`*_~#>]/g, " ");
198105
+ const out = [];
198106
+ for (const raw of lowered.split(/[^a-z0-9]+/)) {
198107
+ if (raw.length < 2)
198108
+ continue;
198109
+ if (STOPWORDS.has(raw))
198110
+ continue;
198111
+ if (drop.has(raw))
198112
+ continue;
198113
+ out.push(raw);
198114
+ }
198115
+ return out;
198116
+ }
198117
+ function pathWords(p) {
198118
+ return p.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 2);
198119
+ }
198120
+ var HEADING_RE = /^ {0,3}#{1,6}\s+(.*)$/;
198121
+ function splitDocSections(body, drop) {
198122
+ const raws = [];
198123
+ let cur = { heading: "", text: "" };
198124
+ for (const line of body.split(/\r?\n/)) {
198125
+ const m = HEADING_RE.exec(line);
198126
+ if (m) {
198127
+ if (cur.text.trim() || cur.heading)
198128
+ raws.push(cur);
198129
+ cur = { heading: m[1].trim(), text: `${line}
198130
+ ` };
198131
+ } else {
198132
+ cur.text += `${line}
198133
+ `;
198134
+ }
198135
+ }
198136
+ if (cur.text.trim() || cur.heading)
198137
+ raws.push(cur);
198138
+ return raws.map((r) => ({
198139
+ realHeading: r.heading === "" ? null : r.heading,
198140
+ tokens: new Set(tokenize(r.text, drop)),
198141
+ text: r.text
198142
+ }));
198143
+ }
198144
+ function headingKey(h) {
198145
+ return h.replace(/[`*_~]/g, "").trim().toLowerCase();
198146
+ }
198147
+ function locateQuote(sections, quote) {
198148
+ const needle = normalizeQuote(quote);
198149
+ if (!needle)
198150
+ return [];
198151
+ const hits = [];
198152
+ for (let i = 0; i < sections.length; i++) {
198153
+ if (normalizeQuote(sections[i].text).includes(needle))
198154
+ hits.push(i);
198155
+ }
198156
+ return hits;
198157
+ }
198158
+ function scoreSections(sections, noteTokens) {
198159
+ const N = sections.length;
198160
+ const df = /* @__PURE__ */ new Map();
198161
+ for (const s of sections)
198162
+ for (const t of s.tokens)
198163
+ df.set(t, (df.get(t) ?? 0) + 1);
198164
+ const idf = (t) => {
198165
+ const d = df.get(t) ?? 0;
198166
+ if (d === 0)
198167
+ return 0;
198168
+ return Math.max(0, Math.log2((N + 1) / (d + 1)));
198169
+ };
198170
+ return sections.map((s) => {
198171
+ let score = 0;
198172
+ for (const t of noteTokens)
198173
+ if (s.tokens.has(t))
198174
+ score += idf(t);
198175
+ return score;
198176
+ });
198177
+ }
198178
+ function verifyOverlapSections(input) {
198179
+ const { docs, note, sections, bodyOf } = input;
198180
+ if (sections.length === 0)
198181
+ return [...sections];
198182
+ const drop = /* @__PURE__ */ new Set([...pathWords(docs[0]), ...pathWords(docs[1])]);
198183
+ const noteTokens = new Set(tokenize(note, drop));
198184
+ return sections.map((ptr) => {
198185
+ const body = bodyOf(ptr.doc);
198186
+ if (body === void 0)
198187
+ return { ...ptr };
198188
+ const candidates = splitDocSections(body, drop);
198189
+ if (candidates.length === 0)
198190
+ return { ...ptr };
198191
+ let pointedIdx;
198192
+ if (ptr.heading === null) {
198193
+ pointedIdx = 0;
198194
+ } else {
198195
+ const key4 = headingKey(ptr.heading);
198196
+ pointedIdx = candidates.findIndex((c) => c.realHeading !== null && headingKey(c.realHeading) === key4);
198197
+ }
198198
+ if (ptr.quote !== void 0) {
198199
+ const hits = locateQuote(candidates, ptr.quote);
198200
+ if (hits.length > 0) {
198201
+ if (pointedIdx >= 0 && hits.includes(pointedIdx))
198202
+ return { ...ptr };
198203
+ const target = hits[0];
198204
+ return { ...ptr, heading: target === 0 ? null : candidates[target].realHeading };
198205
+ }
198206
+ }
198207
+ if (noteTokens.size === 0)
198208
+ return { ...ptr };
198209
+ const scores = scoreSections(candidates, noteTokens);
198210
+ let bestIdx = 0;
198211
+ for (let i = 1; i < scores.length; i++)
198212
+ if (scores[i] > scores[bestIdx])
198213
+ bestIdx = i;
198214
+ const bestScore = scores[bestIdx];
198215
+ const pointedScore = pointedIdx >= 0 ? scores[pointedIdx] : 0;
198216
+ const reanchor = bestIdx !== pointedIdx && bestScore >= MIN_MEANINGFUL_SCORE && pointedScore < MIN_MEANINGFUL_SCORE && pointedScore <= NEGLIGIBLE_RATIO * bestScore;
198217
+ if (!reanchor)
198218
+ return { ...ptr };
198219
+ return { ...ptr, heading: bestIdx === 0 ? null : candidates[bestIdx].realHeading };
198220
+ });
198221
+ }
198222
+
198223
+ // packages/spec-consolidator/dist/overlap-detector.js
197950
198224
  var DEFAULT_MAX_PAIRS_PER_AREA = 60;
197951
198225
  async function flagOverlaps(repoRoot, areas, docs, opts = {}) {
197952
198226
  const result = /* @__PURE__ */ new Map();
197953
198227
  if (opts.enabled === false)
197954
198228
  return result;
197955
198229
  const byPath = new Map(docs.map((d) => [d.path, d]));
197956
- const resolved = resolvedPairKeys(opts.relations ?? []);
197957
198230
  const maxPairs = opts.maxPairsPerArea ?? DEFAULT_MAX_PAIRS_PER_AREA;
197958
198231
  const vocab = opts.vocab;
197959
198232
  const pairs2 = [];
@@ -197968,8 +198241,6 @@ async function flagOverlaps(repoRoot, areas, docs, opts = {}) {
197968
198241
  const b = byPath.get(y);
197969
198242
  if (!a || !b)
197970
198243
  return;
197971
- if (isResolved(resolved, area.id, x, y))
197972
- return;
197973
198244
  const key4 = x < y ? `${x}\0${y}` : `${y}\0${x}`;
197974
198245
  if (seen.has(key4))
197975
198246
  return;
@@ -198036,6 +198307,19 @@ async function flagOverlaps(repoRoot, areas, docs, opts = {}) {
198036
198307
  };
198037
198308
  launch();
198038
198309
  });
198310
+ for (const list of result.values()) {
198311
+ for (const overlap of list) {
198312
+ overlap.sections = verifyOverlapSections({
198313
+ docs: overlap.docs,
198314
+ note: overlap.note,
198315
+ sections: overlap.sections,
198316
+ bodyOf: (ref) => {
198317
+ const d = byPath.get(ref);
198318
+ return d ? docBody2(d) : void 0;
198319
+ }
198320
+ });
198321
+ }
198322
+ }
198039
198323
  const entries = [...result].flatMap(([area, list]) => list.map((overlap) => ({ area, overlap })));
198040
198324
  const merged = dedupeCrossAreaOverlaps(entries);
198041
198325
  result.clear();
@@ -198059,22 +198343,6 @@ async function examineOne(repoRoot, areaId, a, b, runner2) {
198059
198343
  await writeCache3(repoRoot, cacheKey, verdict);
198060
198344
  return verdict;
198061
198345
  }
198062
- function resolvedPairKeys(relations) {
198063
- const set2 = /* @__PURE__ */ new Set();
198064
- for (const r of relations) {
198065
- if (r.scope)
198066
- set2.add(scopedKey2(r.scope, r.older, r.newer));
198067
- else
198068
- set2.add(globalKey(r.older, r.newer));
198069
- }
198070
- return set2;
198071
- }
198072
- var sortedPair = (x, y) => [x, y].sort().join(" ");
198073
- var globalKey = (x, y) => `* ${sortedPair(x, y)}`;
198074
- var scopedKey2 = (scope, x, y) => `${scope} ${sortedPair(x, y)}`;
198075
- function isResolved(set2, areaId, x, y) {
198076
- return set2.has(globalKey(x, y)) || set2.has(scopedKey2(areaId, x, y));
198077
- }
198078
198346
  var OVERLAP_DETECTOR_SYSTEM_PROMPT = `You compare TWO documentation files that both cover the same AREA of a software system and decide whether they may DISAGREE.
198079
198347
 
198080
198348
  ${OUTPUT_ONLY_GUARDRAIL}
@@ -198090,9 +198358,12 @@ NOT a disagreement (do NOT flag):
198090
198358
 
198091
198359
  Bias: when there is a PLAUSIBLE contradiction a human should check, flag it. When the docs are clearly complementary or agree, do not.
198092
198360
 
198093
- When you flag an overlap, also identify the SECTIONS that conflict: the nearest markdown heading (the \`#\`/\`##\`/\`###\` title, verbatim, WITHOUT the leading #s) above the conflicting text in EACH doc. List one entry per side; omit a side only when it genuinely has no conflicting passage.
198361
+ When you flag an overlap, point at WHERE each side's disputed claim lives. Below each doc you are given a CLOSED list of that doc's section options \u2014 its headings, plus a "lead" option. Do NOT recall or guess a heading; SELECT from the list. For EACH side output a pointer with two fields:
198362
+ - \`heading\`: EXACTLY one of that doc's listed section headings, copied verbatim \u2014 OR the JSON literal \`null\` (not the string "null", not "") for the LEAD, the text ABOVE its first heading (or, when the doc opens straight with a title, that opening title block). Never emit a heading that is not one of the listed options.
198363
+ - \`quote\`: a SHORT verbatim excerpt (\u2264 25 words) of the disputed sentence, copied EXACTLY from that doc \u2014 the words that state the claim in dispute. This is your evidence for the heading you picked; copy it, do not paraphrase.
198364
+ List one entry per side; omit a side only when it genuinely has no conflicting passage.
198094
198365
 
198095
- PREAMBLE: when a doc's conflicting passage sits ABOVE its first \`#\` heading \u2014 the preamble block (a README's badges, tagline, or the intro line before any heading) \u2014 there is no heading to name. Set that side's \`heading\` to the JSON literal \`null\` (not the string "null", not ""). Use \`null\` ONLY for that pre-first-heading block; whenever the passage is under a heading, name the heading verbatim.
198366
+ PREAMBLE: use \`heading\`: \`null\` ONLY for that lead/preamble block; whenever the disputed passage is under a listed heading, select that heading verbatim.
198096
198367
 
198097
198368
  In the NOTE, refer to each doc by its FILENAME (the basename shown in the header, e.g. \`users.md\`) \u2014 NEVER "doc A" / "doc B", which mean nothing to the reader.
198098
198369
 
@@ -198100,13 +198371,19 @@ Output ONLY a JSON object, no prose, no code fences:
198100
198371
 
198101
198372
  { "overlap": true,
198102
198373
  "note": "users.md uses auth0_id; identity.md uses auth0_sub for the same user column",
198103
- "sections": [ { "side": "A", "heading": "User model" }, { "side": "B", "heading": "Identity" } ] }
198374
+ "sections": [
198375
+ { "side": "A", "heading": "User model", "quote": "the auth0_id column stores the Auth0 subject" },
198376
+ { "side": "B", "heading": "Identity", "quote": "we persist the Auth0 subject in auth0_sub" }
198377
+ ] }
198104
198378
 
198105
- Preamble example \u2014 doc A's claim is a README badge/tagline above any heading, so its side uses null:
198379
+ Preamble example \u2014 doc A's disputed claim is a README tagline ABOVE its first heading, so its side uses \`heading\`: null and quotes that tagline verbatim:
198106
198380
 
198107
198381
  { "overlap": true,
198108
198382
  "note": "README.md lists C# as a supported language in the preamble; plan.md's Tech Stack omits it",
198109
- "sections": [ { "side": "A", "heading": null }, { "side": "B", "heading": "Tech Stack" } ] }
198383
+ "sections": [
198384
+ { "side": "A", "heading": null, "quote": "Supports TypeScript, Python, and C# out of the box" },
198385
+ { "side": "B", "heading": "Tech Stack", "quote": "The stack is TypeScript and Python" }
198386
+ ] }
198110
198387
 
198111
198388
  Use { "overlap": false, "note": "", "sections": [] } when they are complementary or agree. The note is shown to the user \u2014 name the specific thing that differs.`;
198112
198389
  var OVERLAP_PREVIEW_LINES = 120;
@@ -198140,31 +198417,59 @@ function hasConcernHeading(doc, concern, vocab) {
198140
198417
  }
198141
198418
  return false;
198142
198419
  }
198420
+ function sectionHeadings(body) {
198421
+ const out = [];
198422
+ for (const line of body.split(/\r?\n/)) {
198423
+ const m = /^ {0,3}#{1,6}\s+(.*)$/.exec(line);
198424
+ if (!m)
198425
+ continue;
198426
+ const text4 = m[1].replace(/\s*#*\s*$/, "").trim();
198427
+ if (text4)
198428
+ out.push(text4);
198429
+ }
198430
+ return out;
198431
+ }
198432
+ function sectionOptions(slice5) {
198433
+ const lines = [" - the lead (text above the first heading, or the opening title block) \u2192 use heading: null"];
198434
+ for (const h of sectionHeadings(slice5))
198435
+ lines.push(` - ${h}`);
198436
+ return lines;
198437
+ }
198143
198438
  function buildOverlapUserPrompt(areaId, a, b) {
198144
198439
  const slice5 = (d) => docBody2(d).split(/\r?\n/).slice(0, OVERLAP_PREVIEW_LINES).join("\n");
198440
+ const sliceA = slice5(a);
198441
+ const sliceB = slice5(b);
198145
198442
  return [
198146
198443
  `Area: ${areaId}`,
198147
198444
  "",
198148
198445
  `--- doc A: ${a.path} ---`,
198149
- slice5(a),
198446
+ sliceA,
198150
198447
  `--- end doc A ---`,
198151
198448
  "",
198152
198449
  `--- doc B: ${b.path} ---`,
198153
- slice5(b),
198450
+ sliceB,
198154
198451
  `--- end doc B ---`,
198155
198452
  "",
198453
+ "SECTION OPTIONS \u2014 each side pointer MUST be one of these (verbatim), or the lead (heading: null):",
198454
+ "",
198455
+ `doc A (${a.path}):`,
198456
+ ...sectionOptions(sliceA),
198457
+ "",
198458
+ `doc B (${b.path}):`,
198459
+ ...sectionOptions(sliceB),
198460
+ "",
198156
198461
  "Return the JSON object as specified."
198157
198462
  ].join("\n");
198158
198463
  }
198159
198464
  var LlmOverlapSchema = external_exports.object({
198160
198465
  overlap: external_exports.boolean(),
198161
198466
  note: external_exports.string().default(""),
198162
- sections: external_exports.array(external_exports.object({ side: external_exports.enum(["A", "B"]), heading: external_exports.string().nullable() })).default([])
198467
+ sections: external_exports.array(external_exports.object({ side: external_exports.enum(["A", "B"]), heading: external_exports.string().nullable(), quote: external_exports.string().optional() })).default([])
198163
198468
  });
198164
198469
  var OverlapVerdictSchema = external_exports.object({
198165
198470
  overlap: external_exports.boolean(),
198166
198471
  note: external_exports.string().default(""),
198167
- sections: external_exports.array(external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable() })).default([])
198472
+ sections: external_exports.array(external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable(), quote: external_exports.string().optional() })).default([])
198168
198473
  });
198169
198474
  function spawnOverlapRunner(opts = {}) {
198170
198475
  const transport = opts.transport ?? cliTransport({ bin: opts.bin });
@@ -198184,7 +198489,11 @@ function spawnOverlapRunner(opts = {}) {
198184
198489
  return {
198185
198490
  overlap: inner.overlap,
198186
198491
  note: inner.note,
198187
- sections: inner.sections.map((s) => ({ doc: s.side === "A" ? a.path : b.path, heading: s.heading }))
198492
+ sections: inner.sections.map((s) => ({
198493
+ doc: s.side === "A" ? a.path : b.path,
198494
+ heading: s.heading,
198495
+ ...s.quote !== void 0 ? { quote: s.quote } : {}
198496
+ }))
198188
198497
  };
198189
198498
  };
198190
198499
  }
@@ -198346,12 +198655,12 @@ function prefilterDocs(docs, manualIncludes = []) {
198346
198655
  if (reason)
198347
198656
  reasons.set(doc.path, reason);
198348
198657
  }
198349
- for (const { path: path74, reason } of dedupeNearDuplicates(docs.filter((d) => !manualSet.has(d.path) && !reasons.has(d.path)))) {
198350
- reasons.set(path74, reason);
198658
+ for (const { path: path75, reason } of dedupeNearDuplicates(docs.filter((d) => !manualSet.has(d.path) && !reasons.has(d.path)))) {
198659
+ reasons.set(path75, reason);
198351
198660
  }
198352
198661
  return {
198353
198662
  toClassify: docs.filter((d) => !reasons.has(d.path)),
198354
- skipped: [...reasons].map(([path74, reason]) => ({ path: path74, reason }))
198663
+ skipped: [...reasons].map(([path75, reason]) => ({ path: path75, reason }))
198355
198664
  };
198356
198665
  }
198357
198666
  async function planRelevanceWork(repoRoot, docs, manualIncludes = []) {
@@ -198669,7 +198978,6 @@ async function curate(repoRoot, opts = {}) {
198669
198978
  const overlapsByArea = await flagOverlaps(repoRoot, grouped.areas, docs, {
198670
198979
  runner: opts.overlapRunner,
198671
198980
  enabled: opts.disableOverlapDetection !== true,
198672
- relations,
198673
198981
  vocab,
198674
198982
  transport: opts.transport,
198675
198983
  model: models.overlap,
@@ -198715,7 +199023,8 @@ var EMPTY_DECISIONS = {
198715
199023
  manualIncludes: [],
198716
199024
  manualExcludes: [],
198717
199025
  relations: [],
198718
- manualAreas: []
199026
+ manualAreas: [],
199027
+ conflictResolutions: []
198719
199028
  };
198720
199029
  function readCorpusDecisions(repoRoot) {
198721
199030
  const file = path27.join(repoRoot, ".truecourse", "specs", "decisions.json");
@@ -198737,7 +199046,8 @@ var EMPTY_DECISIONS2 = {
198737
199046
  manualIncludes: [],
198738
199047
  manualExcludes: [],
198739
199048
  relations: [],
198740
- manualAreas: []
199049
+ manualAreas: [],
199050
+ conflictResolutions: []
198741
199051
  };
198742
199052
  function decisionsPath(repoRoot) {
198743
199053
  return path28.join(repoRoot, ".truecourse", "specs", "decisions.json");
@@ -200918,13 +201228,13 @@ UnicodeChar.prototype.toFailure = function(grammar2) {
200918
201228
  return new Failure(this, "a Unicode [" + this.categoryOrProp + "] character", "description");
200919
201229
  };
200920
201230
  Alt.prototype.toFailure = function(grammar2) {
200921
- const fs67 = this.terms.map((t) => t.toFailure(grammar2));
200922
- const description = "(" + fs67.join(" or ") + ")";
201231
+ const fs68 = this.terms.map((t) => t.toFailure(grammar2));
201232
+ const description = "(" + fs68.join(" or ") + ")";
200923
201233
  return new Failure(this, description, "description");
200924
201234
  };
200925
201235
  Seq.prototype.toFailure = function(grammar2) {
200926
- const fs67 = this.factors.map((f2) => f2.toFailure(grammar2));
200927
- const description = "(" + fs67.join(" ") + ")";
201236
+ const fs68 = this.factors.map((f2) => f2.toFailure(grammar2));
201237
+ const description = "(" + fs68.join(" ") + ")";
200928
201238
  return new Failure(this, description, "description");
200929
201239
  };
200930
201240
  Iter.prototype.toFailure = function(grammar2) {
@@ -202643,9 +202953,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
202643
202953
  decl.withSuperGrammar(namespace[superGrammarName]);
202644
202954
  }
202645
202955
  },
202646
- Rule_define(n, fs67, d, _, b) {
202956
+ Rule_define(n, fs68, d, _, b) {
202647
202957
  currentRuleName = n.visit();
202648
- currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
202958
+ currentRuleFormals = fs68.children.map((c) => c.visit())[0] || [];
202649
202959
  if (!decl.defaultStartRule && decl.ensureSuperGrammar() !== Grammar.ProtoBuiltInRules) {
202650
202960
  decl.withDefaultStartRule(currentRuleName);
202651
202961
  }
@@ -202654,9 +202964,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
202654
202964
  const source = this.source.trimmed();
202655
202965
  return decl.define(currentRuleName, currentRuleFormals, body, description, source);
202656
202966
  },
202657
- Rule_override(n, fs67, _, b) {
202967
+ Rule_override(n, fs68, _, b) {
202658
202968
  currentRuleName = n.visit();
202659
- currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
202969
+ currentRuleFormals = fs68.children.map((c) => c.visit())[0] || [];
202660
202970
  const source = this.source.trimmed();
202661
202971
  decl.ensureSuperGrammarRuleForOverriding(currentRuleName, source);
202662
202972
  overriding = true;
@@ -202664,9 +202974,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
202664
202974
  overriding = false;
202665
202975
  return decl.override(currentRuleName, currentRuleFormals, body, null, source);
202666
202976
  },
202667
- Rule_extend(n, fs67, _, b) {
202977
+ Rule_extend(n, fs68, _, b) {
202668
202978
  currentRuleName = n.visit();
202669
- currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
202979
+ currentRuleFormals = fs68.children.map((c) => c.visit())[0] || [];
202670
202980
  const body = b.visit();
202671
202981
  const source = this.source.trimmed();
202672
202982
  return decl.extend(currentRuleName, currentRuleFormals, body, null, source);
@@ -202693,8 +203003,8 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
202693
203003
  return builder.alt(...args).withSource(this.source);
202694
203004
  }
202695
203005
  },
202696
- Formals(opointy, fs67, cpointy) {
202697
- return fs67.visit();
203006
+ Formals(opointy, fs68, cpointy) {
203007
+ return fs68.visit();
202698
203008
  },
202699
203009
  Params(opointy, ps, cpointy) {
202700
203010
  return ps.visit();
@@ -202840,8 +203150,8 @@ function initPrototypeParser(grammar2) {
202840
203150
  formals: optFormals.children.map((c) => c.parse())[0] || []
202841
203151
  };
202842
203152
  },
202843
- Formals(oparen, fs67, cparen) {
202844
- return fs67.asIteration().children.map((c) => c.parse());
203153
+ Formals(oparen, fs68, cparen) {
203154
+ return fs68.asIteration().children.map((c) => c.parse());
202845
203155
  },
202846
203156
  name(first2, rest) {
202847
203157
  return this.sourceString;
@@ -205989,8 +206299,8 @@ function parseAndResolve(files) {
205989
206299
  const parsed = files.map((f2) => parseOne(f2.path, f2.source));
205990
206300
  return resolve(parsed);
205991
206301
  }
205992
- function parseTcFile(path74, source) {
205993
- return parseOne(path74, source);
206302
+ function parseTcFile(path75, source) {
206303
+ return parseOne(path75, source);
205994
206304
  }
205995
206305
 
205996
206306
  // packages/contract-verifier/dist/conformance/index.js
@@ -207315,13 +207625,13 @@ function extractStarletteRoutesFromFile(filePath, source, tree) {
207315
207625
  const identities = starletteIdentitiesForPath(rawPath);
207316
207626
  const line = node2.startPosition.row + 1;
207317
207627
  for (const method of methods) {
207318
- for (const path74 of identities) {
207628
+ for (const path75 of identities) {
207319
207629
  out.push({
207320
- identity: `${method} ${path74}`,
207630
+ identity: `${method} ${path75}`,
207321
207631
  contract: {
207322
207632
  protocol: "http",
207323
207633
  method,
207324
- path: path74,
207634
+ path: path75,
207325
207635
  responses: [],
207326
207636
  tags: []
207327
207637
  },
@@ -207499,14 +207809,14 @@ function parseRouteDecorator(dec, source, stringVars) {
207499
207809
  const args = call.childForFieldName("arguments");
207500
207810
  if (!args)
207501
207811
  return null;
207502
- let path74 = null;
207812
+ let path75 = null;
207503
207813
  let successStatus = "200";
207504
207814
  for (let i = 0; i < args.namedChildCount; i++) {
207505
207815
  const a = args.namedChild(i);
207506
207816
  if (!a)
207507
207817
  continue;
207508
- if (path74 === null && a.type === "string")
207509
- path74 = pyStr(a, source);
207818
+ if (path75 === null && a.type === "string")
207819
+ path75 = pyStr(a, source);
207510
207820
  else if (a.type === "keyword_argument") {
207511
207821
  const name = a.childForFieldName("name");
207512
207822
  const value = a.childForFieldName("value");
@@ -207515,17 +207825,17 @@ function parseRouteDecorator(dec, source, stringVars) {
207515
207825
  }
207516
207826
  }
207517
207827
  }
207518
- if (path74 === null) {
207828
+ if (path75 === null) {
207519
207829
  const firstArg = args.namedChild(0);
207520
207830
  if (firstArg?.type === "identifier") {
207521
207831
  const resolved = stringVars.get(source.slice(firstArg.startIndex, firstArg.endIndex));
207522
207832
  if (resolved !== void 0)
207523
- path74 = resolved;
207833
+ path75 = resolved;
207524
207834
  }
207525
207835
  }
207526
- if (path74 === null)
207836
+ if (path75 === null)
207527
207837
  return null;
207528
- return { method, path: path74, routerVar, successStatus };
207838
+ return { method, path: path75, routerVar, successStatus };
207529
207839
  }
207530
207840
  function extractResponses2(body, source, successStatus) {
207531
207841
  const byStatus = /* @__PURE__ */ new Map();
@@ -207658,9 +207968,9 @@ function looksLikeModel(p, source) {
207658
207968
  const text4 = source.slice(type2.startIndex, type2.endIndex);
207659
207969
  return /^[A-Z]/.test(text4);
207660
207970
  }
207661
- function joinPath(prefix, path74) {
207971
+ function joinPath(prefix, path75) {
207662
207972
  const a = prefix.replace(/\/$/, "");
207663
- const b = path74.startsWith("/") ? path74 : `/${path74}`;
207973
+ const b = path75.startsWith("/") ? path75 : `/${path75}`;
207664
207974
  return a + b || "/";
207665
207975
  }
207666
207976
  function callName(call, source) {
@@ -221611,8 +221921,8 @@ function canonicalIdentity(_kind, identity) {
221611
221921
  let id = identity.trim().replace(/\s+/g, " ");
221612
221922
  const op = HTTP_METHOD.exec(id);
221613
221923
  if (op) {
221614
- const path74 = op[2].replace(/\/+$/, "").replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, "{$1}");
221615
- id = `${op[1].toUpperCase()} ${path74}`;
221924
+ const path75 = op[2].replace(/\/+$/, "").replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, "{$1}");
221925
+ id = `${op[1].toUpperCase()} ${path75}`;
221616
221926
  }
221617
221927
  return id;
221618
221928
  }
@@ -225468,6 +225778,7 @@ function resolveFallbackModel(repoDir = resolveRepoDir(process.cwd())) {
225468
225778
  }
225469
225779
 
225470
225780
  // packages/core/dist/commands/spec-in-process.js
225781
+ init_dist();
225471
225782
  init_transport();
225472
225783
 
225473
225784
  // packages/core/dist/lib/llm-call-log.js
@@ -225685,8 +225996,8 @@ init_dist();
225685
225996
 
225686
225997
  // packages/guard-generator/dist/section-plan.js
225687
225998
  init_zod();
225688
- import fs51 from "node:fs";
225689
- import path53 from "node:path";
225999
+ import fs52 from "node:fs";
226000
+ import path54 from "node:path";
225690
226001
  import { createHash as createHash14 } from "node:crypto";
225691
226002
  init_dist();
225692
226003
 
@@ -225828,6 +226139,11 @@ function buildExtractUserPrompt(ctx) {
225828
226139
  ctx.viewText,
225829
226140
  '"""'
225830
226141
  ];
226142
+ if (ctx.suppressed && ctx.suppressed.length > 0) {
226143
+ lines.push("", "RESOLVED \u2014 STALE, DO NOT EXTRACT. A conflict resolution judged the following", "sentence(s) in this document stale (another document is authoritative here).", "Extract NO claim that asserts what any of them says \u2014 treat them as if absent:");
226144
+ for (const q of ctx.suppressed)
226145
+ lines.push(`- "${q}"`);
226146
+ }
225831
226147
  if (ctx.correction) {
225832
226148
  lines.push("", "CORRECTION \u2014 your previous response was NOT valid. You returned:", ctx.correction.invalidOutput, 'Return exactly ONE JSON object with "claims" and "untestable" arrays matching', 'the schema above, and NOTHING else. Every "driver" is one of cli|api|web|tui;', 'every "sectionAnchor" is an anchor copied verbatim from the outline.');
225833
226149
  }
@@ -225996,17 +226312,127 @@ function buildRecipeUserPrompt(input) {
225996
226312
  return lines.join("\n");
225997
226313
  }
225998
226314
 
225999
- // packages/guard-generator/dist/section-plan.js
226315
+ // packages/guard-generator/dist/suppression.js
226316
+ init_zod();
226317
+ init_dist();
226318
+ import fs51 from "node:fs";
226319
+ import path53 from "node:path";
226320
+ var OverlapSectionShape = external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable().optional(), quote: external_exports.string().optional() }).passthrough();
226321
+ var OverlapShape = external_exports.object({
226322
+ docs: external_exports.tuple([external_exports.string(), external_exports.string()]),
226323
+ note: external_exports.string().optional(),
226324
+ sections: external_exports.array(OverlapSectionShape).optional(),
226325
+ areas: external_exports.array(external_exports.string()).optional()
226326
+ }).passthrough();
226327
+ var RelationShape = external_exports.object({ older: external_exports.string(), newer: external_exports.string(), scope: external_exports.string().optional() }).passthrough();
226000
226328
  var CorpusShape2 = external_exports.object({
226329
+ areas: external_exports.array(external_exports.object({ id: external_exports.string(), overlaps: external_exports.array(OverlapShape).optional() }).passthrough()).optional(),
226330
+ relations: external_exports.array(RelationShape).optional()
226331
+ }).passthrough();
226332
+ var ConflictResolutionShape = external_exports.object({
226333
+ docA: external_exports.string(),
226334
+ anchorA: external_exports.string().nullable().optional(),
226335
+ quoteA: external_exports.string().optional(),
226336
+ docB: external_exports.string(),
226337
+ anchorB: external_exports.string().nullable().optional(),
226338
+ quoteB: external_exports.string().optional(),
226339
+ verdict: external_exports.enum(["a", "b", "dismissed"]),
226340
+ resolvedAt: external_exports.string().optional(),
226341
+ note: external_exports.string().optional()
226342
+ }).passthrough();
226343
+ var DecisionsShape = external_exports.object({
226344
+ relations: external_exports.array(RelationShape).optional(),
226345
+ manualExcludes: external_exports.array(external_exports.string()).optional(),
226346
+ conflictResolutions: external_exports.array(ConflictResolutionShape).optional()
226347
+ }).passthrough();
226348
+ function readJsonTolerant(file, schema2) {
226349
+ if (!fs51.existsSync(file))
226350
+ return void 0;
226351
+ try {
226352
+ const parsed = schema2.safeParse(JSON.parse(fs51.readFileSync(file, "utf-8")));
226353
+ return parsed.success ? parsed.data : void 0;
226354
+ } catch {
226355
+ return void 0;
226356
+ }
226357
+ }
226358
+ function readSuppressedClaims(repoRoot) {
226359
+ const specDir = path53.join(repoRoot, ".truecourse", "specs");
226360
+ const corpus = readJsonTolerant(path53.join(specDir, "corpus.json"), CorpusShape2);
226361
+ if (!corpus)
226362
+ return [];
226363
+ const decisions = readJsonTolerant(path53.join(specDir, "decisions.json"), DecisionsShape);
226364
+ const corpusLike = {
226365
+ areas: (corpus.areas ?? []).map((a) => ({
226366
+ id: a.id,
226367
+ overlaps: (a.overlaps ?? []).map((o) => ({
226368
+ docs: o.docs,
226369
+ note: o.note,
226370
+ sections: (o.sections ?? []).map((s) => ({ doc: s.doc, heading: s.heading ?? null, quote: s.quote })),
226371
+ areas: o.areas
226372
+ }))
226373
+ })),
226374
+ relations: corpus.relations ?? []
226375
+ };
226376
+ const decisionsLike = {
226377
+ relations: decisions?.relations ?? [],
226378
+ manualExcludes: decisions?.manualExcludes ?? [],
226379
+ conflictResolutions: (decisions?.conflictResolutions ?? []).map((r) => ({
226380
+ docA: r.docA,
226381
+ anchorA: r.anchorA ?? null,
226382
+ quoteA: r.quoteA,
226383
+ docB: r.docB,
226384
+ anchorB: r.anchorB ?? null,
226385
+ quoteB: r.quoteB,
226386
+ verdict: r.verdict,
226387
+ resolvedAt: r.resolvedAt,
226388
+ note: r.note
226389
+ }))
226390
+ };
226391
+ return suppressedClaims(corpusLike, decisionsLike);
226392
+ }
226393
+ function readSuppressionIndex(repoRoot) {
226394
+ const map2 = /* @__PURE__ */ new Map();
226395
+ for (const claim of readSuppressedClaims(repoRoot)) {
226396
+ const list = map2.get(claim.doc);
226397
+ if (list)
226398
+ list.push(claim.quote);
226399
+ else
226400
+ map2.set(claim.doc, [claim.quote]);
226401
+ }
226402
+ return map2;
226403
+ }
226404
+ function suppressedQuotesIn(text4, docQuotes) {
226405
+ if (docQuotes.length === 0)
226406
+ return [];
226407
+ const haystack = normalizeQuote(text4);
226408
+ const seen = /* @__PURE__ */ new Set();
226409
+ const hits = [];
226410
+ for (const q of docQuotes) {
226411
+ const needle = normalizeQuote(q);
226412
+ if (!needle || seen.has(needle) || !haystack.includes(needle))
226413
+ continue;
226414
+ seen.add(needle);
226415
+ hits.push(q);
226416
+ }
226417
+ return hits.sort((a, b) => normalizeQuote(a) < normalizeQuote(b) ? -1 : 1);
226418
+ }
226419
+ function suppressionKey(quotes) {
226420
+ if (quotes.length === 0)
226421
+ return "";
226422
+ return [...quotes].map(normalizeQuote).sort().join("\0");
226423
+ }
226424
+
226425
+ // packages/guard-generator/dist/section-plan.js
226426
+ var CorpusShape3 = external_exports.object({
226001
226427
  docs: external_exports.array(external_exports.object({ ref: external_exports.string(), areaTags: external_exports.array(external_exports.string()).optional() }).passthrough()).optional()
226002
226428
  }).passthrough();
226003
226429
  function readCorpusAreaTags(repoRoot) {
226004
- const file = path53.join(repoRoot, ".truecourse", "specs", "corpus.json");
226430
+ const file = path54.join(repoRoot, ".truecourse", "specs", "corpus.json");
226005
226431
  const map2 = /* @__PURE__ */ new Map();
226006
- if (!fs51.existsSync(file))
226432
+ if (!fs52.existsSync(file))
226007
226433
  return map2;
226008
226434
  try {
226009
- const parsed = CorpusShape2.safeParse(JSON.parse(fs51.readFileSync(file, "utf-8")));
226435
+ const parsed = CorpusShape3.safeParse(JSON.parse(fs52.readFileSync(file, "utf-8")));
226010
226436
  if (!parsed.success)
226011
226437
  return map2;
226012
226438
  for (const d of parsed.data.docs ?? [])
@@ -226015,29 +226441,35 @@ function readCorpusAreaTags(repoRoot) {
226015
226441
  }
226016
226442
  return map2;
226017
226443
  }
226018
- function generationInputsHash(fingerprint2, recipeFingerprint) {
226019
- return "sha256:" + createHash14("sha256").update([
226444
+ function generationInputsHash(fingerprint2, recipeFingerprint, suppressionFingerprint = "") {
226445
+ const parts = [
226020
226446
  fingerprint2,
226021
226447
  recipeFingerprint,
226022
226448
  String(GUARD_FORMAT_VERSION),
226023
226449
  EXTRACT_PROMPT_FINGERPRINT2,
226024
226450
  GENERATE_PROMPT_FINGERPRINT
226025
- ].join("\0")).digest("hex");
226451
+ ];
226452
+ if (suppressionFingerprint)
226453
+ parts.push(suppressionFingerprint);
226454
+ return "sha256:" + createHash14("sha256").update(parts.join("\0")).digest("hex");
226026
226455
  }
226027
226456
  function hasGuardUniverse(repoRoot) {
226028
- return fs51.existsSync(path53.join(repoRoot, ".truecourse", "specs", "corpus.json"));
226457
+ return fs52.existsSync(path54.join(repoRoot, ".truecourse", "specs", "corpus.json"));
226029
226458
  }
226030
226459
  function planGuardWork(repoRoot, recipeFingerprint) {
226031
226460
  const recipeFp = recipeFingerprint ?? computeRecipeFingerprint(repoRoot);
226032
- const recipeMissing = !fs51.existsSync(recipePath(repoRoot));
226461
+ const recipeMissing = !fs52.existsSync(recipePath(repoRoot));
226033
226462
  const hasUniverse = hasGuardUniverse(repoRoot);
226034
226463
  const { indexes } = indexRepoDocs(repoRoot, []);
226035
226464
  const areaTags = readCorpusAreaTags(repoRoot);
226465
+ const suppressionIndex = readSuppressionIndex(repoRoot);
226036
226466
  const sections = [];
226037
226467
  for (const [doc, index] of indexes) {
226038
- const texts = extractSectionTexts(doc, fs51.readFileSync(path53.resolve(repoRoot, doc), "utf-8"));
226468
+ const texts = extractSectionTexts(doc, fs52.readFileSync(path54.resolve(repoRoot, doc), "utf-8"));
226469
+ const docQuotes = suppressionIndex.get(doc) ?? [];
226039
226470
  for (const s of index.sections) {
226040
226471
  const t = texts.get(s.anchor);
226472
+ const fullText = t?.fullText ?? "";
226041
226473
  sections.push({
226042
226474
  doc,
226043
226475
  anchor: s.anchor,
@@ -226045,8 +226477,9 @@ function planGuardWork(repoRoot, recipeFingerprint) {
226045
226477
  headingText: s.headingText,
226046
226478
  level: s.level,
226047
226479
  ownText: t?.ownText ?? "",
226048
- fullText: t?.fullText ?? "",
226049
- areaTags: areaTags.get(doc) ?? []
226480
+ fullText,
226481
+ areaTags: areaTags.get(doc) ?? [],
226482
+ suppressionFingerprint: suppressionKey(suppressedQuotesIn(fullText, docQuotes))
226050
226483
  });
226051
226484
  }
226052
226485
  }
@@ -226059,12 +226492,12 @@ function planGuardWork(repoRoot, recipeFingerprint) {
226059
226492
  const key4 = `${s.doc}\0${s.anchor}`;
226060
226493
  seen.add(key4);
226061
226494
  const prior = byKey.get(key4);
226062
- const inputsHash = generationInputsHash(s.fingerprint, recipeFp);
226495
+ const inputsHash = generationInputsHash(s.fingerprint, recipeFp, s.suppressionFingerprint);
226063
226496
  if (!prior || prior.generationInputsHash !== inputsHash)
226064
226497
  work.push(s);
226065
226498
  }
226066
226499
  const orphaned = (manifest?.sections ?? []).filter((e) => !seen.has(`${e.doc}\0${e.anchor}`));
226067
- return { hasUniverse, sections, work, orphaned, recipeFingerprint: recipeFp, recipeMissing };
226500
+ return { hasUniverse, sections, work, orphaned, recipeFingerprint: recipeFp, recipeMissing, suppressionIndex };
226068
226501
  }
226069
226502
  function collectWorkDocs(repoRoot, plan) {
226070
226503
  const workDocs = new Set(plan.work.map((s) => s.doc));
@@ -226080,8 +226513,9 @@ function collectWorkDocs(repoRoot, plan) {
226080
226513
  }
226081
226514
  return [...byDoc].map(([doc, sections]) => ({
226082
226515
  doc,
226083
- content: fs51.readFileSync(path53.resolve(repoRoot, doc), "utf-8"),
226084
- sections
226516
+ content: fs52.readFileSync(path54.resolve(repoRoot, doc), "utf-8"),
226517
+ sections,
226518
+ suppressedQuotes: plan.suppressionIndex.get(doc) ?? []
226085
226519
  }));
226086
226520
  }
226087
226521
 
@@ -226164,8 +226598,13 @@ function flattenZodError(error) {
226164
226598
  // packages/guard-generator/dist/extract.js
226165
226599
  var EXTRACT_CACHE_NAME2 = "guard/extract";
226166
226600
  var EXTRACT_VIEW_BUDGET = 16e3;
226167
- function viewCacheKey(viewText) {
226168
- return createHash15("sha256").update(`${EXTRACT_PROMPT_FINGERPRINT2}::${sha(viewText)}`).digest("hex");
226601
+ function viewCacheKey(viewText, suppressed = []) {
226602
+ const base = `${EXTRACT_PROMPT_FINGERPRINT2}::${sha(viewText)}`;
226603
+ const suppression = suppressionKey(suppressed);
226604
+ return createHash15("sha256").update(suppression ? `${base}::${suppression}` : base).digest("hex");
226605
+ }
226606
+ function suppressedForView(doc, viewText) {
226607
+ return suppressedQuotesIn(viewText, doc.suppressedQuotes);
226169
226608
  }
226170
226609
  function sha(text4) {
226171
226610
  return createHash15("sha256").update(text4).digest("hex");
@@ -226211,7 +226650,7 @@ function countExtractViews(doc) {
226211
226650
  async function countUncachedExtractViews(repoRoot, doc) {
226212
226651
  let n = 0;
226213
226652
  for (const v of planViews(doc)) {
226214
- if (!await getCacheEntry(repoRoot, EXTRACT_CACHE_NAME2, viewCacheKey(v.text)))
226653
+ if (!await getCacheEntry(repoRoot, EXTRACT_CACHE_NAME2, viewCacheKey(v.text, suppressedForView(doc, v.text))))
226215
226654
  n++;
226216
226655
  }
226217
226656
  return n;
@@ -226220,7 +226659,7 @@ async function extractDocClaims(repoRoot, doc, runner2, limit, onView) {
226220
226659
  const outline = outlineOf(doc.sections);
226221
226660
  const views = planViews(doc);
226222
226661
  const run = limit ?? ((fn) => fn());
226223
- const attempts = await Promise.all(views.map((v) => run(() => extractView(repoRoot, doc.doc, outline, v, runner2)).then((got) => {
226662
+ const attempts = await Promise.all(views.map((v) => run(() => extractView(repoRoot, doc.doc, outline, v, suppressedForView(doc, v.text), runner2)).then((got) => {
226224
226663
  onView?.();
226225
226664
  return got;
226226
226665
  })));
@@ -226241,15 +226680,21 @@ async function extractDocClaims(repoRoot, doc, runner2, limit, onView) {
226241
226680
  return { ok: false, reason: firstError || "all extraction views failed" };
226242
226681
  return { ok: true, data: snap(merged, doc.sections), complete: failedViews === 0, failedViews };
226243
226682
  }
226244
- async function extractView(repoRoot, docPath, outline, view, runner2) {
226245
- const cacheKey = viewCacheKey(view.text);
226683
+ async function extractView(repoRoot, docPath, outline, view, suppressed, runner2) {
226684
+ const cacheKey = viewCacheKey(view.text, suppressed);
226246
226685
  const cached = await getCacheEntry(repoRoot, EXTRACT_CACHE_NAME2, cacheKey);
226247
226686
  if (cached) {
226248
226687
  const parsed = DocExtractionSchema.safeParse(cached);
226249
226688
  if (parsed.success)
226250
226689
  return { data: parsed.data };
226251
226690
  }
226252
- const ctx = { doc: docPath, outline, viewText: view.text, view: view.view };
226691
+ const ctx = {
226692
+ doc: docPath,
226693
+ outline,
226694
+ viewText: view.text,
226695
+ view: view.view,
226696
+ ...suppressed.length > 0 ? { suppressed } : {}
226697
+ };
226253
226698
  const attempt = await callExtractWithReask(ctx, runner2);
226254
226699
  if ("data" in attempt)
226255
226700
  await setCacheEntry(repoRoot, EXTRACT_CACHE_NAME2, cacheKey, attempt.data);
@@ -226328,7 +226773,7 @@ function snap(raw, sections) {
226328
226773
 
226329
226774
  // packages/guard-generator/dist/ground.js
226330
226775
  init_zod();
226331
- import path54 from "node:path";
226776
+ import path55 from "node:path";
226332
226777
  import { createHash as createHash16 } from "node:crypto";
226333
226778
  var GROUND_CACHE_NAME = "guard/ground";
226334
226779
  var PROBE_TIMEOUT_MS = 2e4;
@@ -226384,7 +226829,7 @@ function toProbeArgv(fragment, programNames) {
226384
226829
  const tokens = fragment.trim().split(/\s+/).filter(Boolean);
226385
226830
  if (tokens.length === 0)
226386
226831
  return null;
226387
- if (programNames.has(tokens[0]) || programNames.has(path54.basename(tokens[0])))
226832
+ if (programNames.has(tokens[0]) || programNames.has(path55.basename(tokens[0])))
226388
226833
  tokens.shift();
226389
226834
  if (tokens.length === 0)
226390
226835
  return [];
@@ -226405,7 +226850,7 @@ function programNamesOf(entry) {
226405
226850
  return names;
226406
226851
  }
226407
226852
  function addName(set2, arg) {
226408
- const base = path54.basename(arg);
226853
+ const base = path55.basename(arg);
226409
226854
  if (base)
226410
226855
  set2.add(base);
226411
226856
  const stem = base.replace(/\.[^.]+$/, "");
@@ -226467,9 +226912,9 @@ function truncate2(text4) {
226467
226912
  }
226468
226913
 
226469
226914
  // packages/guard-generator/dist/recipe-discovery.js
226470
- import fs52 from "node:fs";
226915
+ import fs53 from "node:fs";
226471
226916
  import os7 from "node:os";
226472
- import path55 from "node:path";
226917
+ import path56 from "node:path";
226473
226918
  import { createHash as createHash17 } from "node:crypto";
226474
226919
  var RECIPE_CACHE_NAME = "guard/recipe";
226475
226920
  var DISCOVERY_INPUTS = ["package.json", "pnpm-lock.yaml", "package-lock.json", "yarn.lock", "turbo.json"];
@@ -226523,13 +226968,13 @@ async function discoverRecipe(repoRoot, runner2) {
226523
226968
  ...proposal.env ? { env: proposal.env } : {}
226524
226969
  };
226525
226970
  const target = recipePath(repoRoot);
226526
- fs52.mkdirSync(path55.dirname(target), { recursive: true });
226527
- fs52.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
226971
+ fs53.mkdirSync(path56.dirname(target), { recursive: true });
226972
+ fs53.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
226528
226973
  return {
226529
226974
  status: "discovered",
226530
226975
  recipe,
226531
226976
  fingerprint: computeRecipeFingerprint(repoRoot),
226532
- wrotePath: path55.relative(repoRoot, target)
226977
+ wrotePath: path56.relative(repoRoot, target)
226533
226978
  };
226534
226979
  }
226535
226980
  async function proposeRecipeWithReask(input, runner2) {
@@ -226554,14 +226999,14 @@ async function proposeRecipeWithReask(input, runner2) {
226554
226999
  return { error: `recipe proposal invalid after re-ask: ${flattenZodError(reParsed.error)}` };
226555
227000
  }
226556
227001
  function readDiscoveryInputs(repoRoot) {
226557
- const pkgPath = path55.join(repoRoot, "package.json");
226558
- const packageJson = fs52.existsSync(pkgPath) ? fs52.readFileSync(pkgPath, "utf-8") : "(no package.json)";
226559
- const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs52.existsSync(path55.join(repoRoot, f2)));
227002
+ const pkgPath = path56.join(repoRoot, "package.json");
227003
+ const packageJson = fs53.existsSync(pkgPath) ? fs53.readFileSync(pkgPath, "utf-8") : "(no package.json)";
227004
+ const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs53.existsSync(path56.join(repoRoot, f2)));
226560
227005
  return { packageJson, presentInputs };
226561
227006
  }
226562
227007
  async function probeEntry(repoRoot, entry) {
226563
227008
  const resolved = resolveEntry(repoRoot, entry);
226564
- const cwd = fs52.mkdtempSync(path55.join(os7.tmpdir(), "tc-guard-probe-"));
227009
+ const cwd = fs53.mkdtempSync(path56.join(os7.tmpdir(), "tc-guard-probe-"));
226565
227010
  try {
226566
227011
  for (const args of [["--help"], []]) {
226567
227012
  const capture = await executeStep({
@@ -226578,7 +227023,7 @@ async function probeEntry(repoRoot, entry) {
226578
227023
  reason: `entrypoint ${JSON.stringify(entry)} did not answer to \`--help\` or a bare invocation`
226579
227024
  };
226580
227025
  } finally {
226581
- fs52.rmSync(cwd, { recursive: true, force: true });
227026
+ fs53.rmSync(cwd, { recursive: true, force: true });
226582
227027
  }
226583
227028
  }
226584
227029
 
@@ -226625,8 +227070,8 @@ async function birthValidate(repoRoot, candidates, opts = {}) {
226625
227070
  }
226626
227071
 
226627
227072
  // packages/guard-generator/dist/serialize.js
226628
- import fs53 from "node:fs";
226629
- import path56 from "node:path";
227073
+ import fs54 from "node:fs";
227074
+ import path57 from "node:path";
226630
227075
  init_dist();
226631
227076
  function anchorLeaf(anchor) {
226632
227077
  const segs = anchor.split("/").filter(Boolean);
@@ -226645,7 +227090,7 @@ function assignScenarioId(anchor, used) {
226645
227090
  function areaOrDocSlug(section) {
226646
227091
  if (section.areaTags.length > 0)
226647
227092
  return slugifyHeading(section.areaTags[0]) || "area";
226648
- const base = path56.basename(section.doc).replace(/\.[^.]+$/, "");
227093
+ const base = path57.basename(section.doc).replace(/\.[^.]+$/, "");
226649
227094
  return slugifyHeading(base) || "doc";
226650
227095
  }
226651
227096
  function buildScenario(section, raw, id) {
@@ -226668,15 +227113,15 @@ function scenarioFileIndex(repoRoot) {
226668
227113
  const root = scenariosDir(repoRoot);
226669
227114
  const map2 = /* @__PURE__ */ new Map();
226670
227115
  const walk20 = (dir) => {
226671
- if (!fs53.existsSync(dir))
227116
+ if (!fs54.existsSync(dir))
226672
227117
  return;
226673
- for (const entry of fs53.readdirSync(dir, { withFileTypes: true })) {
226674
- const full = path56.join(dir, entry.name);
227118
+ for (const entry of fs54.readdirSync(dir, { withFileTypes: true })) {
227119
+ const full = path57.join(dir, entry.name);
226675
227120
  if (entry.isDirectory())
226676
227121
  walk20(full);
226677
227122
  else if (entry.isFile() && /\.ya?ml$/i.test(entry.name)) {
226678
227123
  try {
226679
- const doc = jsYaml.load(fs53.readFileSync(full, "utf-8"));
227124
+ const doc = jsYaml.load(fs54.readFileSync(full, "utf-8"));
226680
227125
  if (doc && typeof doc.id === "string")
226681
227126
  map2.set(doc.id, full);
226682
227127
  } catch {
@@ -226694,18 +227139,18 @@ function serializeScenarioYaml(scenario) {
226694
227139
  return jsYaml.dump(scenario, { lineWidth: -1, noRefs: true });
226695
227140
  }
226696
227141
  function writeScenarioFile(repoRoot, slug2, scenario) {
226697
- const dir = path56.join(scenariosDir(repoRoot), slug2);
226698
- fs53.mkdirSync(dir, { recursive: true });
226699
- const file = path56.join(dir, `${scenario.id}.yaml`);
226700
- fs53.writeFileSync(file, serializeScenarioYaml(scenario));
226701
- return path56.relative(repoRoot, file);
227142
+ const dir = path57.join(scenariosDir(repoRoot), slug2);
227143
+ fs54.mkdirSync(dir, { recursive: true });
227144
+ const file = path57.join(dir, `${scenario.id}.yaml`);
227145
+ fs54.writeFileSync(file, serializeScenarioYaml(scenario));
227146
+ return path57.relative(repoRoot, file);
226702
227147
  }
226703
227148
  function deleteScenarioFiles(repoRoot, ids) {
226704
227149
  const index = scenarioFileIndex(repoRoot);
226705
227150
  for (const id of ids) {
226706
227151
  const file = index.get(id);
226707
- if (file && fs53.existsSync(file))
226708
- fs53.rmSync(file);
227152
+ if (file && fs54.existsSync(file))
227153
+ fs54.rmSync(file);
226709
227154
  }
226710
227155
  }
226711
227156
 
@@ -226925,7 +227370,7 @@ async function generateGuards(options) {
226925
227370
  anchor: section.anchor,
226926
227371
  fingerprint: section.fingerprint,
226927
227372
  scenarioIds: scenarioIds.slice().sort(),
226928
- generationInputsHash: generationInputsHash(section.fingerprint, recipeFingerprint),
227373
+ generationInputsHash: generationInputsHash(section.fingerprint, recipeFingerprint, section.suppressionFingerprint),
226929
227374
  ...classification ? { classification } : {}
226930
227375
  });
226931
227376
  settledKeys.add(k);
@@ -227832,8 +228277,8 @@ function routeContextInner(rules, fileAnalyses, fileContents) {
227832
228277
  }
227833
228278
 
227834
228279
  // packages/core/dist/services/llm/model-prices.js
227835
- import fs54 from "node:fs";
227836
- import path57 from "node:path";
228280
+ import fs55 from "node:fs";
228281
+ import path58 from "node:path";
227837
228282
  var OPENROUTER_URL = "https://openrouter.ai/api/v1/models";
227838
228283
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
227839
228284
  var FETCH_TIMEOUT_MS = 8e3;
@@ -227849,11 +228294,11 @@ function tierOf(id) {
227849
228294
  return s.includes("opus") ? "opus" : s.includes("sonnet") ? "sonnet" : s.includes("haiku") ? "haiku" : null;
227850
228295
  }
227851
228296
  function cacheFilePath() {
227852
- return path57.join(getGlobalDir(), "cache", CACHE_FILE);
228297
+ return path58.join(getGlobalDir(), "cache", CACHE_FILE);
227853
228298
  }
227854
228299
  function readCache7() {
227855
228300
  try {
227856
- const t = JSON.parse(fs54.readFileSync(cacheFilePath(), "utf-8"));
228301
+ const t = JSON.parse(fs55.readFileSync(cacheFilePath(), "utf-8"));
227857
228302
  if (t && t.tiers && t.byId && typeof t.fetchedAt === "number")
227858
228303
  return t;
227859
228304
  } catch {
@@ -227862,8 +228307,8 @@ function readCache7() {
227862
228307
  }
227863
228308
  function writeCache7(t) {
227864
228309
  try {
227865
- fs54.mkdirSync(path57.dirname(cacheFilePath()), { recursive: true });
227866
- fs54.writeFileSync(cacheFilePath(), JSON.stringify(t));
228310
+ fs55.mkdirSync(path58.dirname(cacheFilePath()), { recursive: true });
228311
+ fs55.writeFileSync(cacheFilePath(), JSON.stringify(t));
227867
228312
  } catch {
227868
228313
  }
227869
228314
  }
@@ -228241,8 +228686,8 @@ function changedSubject(total, changed, noun) {
228241
228686
  }
228242
228687
 
228243
228688
  // packages/core/dist/commands/spec-in-process.js
228244
- import fs59 from "node:fs";
228245
- import path62 from "node:path";
228689
+ import fs60 from "node:fs";
228690
+ import path63 from "node:path";
228246
228691
  import { createHash as createHash19, randomUUID as randomUUID21 } from "node:crypto";
228247
228692
 
228248
228693
  // packages/core/dist/lib/repo-ref.js
@@ -228262,8 +228707,8 @@ async function repoRef(repoRoot, commitOverride) {
228262
228707
  }
228263
228708
 
228264
228709
  // packages/core/dist/lib/contract-store.js
228265
- import fs55 from "node:fs";
228266
- import path58 from "node:path";
228710
+ import fs56 from "node:fs";
228711
+ import path59 from "node:path";
228267
228712
  var KIND_REL = {
228268
228713
  contracts: [".truecourse", "contracts"],
228269
228714
  // The inferred tree lives at contracts/_inferred (matches `writeInferred`).
@@ -228273,13 +228718,13 @@ function countTcFiles(dir) {
228273
228718
  let n = 0;
228274
228719
  let entries;
228275
228720
  try {
228276
- entries = fs55.readdirSync(dir, { withFileTypes: true });
228721
+ entries = fs56.readdirSync(dir, { withFileTypes: true });
228277
228722
  } catch {
228278
228723
  return 0;
228279
228724
  }
228280
228725
  for (const e of entries) {
228281
228726
  if (e.isDirectory())
228282
- n += countTcFiles(path58.join(dir, e.name));
228727
+ n += countTcFiles(path59.join(dir, e.name));
228283
228728
  else if (e.isFile() && e.name.endsWith(".tc"))
228284
228729
  n += 1;
228285
228730
  }
@@ -228290,7 +228735,7 @@ function walkTcRel(dir, excludeInferred) {
228290
228735
  const walk20 = (rel) => {
228291
228736
  let entries;
228292
228737
  try {
228293
- entries = fs55.readdirSync(path58.join(dir, rel), { withFileTypes: true });
228738
+ entries = fs56.readdirSync(path59.join(dir, rel), { withFileTypes: true });
228294
228739
  } catch {
228295
228740
  return;
228296
228741
  }
@@ -228314,50 +228759,50 @@ function safeResolve(root, rel) {
228314
228759
  return null;
228315
228760
  if (norm.split("/").some((s) => s === ".." || s === "." || s === ""))
228316
228761
  return null;
228317
- const base = path58.resolve(root);
228318
- const dest = path58.resolve(base, norm);
228319
- if (dest !== base && !dest.startsWith(base + path58.sep))
228762
+ const base = path59.resolve(root);
228763
+ const dest = path59.resolve(base, norm);
228764
+ if (dest !== base && !dest.startsWith(base + path59.sep))
228320
228765
  return null;
228321
228766
  return dest;
228322
228767
  }
228323
228768
  var FileContractStore = class {
228324
228769
  materializesInPlace = true;
228325
228770
  async saveContracts(ref, kind, _sourceDir) {
228326
- const dir = path58.join(ref.repoKey, ...KIND_REL[kind]);
228771
+ const dir = path59.join(ref.repoKey, ...KIND_REL[kind]);
228327
228772
  return { manifest: {}, fileCount: countTcFiles(dir), objectsWritten: 0, manifestHash: "" };
228328
228773
  }
228329
228774
  async loadContracts(ref, kind) {
228330
- const dir = path58.join(ref.repoKey, ...KIND_REL[kind]);
228331
- if (!fs55.existsSync(dir))
228775
+ const dir = path59.join(ref.repoKey, ...KIND_REL[kind]);
228776
+ if (!fs56.existsSync(dir))
228332
228777
  return null;
228333
228778
  return { dir, cleanup: async () => {
228334
228779
  } };
228335
228780
  }
228336
228781
  async hasContracts(ref, kind) {
228337
- return fs55.existsSync(path58.join(ref.repoKey, ...KIND_REL[kind]));
228782
+ return fs56.existsSync(path59.join(ref.repoKey, ...KIND_REL[kind]));
228338
228783
  }
228339
228784
  // The file impl reads the live repo tree, which is whatever is checked out —
228340
228785
  // there is no per-commit history, so `commitSha` is ignored (OSS is latest).
228341
228786
  async listContractFiles(repoKey, kind, _commitSha) {
228342
- return walkTcRel(path58.join(repoKey, ...KIND_REL[kind]), kind === "contracts");
228787
+ return walkTcRel(path59.join(repoKey, ...KIND_REL[kind]), kind === "contracts");
228343
228788
  }
228344
228789
  async readContractFile(repoKey, kind, relPath, _commitSha) {
228345
- const dest = safeResolve(path58.join(repoKey, ...KIND_REL[kind]), relPath);
228346
- if (!dest || !fs55.existsSync(dest) || !fs55.statSync(dest).isFile())
228790
+ const dest = safeResolve(path59.join(repoKey, ...KIND_REL[kind]), relPath);
228791
+ if (!dest || !fs56.existsSync(dest) || !fs56.statSync(dest).isFile())
228347
228792
  return null;
228348
- return fs55.readFileSync(dest, "utf-8");
228793
+ return fs56.readFileSync(dest, "utf-8");
228349
228794
  }
228350
228795
  async putContractFile(ref, kind, relPath, content) {
228351
- const dest = safeResolve(path58.join(ref.repoKey, ...KIND_REL[kind]), relPath);
228796
+ const dest = safeResolve(path59.join(ref.repoKey, ...KIND_REL[kind]), relPath);
228352
228797
  if (!dest)
228353
228798
  throw new Error(`[contract-store] unsafe contract path: ${relPath}`);
228354
- fs55.mkdirSync(path58.dirname(dest), { recursive: true });
228355
- fs55.writeFileSync(dest, content);
228799
+ fs56.mkdirSync(path59.dirname(dest), { recursive: true });
228800
+ fs56.writeFileSync(dest, content);
228356
228801
  }
228357
228802
  async deleteContractFile(ref, kind, relPath) {
228358
- const dest = safeResolve(path58.join(ref.repoKey, ...KIND_REL[kind]), relPath);
228803
+ const dest = safeResolve(path59.join(ref.repoKey, ...KIND_REL[kind]), relPath);
228359
228804
  if (dest)
228360
- fs55.rmSync(dest, { force: true });
228805
+ fs56.rmSync(dest, { force: true });
228361
228806
  }
228362
228807
  // OSS/local has no workspace concept (mirrors the spec store). Writing throws
228363
228808
  // (fail loud — a caller that reached here is mis-wired); reads are empty so an
@@ -228387,16 +228832,16 @@ var readWorkspaceContractFile = (ref, kind, relPath) => active9.readWorkspaceCon
228387
228832
  var contractsMaterializeInPlace = () => active9.materializesInPlace;
228388
228833
 
228389
228834
  // packages/core/dist/lib/repo-doc-reader.js
228390
- import fs56 from "node:fs";
228391
- import path59 from "node:path";
228835
+ import fs57 from "node:fs";
228836
+ import path60 from "node:path";
228392
228837
  var fileRepoDocReader = async (repoKey, docPath) => {
228393
- const root = path59.resolve(repoKey);
228394
- const full = path59.resolve(root, docPath);
228395
- if (full !== root && !full.startsWith(root + path59.sep))
228838
+ const root = path60.resolve(repoKey);
228839
+ const full = path60.resolve(root, docPath);
228840
+ if (full !== root && !full.startsWith(root + path60.sep))
228396
228841
  return null;
228397
- if (!fs56.existsSync(full) || !fs56.statSync(full).isFile())
228842
+ if (!fs57.existsSync(full) || !fs57.statSync(full).isFile())
228398
228843
  return null;
228399
- return fs56.readFileSync(full, "utf-8");
228844
+ return fs57.readFileSync(full, "utf-8");
228400
228845
  };
228401
228846
  var reader = fileRepoDocReader;
228402
228847
  function readRepoDoc(repoKey, docPath, opts) {
@@ -228404,23 +228849,23 @@ function readRepoDoc(repoKey, docPath, opts) {
228404
228849
  }
228405
228850
 
228406
228851
  // packages/core/dist/lib/inferred-action-store.js
228407
- import fs57 from "node:fs";
228408
- import path60 from "node:path";
228852
+ import fs58 from "node:fs";
228853
+ import path61 from "node:path";
228409
228854
  function actionsFile(repoKey) {
228410
- return path60.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
228855
+ return path61.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
228411
228856
  }
228412
228857
  var FileInferredActionStore = class {
228413
228858
  read(repoKey) {
228414
228859
  try {
228415
- return JSON.parse(fs57.readFileSync(actionsFile(repoKey), "utf-8"));
228860
+ return JSON.parse(fs58.readFileSync(actionsFile(repoKey), "utf-8"));
228416
228861
  } catch {
228417
228862
  return [];
228418
228863
  }
228419
228864
  }
228420
228865
  write(repoKey, actions) {
228421
228866
  const file = actionsFile(repoKey);
228422
- fs57.mkdirSync(path60.dirname(file), { recursive: true });
228423
- fs57.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
228867
+ fs58.mkdirSync(path61.dirname(file), { recursive: true });
228868
+ fs58.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
228424
228869
  }
228425
228870
  async setAction(repoKey, action) {
228426
228871
  const next = this.read(repoKey).filter((a) => !(a.kind === action.kind && a.identity === action.identity));
@@ -228543,8 +228988,8 @@ async function reapplyPromoted(ref, decisions) {
228543
228988
  }
228544
228989
 
228545
228990
  // packages/core/dist/services/telemetry.service.js
228546
- import fs58 from "node:fs";
228547
- import path61 from "node:path";
228991
+ import fs59 from "node:fs";
228992
+ import path62 from "node:path";
228548
228993
  import os9 from "node:os";
228549
228994
  import crypto5 from "node:crypto";
228550
228995
  import { fileURLToPath as fileURLToPath5 } from "node:url";
@@ -229284,8 +229729,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname9(proce
229284
229729
  return decodedFile;
229285
229730
  };
229286
229731
  }
229287
- function normalizeWindowsPath(path74) {
229288
- return path74.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
229732
+ function normalizeWindowsPath(path75) {
229733
+ return path75.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
229289
229734
  }
229290
229735
  var ReduceableCache = class {
229291
229736
  constructor(_maxSize) {
@@ -229364,9 +229809,9 @@ async function addSourceContext(frames) {
229364
229809
  LRU_FILE_CONTENTS_CACHE.reduce();
229365
229810
  return frames;
229366
229811
  }
229367
- function getContextLinesFromFile(path74, ranges, output) {
229812
+ function getContextLinesFromFile(path75, ranges, output) {
229368
229813
  return new Promise((resolve11) => {
229369
- const stream = createReadStream(path74);
229814
+ const stream = createReadStream(path75);
229370
229815
  const lineReaded = createInterface({
229371
229816
  input: stream
229372
229817
  });
@@ -229384,7 +229829,7 @@ function getContextLinesFromFile(path74, ranges, output) {
229384
229829
  let rangeStart = range2[0];
229385
229830
  let rangeEnd = range2[1];
229386
229831
  function onStreamError() {
229387
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path74, 1);
229832
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path75, 1);
229388
229833
  lineReaded.close();
229389
229834
  lineReaded.removeAllListeners();
229390
229835
  destroyStreamAndResolve();
@@ -229461,8 +229906,8 @@ function clearLineContext(frame) {
229461
229906
  delete frame.context_line;
229462
229907
  delete frame.post_context;
229463
229908
  }
229464
- function shouldSkipContextLinesForFile(path74) {
229465
- return path74.startsWith("node:") || path74.endsWith(".min.js") || path74.endsWith(".min.cjs") || path74.endsWith(".min.mjs") || path74.startsWith("data:");
229909
+ function shouldSkipContextLinesForFile(path75) {
229910
+ return path75.startsWith("node:") || path75.endsWith(".min.js") || path75.endsWith(".min.cjs") || path75.endsWith(".min.mjs") || path75.startsWith("data:");
229466
229911
  }
229467
229912
  function shouldSkipContextLinesForFrame(frame) {
229468
229913
  if (frame.lineno !== void 0 && frame.lineno > MAX_CONTEXTLINES_LINENO) {
@@ -232334,12 +232779,12 @@ var DEFAULT_CONFIG = {
232334
232779
  };
232335
232780
  var POSTHOG_API_KEY = "phc_ys9Ykf49KmNqAC3fhq3jugTejc4BDqyKqRS8qRoYZYew";
232336
232781
  function getTelemetryConfigPath() {
232337
- return path61.join(os9.homedir(), ".truecourse", "telemetry.json");
232782
+ return path62.join(os9.homedir(), ".truecourse", "telemetry.json");
232338
232783
  }
232339
232784
  function readTelemetryConfig() {
232340
232785
  const configPath = getTelemetryConfigPath();
232341
232786
  try {
232342
- const raw = fs58.readFileSync(configPath, "utf-8");
232787
+ const raw = fs59.readFileSync(configPath, "utf-8");
232343
232788
  const parsed = JSON.parse(raw);
232344
232789
  const config2 = { ...DEFAULT_CONFIG, ...parsed };
232345
232790
  if (!config2.anonymousId) {
@@ -232359,17 +232804,17 @@ function readTelemetryConfig() {
232359
232804
  }
232360
232805
  function writeTelemetryConfig(partial) {
232361
232806
  const configPath = getTelemetryConfigPath();
232362
- const dir = path61.dirname(configPath);
232363
- fs58.mkdirSync(dir, { recursive: true });
232807
+ const dir = path62.dirname(configPath);
232808
+ fs59.mkdirSync(dir, { recursive: true });
232364
232809
  let current;
232365
232810
  try {
232366
- const raw = fs58.readFileSync(configPath, "utf-8");
232811
+ const raw = fs59.readFileSync(configPath, "utf-8");
232367
232812
  current = { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
232368
232813
  } catch {
232369
232814
  current = { ...DEFAULT_CONFIG };
232370
232815
  }
232371
232816
  const merged = { ...current, ...partial };
232372
- fs58.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
232817
+ fs59.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
232373
232818
  }
232374
232819
  var posthogClient = null;
232375
232820
  function isTelemetryEnabled() {
@@ -232428,7 +232873,7 @@ function detectLanguages(result) {
232428
232873
  const languages = /* @__PURE__ */ new Set();
232429
232874
  for (const service of result.services) {
232430
232875
  for (const filePath of service.files) {
232431
- const ext2 = path61.extname(filePath).toLowerCase();
232876
+ const ext2 = path62.extname(filePath).toLowerCase();
232432
232877
  const lang = EXTENSION_TO_LANGUAGE[ext2];
232433
232878
  if (lang)
232434
232879
  languages.add(lang);
@@ -232441,13 +232886,13 @@ function readToolVersion() {
232441
232886
  if (cachedVersion)
232442
232887
  return cachedVersion;
232443
232888
  if (true) {
232444
- cachedVersion = "0.7.0-next.7";
232889
+ cachedVersion = "0.7.0-next.9";
232445
232890
  return cachedVersion;
232446
232891
  }
232447
232892
  try {
232448
232893
  const here = fileURLToPath5(import.meta.url);
232449
- const pkgPath = path61.resolve(path61.dirname(here), "..", "..", "package.json");
232450
- const pkg = JSON.parse(fs58.readFileSync(pkgPath, "utf-8"));
232894
+ const pkgPath = path62.resolve(path62.dirname(here), "..", "..", "package.json");
232895
+ const pkg = JSON.parse(fs59.readFileSync(pkgPath, "utf-8"));
232451
232896
  cachedVersion = String(pkg.version ?? "0.0.0");
232452
232897
  } catch {
232453
232898
  cachedVersion = "0.0.0";
@@ -232587,13 +233032,13 @@ function resolveTransport(options) {
232587
233032
  }
232588
233033
  return getDefaultTransport();
232589
233034
  }
232590
- var GENERATED_MARKER_REL = path62.join(".truecourse", "contracts", "result.json");
233035
+ var GENERATED_MARKER_REL = path63.join(".truecourse", "contracts", "result.json");
232591
233036
  function generatedMarkerPath(repoRoot) {
232592
- return path62.join(repoRoot, GENERATED_MARKER_REL);
233037
+ return path63.join(repoRoot, GENERATED_MARKER_REL);
232593
233038
  }
232594
233039
  function stampGeneratedMarker(repoRoot, summary) {
232595
233040
  const file = generatedMarkerPath(repoRoot);
232596
- fs59.mkdirSync(path62.dirname(file), { recursive: true });
233041
+ fs60.mkdirSync(path63.dirname(file), { recursive: true });
232597
233042
  const body = {
232598
233043
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
232599
233044
  written: summary?.written ?? 0,
@@ -232601,11 +233046,11 @@ function stampGeneratedMarker(repoRoot, summary) {
232601
233046
  validationIssues: summary?.validationIssues ?? [],
232602
233047
  enumerateFailures: summary?.enumerateFailures ?? []
232603
233048
  };
232604
- fs59.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
233049
+ fs60.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
232605
233050
  }
232606
233051
  function readGeneratedSummary(repoRoot) {
232607
233052
  try {
232608
- const raw = JSON.parse(fs59.readFileSync(generatedMarkerPath(repoRoot), "utf-8"));
233053
+ const raw = JSON.parse(fs60.readFileSync(generatedMarkerPath(repoRoot), "utf-8"));
232609
233054
  return {
232610
233055
  generatedAt: typeof raw.generatedAt === "string" ? raw.generatedAt : "",
232611
233056
  written: typeof raw.written === "number" ? raw.written : 0,
@@ -232739,22 +233184,22 @@ async function curateInProcess(repoRoot, options = {}) {
232739
233184
  }
232740
233185
  }
232741
233186
  function buildPriorContracts(repoRoot) {
232742
- const dir = path62.join(repoRoot, ".truecourse", "contracts");
232743
- if (!fs59.existsSync(dir))
233187
+ const dir = path63.join(repoRoot, ".truecourse", "contracts");
233188
+ if (!fs60.existsSync(dir))
232744
233189
  return void 0;
232745
233190
  const targets = [];
232746
233191
  const bodyByKey = /* @__PURE__ */ new Map();
232747
233192
  const walk20 = (d) => {
232748
- for (const e of fs59.readdirSync(d, { withFileTypes: true })) {
233193
+ for (const e of fs60.readdirSync(d, { withFileTypes: true })) {
232749
233194
  if (e.isDirectory()) {
232750
233195
  if (e.name === "_inferred")
232751
233196
  continue;
232752
- walk20(path62.join(d, e.name));
233197
+ walk20(path63.join(d, e.name));
232753
233198
  } else if (e.name.endsWith(".tc")) {
232754
- const abs = path62.join(d, e.name);
232755
- const src = fs59.readFileSync(abs, "utf-8");
233199
+ const abs = path63.join(d, e.name);
233200
+ const src = fs60.readFileSync(abs, "utf-8");
232756
233201
  try {
232757
- const file = parser_ohm_exports.parseTcFile(path62.relative(dir, abs), src);
233202
+ const file = parser_ohm_exports.parseTcFile(path63.relative(dir, abs), src);
232758
233203
  for (const key4 of resolver_exports.resolve([file]).index.keys()) {
232759
233204
  const colon = key4.indexOf(":");
232760
233205
  if (colon < 0)
@@ -232914,9 +233359,9 @@ function resolverHardError(result) {
232914
233359
  const detail = reasons.length ? reasons.slice(0, 3).join("; ") : "duplicate or conflicting artifact identities";
232915
233360
  return new Error(`Contract corpus failed to resolve \u2014 ${detail}`);
232916
233361
  }
232917
- var LEGACY_VERIFY_STATE_REL = path62.join(".truecourse", ".cache", "verifier", "verify-state.json");
233362
+ var LEGACY_VERIFY_STATE_REL = path63.join(".truecourse", ".cache", "verifier", "verify-state.json");
232918
233363
  function legacyVerifyStatePath(repoRoot) {
232919
- return path62.join(repoRoot, LEGACY_VERIFY_STATE_REL);
233364
+ return path63.join(repoRoot, LEGACY_VERIFY_STATE_REL);
232920
233365
  }
232921
233366
  async function readVerifyState(repoRoot) {
232922
233367
  const latest = await readVerifyLatest(repoRoot);
@@ -232954,13 +233399,13 @@ async function readVerifyRunState(repoRoot, runId) {
232954
233399
  };
232955
233400
  }
232956
233401
  async function withContracts(repoRoot, options, tracker, fn) {
232957
- const fallbackPath = path62.join(repoRoot, ".truecourse", "contracts");
233402
+ const fallbackPath = path63.join(repoRoot, ".truecourse", "contracts");
232958
233403
  const wsMat = options.workspaceOrgId ? await loadWorkspaceContracts({ workspaceOrgId: options.workspaceOrgId }, "contracts") : null;
232959
233404
  let repoMat = null;
232960
233405
  try {
232961
233406
  let recorded;
232962
233407
  if (options.contractsDir) {
232963
- if (!fs59.existsSync(options.contractsDir)) {
233408
+ if (!fs60.existsSync(options.contractsDir)) {
232964
233409
  const err = new Error(`Contracts directory not found at ${options.contractsDir}. Run \`truecourse contracts generate\` first.`);
232965
233410
  tracker?.error("load", err.message);
232966
233411
  throw err;
@@ -233005,7 +233450,7 @@ async function verifyInProcess(repoRoot, options = {}) {
233005
233450
  tracker?.start("compare");
233006
233451
  tracker?.done("compare", `${result.drifts.length} drift${result.drifts.length === 1 ? "" : "s"}`);
233007
233452
  if (options.ref) {
233008
- result.drifts = result.drifts.map((d) => d.filePath && path62.isAbsolute(d.filePath) ? { ...d, filePath: path62.relative(repoRoot, d.filePath).split(path62.sep).join("/") } : d);
233453
+ result.drifts = result.drifts.map((d) => d.filePath && path63.isAbsolute(d.filePath) ? { ...d, filePath: path63.relative(repoRoot, d.filePath).split(path63.sep).join("/") } : d);
233009
233454
  }
233010
233455
  const verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
233011
233456
  const { branch, commitHash } = await gitMeta(repoRoot);
@@ -233049,7 +233494,7 @@ async function verifyInProcess(repoRoot, options = {}) {
233049
233494
  bySeverity: summary.bySeverity
233050
233495
  });
233051
233496
  await deleteVerifyDiff(storeKey);
233052
- fs59.rmSync(legacyVerifyStatePath(repoRoot), { force: true });
233497
+ fs60.rmSync(legacyVerifyStatePath(repoRoot), { force: true });
233053
233498
  }
233054
233499
  const state = {
233055
233500
  verifiedAt,
@@ -233097,7 +233542,7 @@ async function runWithStash(repoRoot, skipStash, tracker, fn) {
233097
233542
  const status = await stashGit.status();
233098
233543
  if (!status.isClean()) {
233099
233544
  const gitRoot = (await stashGit.revparse(["--show-toplevel"])).trim();
233100
- if (path62.resolve(repoRoot) === path62.resolve(gitRoot)) {
233545
+ if (path63.resolve(repoRoot) === path63.resolve(gitRoot)) {
233101
233546
  tracker?.detail?.("load", "Stashing pending changes...");
233102
233547
  const res = await stashGit.stash(["push", "--include-untracked", "-m", "truecourse-verify-stash"]);
233103
233548
  didStash = !res.includes("No local changes");
@@ -233199,7 +233644,7 @@ async function verifyDiffInProcess(repoRoot, options = {}) {
233199
233644
  async function inferInProcess(repoRoot, options = {}) {
233200
233645
  const startedAt = Date.now();
233201
233646
  const codeDir = options.codeDir ?? autodetectCodeDir(repoRoot);
233202
- let contractsDir = options.contractsDir ?? path62.join(repoRoot, ".truecourse", "contracts");
233647
+ let contractsDir = options.contractsDir ?? path63.join(repoRoot, ".truecourse", "contracts");
233203
233648
  let releaseContracts = async () => {
233204
233649
  };
233205
233650
  if (!options.contractsDir && options.ref) {
@@ -233243,7 +233688,7 @@ async function persistInferred(repoRoot, options, contractsDir, codeDir, started
233243
233688
  });
233244
233689
  }
233245
233690
  if (!options.dryRun && options.ref) {
233246
- await saveContracts(options.ref, "contracts_inferred", path62.join(contractsDir, "_inferred"));
233691
+ await saveContracts(options.ref, "contracts_inferred", path63.join(contractsDir, "_inferred"));
233247
233692
  }
233248
233693
  const rendered = result.decisions.map((d) => renderDecision(d));
233249
233694
  const decisionPaths = rendered.map((r) => r.relPath);
@@ -233274,8 +233719,8 @@ async function inferDiffInProcess(repoRoot, options = {}) {
233274
233719
  return diffDecisions(head, base);
233275
233720
  }
233276
233721
  function autodetectCodeDir(repoRoot) {
233277
- const codeSubdir = path62.join(repoRoot, "code");
233278
- if (fs59.existsSync(codeSubdir) && fs59.statSync(codeSubdir).isDirectory()) {
233722
+ const codeSubdir = path63.join(repoRoot, "code");
233723
+ if (fs60.existsSync(codeSubdir) && fs60.statSync(codeSubdir).isDirectory()) {
233279
233724
  return codeSubdir;
233280
233725
  }
233281
233726
  return repoRoot;
@@ -233285,7 +233730,8 @@ var EMPTY_DECISIONS3 = {
233285
233730
  manualIncludes: [],
233286
233731
  manualExcludes: [],
233287
233732
  relations: [],
233288
- manualAreas: []
233733
+ manualAreas: [],
233734
+ conflictResolutions: []
233289
233735
  };
233290
233736
  var DECISIONS_REF = "_repo";
233291
233737
  var prDecisionsRef = (pr) => `_pr/${pr}`;
@@ -233339,7 +233785,12 @@ function mergeDecisions(base, overlay) {
233339
233785
  ...(base.manualAreas ?? []).filter((a) => !overlayAreaDocs.has(a.doc)),
233340
233786
  ...overlay.manualAreas ?? []
233341
233787
  ];
233342
- return { version: 1, manualIncludes, manualExcludes, relations, manualAreas };
233788
+ const overlayResKeys = new Set((overlay.conflictResolutions ?? []).map(conflictResolutionKey));
233789
+ const conflictResolutions = [
233790
+ ...(base.conflictResolutions ?? []).filter((r) => !overlayResKeys.has(conflictResolutionKey(r))),
233791
+ ...overlay.conflictResolutions ?? []
233792
+ ];
233793
+ return { version: 1, manualIncludes, manualExcludes, relations, manualAreas, conflictResolutions };
233343
233794
  }
233344
233795
  function uniqueStrings(items) {
233345
233796
  return [...new Set(items)];
@@ -233393,7 +233844,7 @@ async function recurateStoredCorpus(repoKey) {
233393
233844
  const commitSha = await baselineSpecCommit(repoKey);
233394
233845
  if (commitSha)
233395
233846
  await saveSpec({ repoKey, commitSha }, "corpus", result.corpus);
233396
- return { corpus: result.corpus, openConflicts: result.stats.overlapFlags };
233847
+ return { corpus: result.corpus, openConflicts: openConflicts(result.corpus, decisions).length };
233397
233848
  }
233398
233849
  async function baselineSpecCommit(repoKey) {
233399
233850
  return (await readVerifyState(repoKey))?.commitHash ?? null;
@@ -233416,9 +233867,16 @@ async function recuratePrCorpus(repoKey, prHeadSha, prNumber) {
233416
233867
  skipCorpusWrite: true
233417
233868
  });
233418
233869
  await saveSpec({ repoKey, commitSha: prHeadSha }, "corpus", result.corpus);
233419
- return { corpus: result.corpus, openConflicts: result.stats.overlapFlags };
233870
+ return { corpus: result.corpus, openConflicts: openConflicts(result.corpus, decisions).length };
233420
233871
  }
233421
233872
  var relationKey = (r) => `${[r.older, r.newer].sort().join(" ")} ${r.scope ?? ""}`;
233873
+ var conflictResolutionKey = (r) => {
233874
+ const sides = [
233875
+ `${r.docA}#${r.anchorA ?? ""}`,
233876
+ `${r.docB}#${r.anchorB ?? ""}`
233877
+ ].sort();
233878
+ return sides.join(" \0 ");
233879
+ };
233422
233880
  function applyAddRelation(existing, input) {
233423
233881
  if (input.older === input.newer) {
233424
233882
  throw new Error("addRelation: older and newer must be different docs");
@@ -233431,20 +233889,22 @@ function applyAddRelation(existing, input) {
233431
233889
  manualIncludes: existing.manualIncludes ?? [],
233432
233890
  manualExcludes: existing.manualExcludes ?? [],
233433
233891
  relations: [...dedup, relation],
233434
- manualAreas: existing.manualAreas ?? []
233892
+ manualAreas: existing.manualAreas ?? [],
233893
+ conflictResolutions: existing.conflictResolutions ?? []
233435
233894
  };
233436
233895
  }
233437
233896
  function applyRemoveRelation(existing, input) {
233438
233897
  const matches = (r) => {
233439
- const samePair = r.older === input.older && r.newer === input.newer || r.older === input.newer && r.newer === input.older;
233440
- return samePair && (input.scope === void 0 || r.scope === input.scope);
233898
+ const samePair2 = r.older === input.older && r.newer === input.newer || r.older === input.newer && r.newer === input.older;
233899
+ return samePair2 && (input.scope === void 0 || r.scope === input.scope);
233441
233900
  };
233442
233901
  return {
233443
233902
  version: 1,
233444
233903
  manualIncludes: existing.manualIncludes ?? [],
233445
233904
  manualExcludes: existing.manualExcludes ?? [],
233446
233905
  relations: (existing.relations ?? []).filter((r) => !matches(r)),
233447
- manualAreas: existing.manualAreas ?? []
233906
+ manualAreas: existing.manualAreas ?? [],
233907
+ conflictResolutions: existing.conflictResolutions ?? []
233448
233908
  };
233449
233909
  }
233450
233910
  function applyAddManualInclude(existing, docPath) {
@@ -233457,7 +233917,8 @@ function applyAddManualInclude(existing, docPath) {
233457
233917
  manualIncludes: includes.includes(docPath) ? includes : [...includes, docPath],
233458
233918
  manualExcludes: excludes.filter((p) => p !== docPath),
233459
233919
  relations: existing.relations ?? [],
233460
- manualAreas: existing.manualAreas ?? []
233920
+ manualAreas: existing.manualAreas ?? [],
233921
+ conflictResolutions: existing.conflictResolutions ?? []
233461
233922
  };
233462
233923
  }
233463
233924
  function applyRemoveManualInclude(existing, docPath) {
@@ -233466,7 +233927,8 @@ function applyRemoveManualInclude(existing, docPath) {
233466
233927
  manualIncludes: (existing.manualIncludes ?? []).filter((p) => p !== docPath),
233467
233928
  manualExcludes: existing.manualExcludes ?? [],
233468
233929
  relations: existing.relations ?? [],
233469
- manualAreas: existing.manualAreas ?? []
233930
+ manualAreas: existing.manualAreas ?? [],
233931
+ conflictResolutions: existing.conflictResolutions ?? []
233470
233932
  };
233471
233933
  }
233472
233934
  function applyAddManualExclude(existing, docPath) {
@@ -233479,7 +233941,8 @@ function applyAddManualExclude(existing, docPath) {
233479
233941
  manualIncludes: includes.filter((p) => p !== docPath),
233480
233942
  manualExcludes: excludes.includes(docPath) ? excludes : [...excludes, docPath],
233481
233943
  relations: existing.relations ?? [],
233482
- manualAreas: existing.manualAreas ?? []
233944
+ manualAreas: existing.manualAreas ?? [],
233945
+ conflictResolutions: existing.conflictResolutions ?? []
233483
233946
  };
233484
233947
  }
233485
233948
  function applyRemoveManualExclude(existing, docPath) {
@@ -233488,7 +233951,34 @@ function applyRemoveManualExclude(existing, docPath) {
233488
233951
  manualIncludes: existing.manualIncludes ?? [],
233489
233952
  manualExcludes: (existing.manualExcludes ?? []).filter((p) => p !== docPath),
233490
233953
  relations: existing.relations ?? [],
233491
- manualAreas: existing.manualAreas ?? []
233954
+ manualAreas: existing.manualAreas ?? [],
233955
+ conflictResolutions: existing.conflictResolutions ?? []
233956
+ };
233957
+ }
233958
+ function applyAddConflictResolution(existing, input) {
233959
+ if (input.docA === input.docB) {
233960
+ throw new Error("addConflictResolution: docA and docB must be different docs");
233961
+ }
233962
+ const key4 = conflictResolutionKey(input);
233963
+ const dedup = (existing.conflictResolutions ?? []).filter((r) => conflictResolutionKey(r) !== key4);
233964
+ return {
233965
+ version: 1,
233966
+ manualIncludes: existing.manualIncludes ?? [],
233967
+ manualExcludes: existing.manualExcludes ?? [],
233968
+ relations: existing.relations ?? [],
233969
+ manualAreas: existing.manualAreas ?? [],
233970
+ conflictResolutions: [...dedup, input]
233971
+ };
233972
+ }
233973
+ function applyRemoveConflictResolution(existing, input) {
233974
+ const key4 = conflictResolutionKey({ ...input, verdict: "dismissed", resolvedAt: "" });
233975
+ return {
233976
+ version: 1,
233977
+ manualIncludes: existing.manualIncludes ?? [],
233978
+ manualExcludes: existing.manualExcludes ?? [],
233979
+ relations: existing.relations ?? [],
233980
+ manualAreas: existing.manualAreas ?? [],
233981
+ conflictResolutions: (existing.conflictResolutions ?? []).filter((r) => conflictResolutionKey(r) !== key4)
233492
233982
  };
233493
233983
  }
233494
233984
  async function addRelation(repoRoot, input, opts) {
@@ -233525,6 +234015,16 @@ async function removeManualExclude(repoRoot, docPath, opts) {
233525
234015
  await storeDecisions(repoRoot, next, opts);
233526
234016
  return next;
233527
234017
  }
234018
+ async function addConflictResolution(repoRoot, input, opts) {
234019
+ const next = applyAddConflictResolution(await loadDecisions(repoRoot, opts), input);
234020
+ await storeDecisions(repoRoot, next, opts);
234021
+ return next;
234022
+ }
234023
+ async function removeConflictResolution(repoRoot, input, opts) {
234024
+ const next = applyRemoveConflictResolution(await loadDecisions(repoRoot, opts), input);
234025
+ await storeDecisions(repoRoot, next, opts);
234026
+ return next;
234027
+ }
233528
234028
 
233529
234029
  // packages/core/dist/commands/repo-events.js
233530
234030
  function pickLatestEvent(candidates, registryLastAnalyzed) {
@@ -233630,10 +234130,10 @@ router.post("/", async (req, res, next) => {
233630
234130
  throw createAppError("Invalid request body: path is required", 400);
233631
234131
  }
233632
234132
  const repoPath = parsed.data.path;
233633
- if (!fs60.existsSync(repoPath)) {
234133
+ if (!fs61.existsSync(repoPath)) {
233634
234134
  throw createAppError(`Path does not exist: ${repoPath}`, 400);
233635
234135
  }
233636
- if (!fs60.statSync(repoPath).isDirectory()) {
234136
+ if (!fs61.statSync(repoPath).isDirectory()) {
233637
234137
  throw createAppError(`Path is not a directory: ${repoPath}`, 400);
233638
234138
  }
233639
234139
  const entry = await registerProject(repoPath);
@@ -233716,8 +234216,8 @@ router.delete("/:id", async (req, res, next) => {
233716
234216
  throw createAppError("Project not found", 404);
233717
234217
  }
233718
234218
  const tcDir = getRepoTruecourseDir(entry.path);
233719
- if (fs60.existsSync(tcDir)) {
233720
- fs60.rmSync(tcDir, { recursive: true, force: true });
234219
+ if (fs61.existsSync(tcDir)) {
234220
+ fs61.rmSync(tcDir, { recursive: true, force: true });
233721
234221
  }
233722
234222
  await unregisterProject(slug2);
233723
234223
  res.status(204).send();
@@ -233788,7 +234288,7 @@ var repos_default = router;
233788
234288
  // apps/dashboard/server/src/routes/analyses.ts
233789
234289
  var import_express2 = __toESM(require_express2(), 1);
233790
234290
  init_dist();
233791
- import path66 from "node:path";
234291
+ import path67 from "node:path";
233792
234292
 
233793
234293
  // packages/core/dist/config/current-project.js
233794
234294
  async function resolveProjectForRequest(slug2) {
@@ -233804,7 +234304,7 @@ async function resolveProjectForRequest(slug2) {
233804
234304
  // packages/core/dist/commands/analyze-core.js
233805
234305
  init_logger();
233806
234306
  import { randomUUID as randomUUID27 } from "node:crypto";
233807
- import path64 from "node:path";
234307
+ import path65 from "node:path";
233808
234308
 
233809
234309
  // packages/core/dist/services/analyzer.service.js
233810
234310
  init_logger();
@@ -234426,8 +234926,8 @@ async function enrichFlowWithLLM(repoPath, flowId) {
234426
234926
  // packages/core/dist/services/violation-pipeline.service.js
234427
234927
  init_dist3();
234428
234928
  import { randomUUID as randomUUID26 } from "node:crypto";
234429
- import fs61 from "node:fs";
234430
- import path63 from "node:path";
234929
+ import fs62 from "node:fs";
234930
+ import path64 from "node:path";
234431
234931
  init_provider();
234432
234932
 
234433
234933
  // packages/core/dist/services/violation.service.js
@@ -234829,7 +235329,7 @@ function findCSharpProjectFiles(repoPath) {
234829
235329
  return;
234830
235330
  let entries;
234831
235331
  try {
234832
- entries = fs61.readdirSync(dir, { withFileTypes: true });
235332
+ entries = fs62.readdirSync(dir, { withFileTypes: true });
234833
235333
  } catch {
234834
235334
  return;
234835
235335
  }
@@ -234837,18 +235337,18 @@ function findCSharpProjectFiles(repoPath) {
234837
235337
  if (e.isDirectory()) {
234838
235338
  if (SKIP.has(e.name) || e.name.startsWith("."))
234839
235339
  continue;
234840
- walk20(path63.join(dir, e.name), depth + 1);
235340
+ walk20(path64.join(dir, e.name), depth + 1);
234841
235341
  } else if (e.isFile()) {
234842
235342
  if (e.name.endsWith(".sln") || e.name.endsWith(".slnx"))
234843
- solutions.push(path63.join(dir, e.name));
235343
+ solutions.push(path64.join(dir, e.name));
234844
235344
  else if (e.name.endsWith(".csproj"))
234845
- projects.push(path63.join(dir, e.name));
235345
+ projects.push(path64.join(dir, e.name));
234846
235346
  }
234847
235347
  }
234848
235348
  };
234849
235349
  walk20(repoPath, 0);
234850
235350
  if (solutions.length > 0) {
234851
- solutions.sort((a, b) => a.split(path63.sep).length - b.split(path63.sep).length);
235351
+ solutions.sort((a, b) => a.split(path64.sep).length - b.split(path64.sep).length);
234852
235352
  return [solutions[0]];
234853
235353
  }
234854
235354
  return projects;
@@ -234952,7 +235452,7 @@ async function runViolationPipeline(input) {
234952
235452
  const enabledLlmCodeRules = enableLlmRules !== false ? allRules.filter((r) => (r.domain ? codeDomains.has(r.domain) : r.category === "code") && r.type === "llm" && r.prompt) : [];
234953
235453
  const archLlmRules = allRules.filter((r) => r.type === "llm" && r.prompt && r.domain === "architecture").map((r) => ({ key: r.key, name: r.name, severity: r.severity, prompt: r.prompt, category: r.category }));
234954
235454
  const dbSchemaLlmRules = allRules.filter((r) => r.type === "llm" && r.prompt && r.domain === "database" && r.category === "database").map((r) => ({ key: r.key, name: r.name, severity: r.severity, prompt: r.prompt, category: r.category }));
234955
- const filesToScan = changedFileSet ? [...changedFileSet].map((relPath) => ({ filePath: relPath, resolve: true })) : (result.fileAnalyses || []).map((fa) => ({ filePath: fa.filePath, resolve: !path63.isAbsolute(fa.filePath) }));
235455
+ const filesToScan = changedFileSet ? [...changedFileSet].map((relPath) => ({ filePath: relPath, resolve: true })) : (result.fileAnalyses || []).map((fa) => ({ filePath: fa.filePath, resolve: !path64.isAbsolute(fa.filePath) }));
234956
235456
  const hasLlm = enabledLlm.length > 0;
234957
235457
  if (hasLlm)
234958
235458
  tracker?.start("scan", "Reading files...");
@@ -234964,10 +235464,10 @@ async function runViolationPipeline(input) {
234964
235464
  const lang = detectLanguage(filePath);
234965
235465
  if (!lang)
234966
235466
  continue;
234967
- const absPath = resolve11 ? path63.resolve(repoPath, filePath) : path63.isAbsolute(filePath) ? filePath : path63.join(repoPath, filePath);
234968
- if (!fs61.existsSync(absPath))
235467
+ const absPath = resolve11 ? path64.resolve(repoPath, filePath) : path64.isAbsolute(filePath) ? filePath : path64.join(repoPath, filePath);
235468
+ if (!fs62.existsSync(absPath))
234969
235469
  continue;
234970
- const content = fs61.readFileSync(absPath, "utf-8");
235470
+ const content = fs62.readFileSync(absPath, "utf-8");
234971
235471
  const lineCount = content.split("\n").length;
234972
235472
  fileContents.set(changedFileSet ? absPath : filePath, { content, lineCount });
234973
235473
  } catch {
@@ -234980,7 +235480,7 @@ async function runViolationPipeline(input) {
234980
235480
  let typeQuery;
234981
235481
  const enabledCodeKeys = new Set(enabledCodeRules.filter((r) => r.type === "deterministic" && r.enabled).map((r) => r.key));
234982
235482
  if (hasTypeAwareVisitors(enabledCodeKeys)) {
234983
- const tsFiles = filesToScan.filter(({ filePath: fp }) => /\.(ts|tsx|js|jsx)$/.test(fp)).map(({ filePath: fp, resolve: res }) => res ? path63.resolve(repoPath, fp) : path63.isAbsolute(fp) ? fp : path63.join(repoPath, fp));
235483
+ const tsFiles = filesToScan.filter(({ filePath: fp }) => /\.(ts|tsx|js|jsx)$/.test(fp)).map(({ filePath: fp, resolve: res }) => res ? path64.resolve(repoPath, fp) : path64.isAbsolute(fp) ? fp : path64.join(repoPath, fp));
234984
235484
  if (tsFiles.length > 0) {
234985
235485
  const scoped = buildScopedCompilerOptions(repoPath);
234986
235486
  typeQuery = createTypeQueryService(tsFiles, scoped, repoPath);
@@ -235074,7 +235574,7 @@ async function runViolationPipeline(input) {
235074
235574
  const lang = detectLanguage(filePath);
235075
235575
  if (!lang)
235076
235576
  continue;
235077
- const absPath = resolve11 ? path63.resolve(repoPath, filePath) : path63.isAbsolute(filePath) ? filePath : path63.join(repoPath, filePath);
235577
+ const absPath = resolve11 ? path64.resolve(repoPath, filePath) : path64.isAbsolute(filePath) ? filePath : path64.join(repoPath, filePath);
235078
235578
  const key4 = changedFileSet ? absPath : filePath;
235079
235579
  const fc = fileContents.get(key4);
235080
235580
  if (!fc)
@@ -235131,7 +235631,7 @@ async function runViolationPipeline(input) {
235131
235631
  for (const { filePath, resolve: resolve11 } of filesToScan) {
235132
235632
  if (detectLanguage(filePath) !== "csharp")
235133
235633
  continue;
235134
- const absPath = resolve11 ? path63.resolve(repoPath, filePath) : path63.isAbsolute(filePath) ? filePath : path63.join(repoPath, filePath);
235634
+ const absPath = resolve11 ? path64.resolve(repoPath, filePath) : path64.isAbsolute(filePath) ? filePath : path64.join(repoPath, filePath);
235135
235635
  const key4 = changedFileSet ? absPath : filePath;
235136
235636
  const fc = fileContents.get(key4);
235137
235637
  if (fc)
@@ -235170,26 +235670,26 @@ async function runViolationPipeline(input) {
235170
235670
  const ruleByKey = new Map(enabledWorkspaceRules.map((r) => [r.key, r]));
235171
235671
  const ruleKeys = enabledWorkspaceRules.map((r) => r.key);
235172
235672
  for (const [pi, projectFile] of projectFiles.entries()) {
235173
- startCsharpStep(projectFiles.length > 1 ? `Loading project ${pi + 1}/${projectFiles.length}: ${path63.basename(projectFile)}\u2026` : `Loading project ${path63.basename(projectFile)}\u2026`);
235673
+ startCsharpStep(projectFiles.length > 1 ? `Loading project ${pi + 1}/${projectFiles.length}: ${path64.basename(projectFile)}\u2026` : `Loading project ${path64.basename(projectFile)}\u2026`);
235174
235674
  let wsViolations;
235175
235675
  try {
235176
235676
  wsViolations = await runRoslynWorkspace(projectFile, ruleKeys);
235177
235677
  } catch (err) {
235178
- tracker?.error("csharp", `Project load failed: ${path63.basename(projectFile)}`);
235678
+ tracker?.error("csharp", `Project load failed: ${path64.basename(projectFile)}`);
235179
235679
  if (err instanceof RoslynHostUnavailableError)
235180
235680
  throw err;
235181
- throw new Error(`Project-aware C# analysis failed for ${path63.basename(projectFile)}: ${err.message}. Restore the project (\`dotnet restore\`) and ensure its pinned .NET SDK is installed.`);
235681
+ throw new Error(`Project-aware C# analysis failed for ${path64.basename(projectFile)}: ${err.message}. Restore the project (\`dotnet restore\`) and ensure its pinned .NET SDK is installed.`);
235182
235682
  }
235183
235683
  for (const v of wsViolations) {
235184
235684
  const rule = ruleByKey.get(v.ruleKey);
235185
235685
  if (!rule)
235186
235686
  continue;
235187
- const relPath = path63.isAbsolute(v.path) ? path63.relative(repoPath, v.path) : v.path;
235687
+ const relPath = path64.isAbsolute(v.path) ? path64.relative(repoPath, v.path) : v.path;
235188
235688
  const fileKey = changedFileSet ? v.path : relPath;
235189
235689
  let snippet2 = fileContents.get(fileKey)?.content.split("\n")[v.line - 1];
235190
235690
  if (snippet2 === void 0) {
235191
235691
  try {
235192
- snippet2 = fs61.readFileSync(v.path, "utf-8").split("\n")[v.line - 1];
235692
+ snippet2 = fs62.readFileSync(v.path, "utf-8").split("\n")[v.line - 1];
235193
235693
  } catch {
235194
235694
  snippet2 = "";
235195
235695
  }
@@ -235216,11 +235716,11 @@ async function runViolationPipeline(input) {
235216
235716
  }
235217
235717
  log.info(`[Pipeline] Code scan: ${allCodeViolations.length} violations from ${filesToScan.length} files (${enabledCodeRules.length} det rules, ${enabledLlmCodeRules.length} LLM rules)`);
235218
235718
  if (enabledCodeRules.some((r) => r.key === "bugs/deterministic/invalid-pyproject-toml")) {
235219
- const pyprojectPath = path63.join(repoPath, "pyproject.toml");
235220
- if (fs61.existsSync(pyprojectPath)) {
235719
+ const pyprojectPath = path64.join(repoPath, "pyproject.toml");
235720
+ if (fs62.existsSync(pyprojectPath)) {
235221
235721
  try {
235222
235722
  const { checkPyprojectToml: checkPyprojectToml2 } = await Promise.resolve().then(() => (init_dist3(), dist_exports));
235223
- const content = fs61.readFileSync(pyprojectPath, "utf-8");
235723
+ const content = fs62.readFileSync(pyprojectPath, "utf-8");
235224
235724
  const tomlViolations = checkPyprojectToml2(pyprojectPath, content);
235225
235725
  allCodeViolations.push(...tomlViolations);
235226
235726
  } catch {
@@ -236053,7 +236553,7 @@ function processLlmCodeViolations(codeResult, validFilePaths, fileContents, allC
236053
236553
  for (const v of codeResult.violations) {
236054
236554
  let filePath = v.filePath;
236055
236555
  if (!validFilePaths.has(filePath)) {
236056
- const resolved = path63.resolve(repoPath, filePath);
236556
+ const resolved = path64.resolve(repoPath, filePath);
236057
236557
  if (validFilePaths.has(resolved)) {
236058
236558
  filePath = resolved;
236059
236559
  } else {
@@ -236108,8 +236608,8 @@ function toUsageRecords(records) {
236108
236608
 
236109
236609
  // packages/core/dist/commands/analyze-core.js
236110
236610
  function toRepoRelative(filePath, codeDir) {
236111
- if (path64.isAbsolute(filePath) && (filePath === codeDir || filePath.startsWith(codeDir + path64.sep))) {
236112
- return path64.relative(codeDir, filePath).split(path64.sep).join("/");
236611
+ if (path65.isAbsolute(filePath) && (filePath === codeDir || filePath.startsWith(codeDir + path65.sep))) {
236612
+ return path65.relative(codeDir, filePath).split(path65.sep).join("/");
236113
236613
  }
236114
236614
  return filePath;
236115
236615
  }
@@ -236163,7 +236663,7 @@ async function analyzeCore(project, options) {
236163
236663
  const status = await stashGit.status();
236164
236664
  if (!status.isClean()) {
236165
236665
  const gitRoot = (await stashGit.revparse(["--show-toplevel"])).trim();
236166
- const isSubdirectory = path64.resolve(codeDir) !== path64.resolve(gitRoot);
236666
+ const isSubdirectory = path65.resolve(codeDir) !== path65.resolve(gitRoot);
236167
236667
  if (!isSubdirectory) {
236168
236668
  options.tracker?.detail("parse", "Stashing pending changes...");
236169
236669
  options.onProgress?.({ detail: "Stashing pending changes to analyze committed state..." });
@@ -236234,7 +236734,7 @@ async function analyzeCore(project, options) {
236234
236734
  options.tracker?.done("parse", `${result.services.length} services, ${result.fileAnalyses?.length ?? 0} files`);
236235
236735
  const previousActiveViolations = latestBaseline ? latestBaseline.violations.filter((v) => branch == null || latestBaseline.analysis.branch == null || latestBaseline.analysis.branch === branch) : [];
236236
236736
  const previousAnalysisId = latestBaseline?.analysis.id ?? null;
236237
- const previousForDiff = previousActiveViolations.map((v) => v.filePath && !path64.isAbsolute(v.filePath) ? { ...v, filePath: path64.resolve(codeDir, v.filePath) } : v);
236737
+ const previousForDiff = previousActiveViolations.map((v) => v.filePath && !path65.isAbsolute(v.filePath) ? { ...v, filePath: path65.resolve(codeDir, v.filePath) } : v);
236238
236738
  const provider = options.provider ?? (effectiveLlmRules ? createLLMProvider(options.transport ?? getDefaultTransport()) : void 0);
236239
236739
  if (provider) {
236240
236740
  provider.setAnalysisId(analysisId);
@@ -236326,7 +236826,7 @@ function enforceLocationInvariant(violations) {
236326
236826
 
236327
236827
  // packages/core/dist/commands/analyze-persist.js
236328
236828
  init_logger();
236329
- import path65 from "node:path";
236829
+ import path66 from "node:path";
236330
236830
  async function persistFullAnalysis(project, core2, startedAt) {
236331
236831
  const filename = buildAnalysisFilename(core2.analysisId, core2.now);
236332
236832
  const snapshot = {
@@ -236454,8 +236954,8 @@ function buildDiffSnapshot(repoPath, core2, baseline) {
236454
236954
  const newViolations = pipelineResult.added.map(denormalize);
236455
236955
  const latestById = new Map(baseline.violations.map((v) => [v.id, v]));
236456
236956
  const resolvedViolations = pipelineResult.resolvedRefs.map((r) => latestById.get(r.id)).filter((v) => !!v);
236457
- const changedAbs = new Set(changedFiles.map((c) => path65.resolve(repoPath, c.path)));
236458
- const matchesChanged = (p) => !!p && (changedAbs.has(p) || changedAbs.has(path65.resolve(repoPath, p)));
236957
+ const changedAbs = new Set(changedFiles.map((c) => path66.resolve(repoPath, c.path)));
236958
+ const matchesChanged = (p) => !!p && (changedAbs.has(p) || changedAbs.has(path66.resolve(repoPath, p)));
236459
236959
  const affectedModules = graph.modules.filter((m) => matchesChanged(m.filePath));
236460
236960
  const affectedModuleIdSet = new Set(affectedModules.map((m) => m.id));
236461
236961
  const serviceNameById = new Map(graph.services.map((s) => [s.id, s.name]));
@@ -236752,7 +237252,7 @@ router2.post("/:id/analyses", async (req, res, next) => {
236752
237252
  const trackerSteps = buildAnalysisSteps(effectiveCategories, effectiveLlmRules);
236753
237253
  const tracker = createSocketTracker(id, trackerSteps);
236754
237254
  pushLogger({
236755
- filePath: path66.join(repo.path, ".truecourse/logs/analyze.log"),
237255
+ filePath: path67.join(repo.path, ".truecourse/logs/analyze.log"),
236756
237256
  tee: process.env.TRUECOURSE_DEV === "1"
236757
237257
  });
236758
237258
  try {
@@ -237018,7 +237518,7 @@ async function resolveStashDecisionForRoute(repoId, repoPath) {
237018
237518
  const status = await git.status();
237019
237519
  if (status.isClean()) return "stash";
237020
237520
  const gitRoot = (await git.revparse(["--show-toplevel"])).trim();
237021
- if (path66.resolve(repoPath) !== path66.resolve(gitRoot)) return "stash";
237521
+ if (path67.resolve(repoPath) !== path67.resolve(gitRoot)) return "stash";
237022
237522
  modifiedCount = status.modified.length + status.staged.length + status.deleted.length + status.created.length;
237023
237523
  untrackedCount = status.not_added.length;
237024
237524
  } catch {
@@ -237120,7 +237620,7 @@ var analyses_default = router2;
237120
237620
  var import_express3 = __toESM(require_express2(), 1);
237121
237621
 
237122
237622
  // packages/core/dist/config/ui-state.js
237123
- import fs62 from "node:fs";
237623
+ import fs63 from "node:fs";
237124
237624
  var EMPTY_STATE = { positions: {}, collapsed: {} };
237125
237625
  function scopeKey(branch, level) {
237126
237626
  return `${branch || "HEAD"}/${level}`;
@@ -237128,10 +237628,10 @@ function scopeKey(branch, level) {
237128
237628
  var FileUiStateStore = class {
237129
237629
  async readUiState(repoDir) {
237130
237630
  const file = getRepoUiStatePath(repoDir);
237131
- if (!fs62.existsSync(file))
237631
+ if (!fs63.existsSync(file))
237132
237632
  return structuredClone(EMPTY_STATE);
237133
237633
  try {
237134
- const parsed = JSON.parse(fs62.readFileSync(file, "utf-8"));
237634
+ const parsed = JSON.parse(fs63.readFileSync(file, "utf-8"));
237135
237635
  return {
237136
237636
  positions: parsed.positions ?? {},
237137
237637
  collapsed: parsed.collapsed ?? {}
@@ -237142,7 +237642,7 @@ var FileUiStateStore = class {
237142
237642
  }
237143
237643
  async writeUiState(repoDir, state) {
237144
237644
  ensureRepoTruecourseDir(repoDir);
237145
- fs62.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
237645
+ fs63.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
237146
237646
  }
237147
237647
  };
237148
237648
  var active11 = new FileUiStateStore();
@@ -238025,8 +238525,8 @@ var graph_default = router3;
238025
238525
 
238026
238526
  // apps/dashboard/server/src/routes/files.ts
238027
238527
  var import_express4 = __toESM(require_express2(), 1);
238028
- import fs63 from "node:fs";
238029
- import path67 from "node:path";
238528
+ import fs64 from "node:fs";
238529
+ import path68 from "node:path";
238030
238530
  var router4 = (0, import_express4.Router)();
238031
238531
  router4.get("/:id/files", async (req, res, next) => {
238032
238532
  try {
@@ -238055,28 +238555,28 @@ router4.get("/:id/file-content", async (req, res, next) => {
238055
238555
  const ref = req.query.ref;
238056
238556
  if (!filePath) throw createAppError('Missing "path" query parameter', 400);
238057
238557
  const repo = await resolveProjectForRequest(id);
238058
- const resolved = path67.resolve(repo.path, filePath);
238059
- if (!resolved.startsWith(path67.resolve(repo.path) + path67.sep) && resolved !== path67.resolve(repo.path)) {
238558
+ const resolved = path68.resolve(repo.path, filePath);
238559
+ if (!resolved.startsWith(path68.resolve(repo.path) + path68.sep) && resolved !== path68.resolve(repo.path)) {
238060
238560
  throw createAppError("Path traversal not allowed", 403);
238061
238561
  }
238062
238562
  let content;
238063
238563
  if (ref === "working-tree") {
238064
- if (!fs63.existsSync(resolved)) throw createAppError("File not found", 404);
238065
- const stat = fs63.statSync(resolved);
238564
+ if (!fs64.existsSync(resolved)) throw createAppError("File not found", 404);
238565
+ const stat = fs64.statSync(resolved);
238066
238566
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
238067
- content = fs63.readFileSync(resolved, "utf-8");
238567
+ content = fs64.readFileSync(resolved, "utf-8");
238068
238568
  } else {
238069
238569
  const git = await getGit(repo.path);
238070
238570
  try {
238071
238571
  content = await git.show([`HEAD:${filePath}`]);
238072
238572
  } catch {
238073
- if (!fs63.existsSync(resolved)) throw createAppError("File not found", 404);
238074
- const stat = fs63.statSync(resolved);
238573
+ if (!fs64.existsSync(resolved)) throw createAppError("File not found", 404);
238574
+ const stat = fs64.statSync(resolved);
238075
238575
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
238076
- content = fs63.readFileSync(resolved, "utf-8");
238576
+ content = fs64.readFileSync(resolved, "utf-8");
238077
238577
  }
238078
238578
  }
238079
- const ext2 = path67.extname(resolved).slice(1).toLowerCase();
238579
+ const ext2 = path68.extname(resolved).slice(1).toLowerCase();
238080
238580
  const langMap = {
238081
238581
  ts: "typescript",
238082
238582
  tsx: "typescript",
@@ -238576,8 +239076,8 @@ var analytics_default = router9;
238576
239076
 
238577
239077
  // apps/dashboard/server/src/routes/spec.ts
238578
239078
  var import_express10 = __toESM(require_express2(), 1);
238579
- import fs64 from "node:fs";
238580
- import path68 from "node:path";
239079
+ import fs65 from "node:fs";
239080
+ import path69 from "node:path";
238581
239081
 
238582
239082
  // packages/core/dist/lib/background-tasks.js
238583
239083
  var runner = null;
@@ -238612,6 +239112,7 @@ async function corpusPayload(repoPath, ref, pr) {
238612
239112
  userRelations: decisions.relations ?? [],
238613
239113
  manualIncludes: decisions.manualIncludes ?? [],
238614
239114
  manualExcludes: decisions.manualExcludes ?? [],
239115
+ conflictResolutions: decisions.conflictResolutions ?? [],
238615
239116
  corpusCommit
238616
239117
  };
238617
239118
  }
@@ -238621,6 +239122,7 @@ function prCorpusPayload(repoPath, pr, ref, corpus) {
238621
239122
  userRelations: decisions.relations ?? [],
238622
239123
  manualIncludes: decisions.manualIncludes ?? [],
238623
239124
  manualExcludes: decisions.manualExcludes ?? [],
239125
+ conflictResolutions: decisions.conflictResolutions ?? [],
238624
239126
  corpusCommit: corpus ? ref : void 0
238625
239127
  }));
238626
239128
  }
@@ -238691,7 +239193,7 @@ router10.get(
238691
239193
  res.status(400).json({ error: "Missing ?ref=<doc path>." });
238692
239194
  return;
238693
239195
  }
238694
- if (path68.isAbsolute(ref) || ref.split(/[\\/]/).includes("..")) {
239196
+ if (path69.isAbsolute(ref) || ref.split(/[\\/]/).includes("..")) {
238695
239197
  res.status(400).json({ error: "ref escapes the repository." });
238696
239198
  return;
238697
239199
  }
@@ -238940,6 +239442,92 @@ router10.delete(
238940
239442
  }
238941
239443
  }
238942
239444
  );
239445
+ var CONFLICT_VERDICTS = ["a", "b", "dismissed"];
239446
+ async function mutateConflictResolution(repoPath, res, mutate) {
239447
+ if (!contractsMaterializeInPlace()) {
239448
+ await mutate();
239449
+ await recurateAndRegenIfResolved(repoPath);
239450
+ res.json(await corpusPayload(repoPath));
239451
+ return;
239452
+ }
239453
+ const decisions = await mutate();
239454
+ res.json({ conflictResolutions: decisions.conflictResolutions ?? [] });
239455
+ }
239456
+ async function applyConflictResolution(req, res, repoPath, mutate) {
239457
+ const parsed = parsePrScope(req);
239458
+ if ("error" in parsed) {
239459
+ res.status(400).json({ error: parsed.error });
239460
+ return;
239461
+ }
239462
+ if (parsed.scope) {
239463
+ await mutateSpecDecisionPr(repoPath, parsed.scope, res, mutate);
239464
+ return;
239465
+ }
239466
+ await mutateConflictResolution(repoPath, res, () => mutate());
239467
+ }
239468
+ router10.post(
239469
+ "/:id/spec/conflict-resolution",
239470
+ async (req, res, next) => {
239471
+ try {
239472
+ const repo = await resolveProjectForRequest(req.params.id);
239473
+ const body = req.body;
239474
+ if (!body.docA || !body.docB || body.docA === body.docB) {
239475
+ res.status(400).json({ error: "docA and docB are required and must differ." });
239476
+ return;
239477
+ }
239478
+ if (!body.verdict || !CONFLICT_VERDICTS.includes(body.verdict)) {
239479
+ res.status(400).json({ error: `verdict must be one of ${CONFLICT_VERDICTS.join(", ")}.` });
239480
+ return;
239481
+ }
239482
+ const resolution = {
239483
+ docA: body.docA,
239484
+ anchorA: body.anchorA ?? null,
239485
+ quoteA: body.quoteA,
239486
+ docB: body.docB,
239487
+ anchorB: body.anchorB ?? null,
239488
+ quoteB: body.quoteB,
239489
+ verdict: body.verdict,
239490
+ resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
239491
+ note: body.note
239492
+ };
239493
+ await applyConflictResolution(
239494
+ req,
239495
+ res,
239496
+ repo.path,
239497
+ (opts) => addConflictResolution(repo.path, resolution, opts)
239498
+ );
239499
+ } catch (e) {
239500
+ next(e);
239501
+ }
239502
+ }
239503
+ );
239504
+ router10.delete(
239505
+ "/:id/spec/conflict-resolution",
239506
+ async (req, res, next) => {
239507
+ try {
239508
+ const repo = await resolveProjectForRequest(req.params.id);
239509
+ const body = req.body;
239510
+ if (!body.docA || !body.docB) {
239511
+ res.status(400).json({ error: "docA and docB are required." });
239512
+ return;
239513
+ }
239514
+ const input = {
239515
+ docA: body.docA,
239516
+ anchorA: body.anchorA ?? null,
239517
+ docB: body.docB,
239518
+ anchorB: body.anchorB ?? null
239519
+ };
239520
+ await applyConflictResolution(
239521
+ req,
239522
+ res,
239523
+ repo.path,
239524
+ (opts) => removeConflictResolution(repo.path, input, opts)
239525
+ );
239526
+ } catch (e) {
239527
+ next(e);
239528
+ }
239529
+ }
239530
+ );
238943
239531
  router10.get(
238944
239532
  "/:id/spec/staleness",
238945
239533
  async (req, res, next) => {
@@ -238956,6 +239544,8 @@ router10.get(
238956
239544
  verifyStale: false,
238957
239545
  // EE re-curates on every decision, so decisions never outrun the corpus.
238958
239546
  decisionsPending: false,
239547
+ // EE has no live tree — docs can't drift out from under the stored corpus.
239548
+ docsChanged: false,
238959
239549
  hasCorpus: corpus !== null,
238960
239550
  hasGenerated: contractFiles.length > 0,
238961
239551
  hasVerified: verify2 !== null
@@ -238971,6 +239561,7 @@ router10.get(
238971
239561
  contractsStale,
238972
239562
  verifyStale,
238973
239563
  decisionsPending: hasPendingDecisions(repo.path),
239564
+ docsChanged: hasChangedDocs(repo.path),
238974
239565
  hasCorpus: corpusMtime !== null,
238975
239566
  hasGenerated: generatedMtime !== null,
238976
239567
  hasVerified: verifiedMtime !== null
@@ -238982,7 +239573,7 @@ router10.get(
238982
239573
  );
238983
239574
  function mtimeIfExists(file) {
238984
239575
  try {
238985
- return fs64.statSync(file).mtimeMs;
239576
+ return fs65.statSync(file).mtimeMs;
238986
239577
  } catch {
238987
239578
  return null;
238988
239579
  }
@@ -238991,7 +239582,7 @@ function hasPendingDecisions(repoPath) {
238991
239582
  const decisionsMtime = mtimeIfExists(decisionsPath(repoPath));
238992
239583
  if (decisionsMtime === null) return false;
238993
239584
  try {
238994
- const corpus = JSON.parse(fs64.readFileSync(corpusFilePath(repoPath), "utf8"));
239585
+ const corpus = JSON.parse(fs65.readFileSync(corpusFilePath(repoPath), "utf8"));
238995
239586
  const generatedAt = Date.parse(corpus.generatedAt ?? "");
238996
239587
  if (Number.isNaN(generatedAt)) return false;
238997
239588
  return decisionsMtime > generatedAt;
@@ -238999,6 +239590,21 @@ function hasPendingDecisions(repoPath) {
238999
239590
  return false;
239000
239591
  }
239001
239592
  }
239593
+ function hasChangedDocs(repoPath) {
239594
+ try {
239595
+ const corpus = JSON.parse(fs65.readFileSync(corpusFilePath(repoPath), "utf8"));
239596
+ const generatedAt = Date.parse(corpus.generatedAt ?? "");
239597
+ if (Number.isNaN(generatedAt)) return false;
239598
+ for (const doc of corpus.docs ?? []) {
239599
+ if (!doc.ref) continue;
239600
+ const docMtime = mtimeIfExists(path69.join(repoPath, doc.ref));
239601
+ if (docMtime !== null && docMtime > generatedAt) return true;
239602
+ }
239603
+ return false;
239604
+ } catch {
239605
+ return false;
239606
+ }
239607
+ }
239002
239608
  var spec_default = router10;
239003
239609
 
239004
239610
  // apps/dashboard/server/src/routes/contracts.ts
@@ -239054,16 +239660,16 @@ async function effectiveContractFiles(repoKey, workspaceOrgId, commitSha) {
239054
239660
  authored = await listContractFiles(repoKey, "contracts");
239055
239661
  }
239056
239662
  const promoted = new Set(await promotedContractPaths(repoKey));
239057
- const out = authored.map((path74) => ({
239058
- path: path74,
239663
+ const out = authored.map((path75) => ({
239664
+ path: path75,
239059
239665
  provenance: "repo",
239060
- inferred: promoted.has(path74)
239666
+ inferred: promoted.has(path75)
239061
239667
  }));
239062
239668
  if (workspaceOrgId) {
239063
239669
  const repoSet = new Set(authored);
239064
239670
  const ws = await listWorkspaceContractFiles({ workspaceOrgId }, "contracts");
239065
- for (const path74 of ws) {
239066
- if (!repoSet.has(path74)) out.push({ path: path74, provenance: "workspace" });
239671
+ for (const path75 of ws) {
239672
+ if (!repoSet.has(path75)) out.push({ path: path75, provenance: "workspace" });
239067
239673
  }
239068
239674
  }
239069
239675
  return out;
@@ -239245,7 +239851,7 @@ var contracts_default = router11;
239245
239851
 
239246
239852
  // apps/dashboard/server/src/routes/verify.ts
239247
239853
  var import_express12 = __toESM(require_express2(), 1);
239248
- import path69 from "node:path";
239854
+ import path70 from "node:path";
239249
239855
 
239250
239856
  // packages/core/dist/lib/workspace-doc-links.js
239251
239857
  var resolver = null;
@@ -239385,7 +239991,7 @@ async function resolveVerifyStashDecision(repoId, repoPath) {
239385
239991
  const status = await git.status();
239386
239992
  if (status.isClean()) return "stash";
239387
239993
  const gitRoot = (await git.revparse(["--show-toplevel"])).trim();
239388
- if (path69.resolve(repoPath) !== path69.resolve(gitRoot)) return "stash";
239994
+ if (path70.resolve(repoPath) !== path70.resolve(gitRoot)) return "stash";
239389
239995
  modifiedCount = status.modified.length + status.staged.length + status.deleted.length + status.created.length;
239390
239996
  untrackedCount = status.not_added.length;
239391
239997
  } catch {
@@ -239606,12 +240212,12 @@ var verify_default = router12;
239606
240212
 
239607
240213
  // apps/dashboard/server/src/routes/guard.ts
239608
240214
  var import_express13 = __toESM(require_express2(), 1);
239609
- import path71 from "node:path";
240215
+ import path72 from "node:path";
239610
240216
  init_dist();
239611
240217
 
239612
240218
  // packages/core/dist/commands/guard-read.js
239613
- import fs65 from "node:fs";
239614
- import path70 from "node:path";
240219
+ import fs66 from "node:fs";
240220
+ import path71 from "node:path";
239615
240221
  init_dist();
239616
240222
  function composeDocCoverage(doc, content, sources) {
239617
240223
  const { manifest, latest, result } = sources;
@@ -239779,11 +240385,11 @@ function listGuardScenarios(repoRoot) {
239779
240385
  function headingTextIndex(repoRoot, docs) {
239780
240386
  const map2 = /* @__PURE__ */ new Map();
239781
240387
  for (const doc of new Set(docs)) {
239782
- if (path70.isAbsolute(doc) || doc.split(/[\\/]/).includes(".."))
240388
+ if (path71.isAbsolute(doc) || doc.split(/[\\/]/).includes(".."))
239783
240389
  continue;
239784
240390
  let content;
239785
240391
  try {
239786
- content = fs65.readFileSync(path70.join(repoRoot, doc), "utf-8");
240392
+ content = fs66.readFileSync(path71.join(repoRoot, doc), "utf-8");
239787
240393
  } catch {
239788
240394
  continue;
239789
240395
  }
@@ -239841,13 +240447,13 @@ function scenarioFilesById(repoRoot) {
239841
240447
  for (const file of collectYamlFiles(scenariosDir(repoRoot)).sort()) {
239842
240448
  let parsed;
239843
240449
  try {
239844
- parsed = jsYaml.load(fs65.readFileSync(file, "utf-8"));
240450
+ parsed = jsYaml.load(fs66.readFileSync(file, "utf-8"));
239845
240451
  } catch {
239846
240452
  continue;
239847
240453
  }
239848
240454
  const id = parsed?.id;
239849
240455
  if (typeof id === "string" && !map2.has(id))
239850
- map2.set(id, path70.relative(repoRoot, file));
240456
+ map2.set(id, path71.relative(repoRoot, file));
239851
240457
  }
239852
240458
  return map2;
239853
240459
  }
@@ -239864,7 +240470,7 @@ function readGuardScenarioSource(repoRoot, id) {
239864
240470
  for (const file of collectYamlFiles(scenariosDir(repoRoot))) {
239865
240471
  let raw;
239866
240472
  try {
239867
- raw = fs65.readFileSync(file, "utf-8");
240473
+ raw = fs66.readFileSync(file, "utf-8");
239868
240474
  } catch {
239869
240475
  continue;
239870
240476
  }
@@ -239875,7 +240481,7 @@ function readGuardScenarioSource(repoRoot, id) {
239875
240481
  continue;
239876
240482
  }
239877
240483
  if (parsed && typeof parsed === "object" && parsed.id === id) {
239878
- return { id, file: path70.relative(repoRoot, file), content: raw };
240484
+ return { id, file: path71.relative(repoRoot, file), content: raw };
239879
240485
  }
239880
240486
  }
239881
240487
  return null;
@@ -239883,27 +240489,27 @@ function readGuardScenarioSource(repoRoot, id) {
239883
240489
  function readGuardEvidence(repoRoot, runId, scenarioId, file = "transcript.txt") {
239884
240490
  if (!SAFE_SEGMENT.test(runId) || !SAFE_SEGMENT.test(file))
239885
240491
  return null;
239886
- const full = path70.resolve(evidenceScenarioDir(repoRoot, runId, scenarioId), file);
239887
- const runDir = path70.resolve(evidenceRunDir(repoRoot, runId));
239888
- if (full !== runDir && !full.startsWith(runDir + path70.sep))
240492
+ const full = path71.resolve(evidenceScenarioDir(repoRoot, runId, scenarioId), file);
240493
+ const runDir = path71.resolve(evidenceRunDir(repoRoot, runId));
240494
+ if (full !== runDir && !full.startsWith(runDir + path71.sep))
239889
240495
  return null;
239890
- if (!fs65.existsSync(full) || !fs65.statSync(full).isFile())
240496
+ if (!fs66.existsSync(full) || !fs66.statSync(full).isFile())
239891
240497
  return null;
239892
- return fs65.readFileSync(full, "utf-8");
240498
+ return fs66.readFileSync(full, "utf-8");
239893
240499
  }
239894
240500
  function readGuardEvidenceAt(repoRoot, evidenceDir, file = "transcript.txt") {
239895
240501
  if (!SAFE_SEGMENT.test(file))
239896
240502
  return null;
239897
- const evidenceRoot = path70.resolve(guardDir(repoRoot), "evidence");
239898
- const dir = path70.resolve(repoRoot, evidenceDir);
239899
- if (dir !== evidenceRoot && !dir.startsWith(evidenceRoot + path70.sep))
240503
+ const evidenceRoot = path71.resolve(guardDir(repoRoot), "evidence");
240504
+ const dir = path71.resolve(repoRoot, evidenceDir);
240505
+ if (dir !== evidenceRoot && !dir.startsWith(evidenceRoot + path71.sep))
239900
240506
  return null;
239901
- const full = path70.resolve(dir, file);
239902
- if (!full.startsWith(dir + path70.sep))
240507
+ const full = path71.resolve(dir, file);
240508
+ if (!full.startsWith(dir + path71.sep))
239903
240509
  return null;
239904
- if (!fs65.existsSync(full) || !fs65.statSync(full).isFile())
240510
+ if (!fs66.existsSync(full) || !fs66.statSync(full).isFile())
239905
240511
  return null;
239906
- return fs65.readFileSync(full, "utf-8");
240512
+ return fs66.readFileSync(full, "utf-8");
239907
240513
  }
239908
240514
  function computeGuardStaleness(repoRoot) {
239909
240515
  const corpusMtime = mtimeIfExists2(corpusFilePath(repoRoot));
@@ -239929,11 +240535,11 @@ function newestScenarioMtime(repoRoot) {
239929
240535
  return newest;
239930
240536
  }
239931
240537
  function collectYamlFiles(dir) {
239932
- if (!fs65.existsSync(dir))
240538
+ if (!fs66.existsSync(dir))
239933
240539
  return [];
239934
240540
  const out = [];
239935
- for (const entry of fs65.readdirSync(dir, { withFileTypes: true })) {
239936
- const full = path70.join(dir, entry.name);
240541
+ for (const entry of fs66.readdirSync(dir, { withFileTypes: true })) {
240542
+ const full = path71.join(dir, entry.name);
239937
240543
  if (entry.isDirectory())
239938
240544
  out.push(...collectYamlFiles(full));
239939
240545
  else if (entry.isFile() && /\.ya?ml$/i.test(entry.name))
@@ -239943,16 +240549,16 @@ function collectYamlFiles(dir) {
239943
240549
  }
239944
240550
  function mtimeIfExists2(file) {
239945
240551
  try {
239946
- return fs65.statSync(file).mtimeMs;
240552
+ return fs66.statSync(file).mtimeMs;
239947
240553
  } catch {
239948
240554
  return null;
239949
240555
  }
239950
240556
  }
239951
240557
  function readJson(file, map2) {
239952
- if (!fs65.existsSync(file))
240558
+ if (!fs66.existsSync(file))
239953
240559
  return null;
239954
240560
  try {
239955
- return map2(JSON.parse(fs65.readFileSync(file, "utf-8")));
240561
+ return map2(JSON.parse(fs66.readFileSync(file, "utf-8")));
239956
240562
  } catch {
239957
240563
  return null;
239958
240564
  }
@@ -240025,7 +240631,7 @@ router13.get("/:id/guard/coverage", async (req, res, next) => {
240025
240631
  res.status(400).json({ error: "Missing ?doc=<doc path>." });
240026
240632
  return;
240027
240633
  }
240028
- if (path71.isAbsolute(doc) || doc.split(/[\\/]/).includes("..")) {
240634
+ if (path72.isAbsolute(doc) || doc.split(/[\\/]/).includes("..")) {
240029
240635
  res.status(400).json({ error: "doc escapes the repository." });
240030
240636
  return;
240031
240637
  }
@@ -240664,7 +241270,7 @@ var enterpriseAuthGate = async (req, res, next) => {
240664
241270
  };
240665
241271
 
240666
241272
  // apps/dashboard/server/src/app.ts
240667
- var __dirname3 = path72.dirname(fileURLToPath6(import.meta.url));
241273
+ var __dirname3 = path73.dirname(fileURLToPath6(import.meta.url));
240668
241274
  function createApp(opts = {}) {
240669
241275
  const app = (0, import_express16.default)();
240670
241276
  app.use((0, import_cors.default)({ origin: true, credentials: true }));
@@ -240701,11 +241307,11 @@ function createApp(opts = {}) {
240701
241307
  app.use("/api/rules", rules_default);
240702
241308
  app.use(errorHandler);
240703
241309
  if (opts.serveStatic !== false) {
240704
- const staticDir = path72.join(__dirname3, "public");
240705
- if (fs66.existsSync(staticDir)) {
241310
+ const staticDir = path73.join(__dirname3, "public");
241311
+ if (fs67.existsSync(staticDir)) {
240706
241312
  app.use(import_express16.default.static(staticDir));
240707
241313
  app.get("*", (_req, res) => {
240708
- res.sendFile(path72.join(staticDir, "index.html"));
241314
+ res.sendFile(path73.join(staticDir, "index.html"));
240709
241315
  });
240710
241316
  }
240711
241317
  }
@@ -240741,7 +241347,7 @@ var port = parseInt(process.env.PORT || "3001", 10);
240741
241347
  async function main() {
240742
241348
  const logDir = process.env.TRUECOURSE_LOG_DIR ?? getLogDir();
240743
241349
  configureLogger({
240744
- filePath: path73.join(logDir, "dashboard.log"),
241350
+ filePath: path74.join(logDir, "dashboard.log"),
240745
241351
  tee: process.env.TRUECOURSE_DEV === "1"
240746
241352
  });
240747
241353
  if (wipeLegacyPostgresData()) {