truecourse 0.4.5 → 0.5.1

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
@@ -1298,8 +1298,8 @@ var require_node = __commonJS({
1298
1298
  }
1299
1299
  break;
1300
1300
  case "FILE":
1301
- var fs13 = __require("fs");
1302
- stream2 = new fs13.SyncWriteStream(fd2, { autoClose: false });
1301
+ var fs14 = __require("fs");
1302
+ stream2 = new fs14.SyncWriteStream(fd2, { autoClose: false });
1303
1303
  stream2._type = "fs";
1304
1304
  break;
1305
1305
  case "PIPE":
@@ -14086,11 +14086,11 @@ var require_mime_types = __commonJS({
14086
14086
  }
14087
14087
  return exts[0];
14088
14088
  }
14089
- function lookup(path17) {
14090
- if (!path17 || typeof path17 !== "string") {
14089
+ function lookup(path18) {
14090
+ if (!path18 || typeof path18 !== "string") {
14091
14091
  return false;
14092
14092
  }
14093
- var extension2 = extname("x." + path17).toLowerCase().substr(1);
14093
+ var extension2 = extname("x." + path18).toLowerCase().substr(1);
14094
14094
  if (!extension2) {
14095
14095
  return false;
14096
14096
  }
@@ -17605,7 +17605,7 @@ var require_path_to_regexp = __commonJS({
17605
17605
  "node_modules/.pnpm/path-to-regexp@0.1.12/node_modules/path-to-regexp/index.js"(exports, module) {
17606
17606
  module.exports = pathToRegexp;
17607
17607
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
17608
- function pathToRegexp(path17, keys, options) {
17608
+ function pathToRegexp(path18, keys, options) {
17609
17609
  options = options || {};
17610
17610
  keys = keys || [];
17611
17611
  var strict = options.strict;
@@ -17619,8 +17619,8 @@ var require_path_to_regexp = __commonJS({
17619
17619
  var pos = 0;
17620
17620
  var backtrack = "";
17621
17621
  var m;
17622
- if (path17 instanceof RegExp) {
17623
- while (m = MATCHING_GROUP_REGEXP.exec(path17.source)) {
17622
+ if (path18 instanceof RegExp) {
17623
+ while (m = MATCHING_GROUP_REGEXP.exec(path18.source)) {
17624
17624
  if (m[0][0] === "\\") continue;
17625
17625
  keys.push({
17626
17626
  name: m[1] || name++,
@@ -17628,18 +17628,18 @@ var require_path_to_regexp = __commonJS({
17628
17628
  offset: m.index
17629
17629
  });
17630
17630
  }
17631
- return path17;
17631
+ return path18;
17632
17632
  }
17633
- if (Array.isArray(path17)) {
17634
- path17 = path17.map(function(value) {
17633
+ if (Array.isArray(path18)) {
17634
+ path18 = path18.map(function(value) {
17635
17635
  return pathToRegexp(value, keys, options).source;
17636
17636
  });
17637
- return new RegExp(path17.join("|"), flags);
17637
+ return new RegExp(path18.join("|"), flags);
17638
17638
  }
17639
- if (typeof path17 !== "string") {
17639
+ if (typeof path18 !== "string") {
17640
17640
  throw new TypeError("path must be a string, array of strings, or regular expression");
17641
17641
  }
17642
- path17 = path17.replace(
17642
+ path18 = path18.replace(
17643
17643
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
17644
17644
  function(match2, slash, format, key, capture, star3, optional, offset) {
17645
17645
  if (match2[0] === "\\") {
@@ -17656,7 +17656,7 @@ var require_path_to_regexp = __commonJS({
17656
17656
  if (slash || format) {
17657
17657
  backtrack = "";
17658
17658
  } else {
17659
- backtrack += path17.slice(pos, offset);
17659
+ backtrack += path18.slice(pos, offset);
17660
17660
  }
17661
17661
  pos = offset + match2.length;
17662
17662
  if (match2 === "*") {
@@ -17684,7 +17684,7 @@ var require_path_to_regexp = __commonJS({
17684
17684
  return result;
17685
17685
  }
17686
17686
  );
17687
- while (m = MATCHING_GROUP_REGEXP.exec(path17)) {
17687
+ while (m = MATCHING_GROUP_REGEXP.exec(path18)) {
17688
17688
  if (m[0][0] === "\\") continue;
17689
17689
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
17690
17690
  keys.splice(keysOffset + i, 0, {
@@ -17696,13 +17696,13 @@ var require_path_to_regexp = __commonJS({
17696
17696
  }
17697
17697
  i++;
17698
17698
  }
17699
- path17 += strict ? "" : path17[path17.length - 1] === "/" ? "?" : "/?";
17699
+ path18 += strict ? "" : path18[path18.length - 1] === "/" ? "?" : "/?";
17700
17700
  if (end) {
17701
- path17 += "$";
17702
- } else if (path17[path17.length - 1] !== "/") {
17703
- path17 += lookahead ? "(?=/|$)" : "(?:/|$)";
17701
+ path18 += "$";
17702
+ } else if (path18[path18.length - 1] !== "/") {
17703
+ path18 += lookahead ? "(?=/|$)" : "(?:/|$)";
17704
17704
  }
17705
- return new RegExp("^" + path17, flags);
17705
+ return new RegExp("^" + path18, flags);
17706
17706
  }
17707
17707
  }
17708
17708
  });
@@ -17715,19 +17715,19 @@ var require_layer = __commonJS({
17715
17715
  var debug2 = require_src()("express:router:layer");
17716
17716
  var hasOwnProperty = Object.prototype.hasOwnProperty;
17717
17717
  module.exports = Layer;
17718
- function Layer(path17, options, fn) {
17718
+ function Layer(path18, options, fn) {
17719
17719
  if (!(this instanceof Layer)) {
17720
- return new Layer(path17, options, fn);
17720
+ return new Layer(path18, options, fn);
17721
17721
  }
17722
- debug2("new %o", path17);
17722
+ debug2("new %o", path18);
17723
17723
  var opts = options || {};
17724
17724
  this.handle = fn;
17725
17725
  this.name = fn.name || "<anonymous>";
17726
17726
  this.params = void 0;
17727
17727
  this.path = void 0;
17728
- this.regexp = pathRegexp(path17, this.keys = [], opts);
17729
- this.regexp.fast_star = path17 === "*";
17730
- this.regexp.fast_slash = path17 === "/" && opts.end === false;
17728
+ this.regexp = pathRegexp(path18, this.keys = [], opts);
17729
+ this.regexp.fast_star = path18 === "*";
17730
+ this.regexp.fast_slash = path18 === "/" && opts.end === false;
17731
17731
  }
17732
17732
  Layer.prototype.handle_error = function handle_error(error, req, res, next) {
17733
17733
  var fn = this.handle;
@@ -17751,20 +17751,20 @@ var require_layer = __commonJS({
17751
17751
  next(err);
17752
17752
  }
17753
17753
  };
17754
- Layer.prototype.match = function match2(path17) {
17754
+ Layer.prototype.match = function match2(path18) {
17755
17755
  var match3;
17756
- if (path17 != null) {
17756
+ if (path18 != null) {
17757
17757
  if (this.regexp.fast_slash) {
17758
17758
  this.params = {};
17759
17759
  this.path = "";
17760
17760
  return true;
17761
17761
  }
17762
17762
  if (this.regexp.fast_star) {
17763
- this.params = { "0": decode_param(path17) };
17764
- this.path = path17;
17763
+ this.params = { "0": decode_param(path18) };
17764
+ this.path = path18;
17765
17765
  return true;
17766
17766
  }
17767
- match3 = this.regexp.exec(path17);
17767
+ match3 = this.regexp.exec(path18);
17768
17768
  }
17769
17769
  if (!match3) {
17770
17770
  this.params = void 0;
@@ -17857,10 +17857,10 @@ var require_route = __commonJS({
17857
17857
  var slice = Array.prototype.slice;
17858
17858
  var toString = Object.prototype.toString;
17859
17859
  module.exports = Route;
17860
- function Route(path17) {
17861
- this.path = path17;
17860
+ function Route(path18) {
17861
+ this.path = path18;
17862
17862
  this.stack = [];
17863
- debug2("new %o", path17);
17863
+ debug2("new %o", path18);
17864
17864
  this.methods = {};
17865
17865
  }
17866
17866
  Route.prototype._handles_method = function _handles_method(method) {
@@ -18072,8 +18072,8 @@ var require_router = __commonJS({
18072
18072
  if (++sync > 100) {
18073
18073
  return setImmediate(next, err);
18074
18074
  }
18075
- var path17 = getPathname(req);
18076
- if (path17 == null) {
18075
+ var path18 = getPathname(req);
18076
+ if (path18 == null) {
18077
18077
  return done(layerError);
18078
18078
  }
18079
18079
  var layer;
@@ -18081,7 +18081,7 @@ var require_router = __commonJS({
18081
18081
  var route;
18082
18082
  while (match2 !== true && idx < stack2.length) {
18083
18083
  layer = stack2[idx++];
18084
- match2 = matchLayer(layer, path17);
18084
+ match2 = matchLayer(layer, path18);
18085
18085
  route = layer.route;
18086
18086
  if (typeof match2 !== "boolean") {
18087
18087
  layerError = layerError || match2;
@@ -18119,18 +18119,18 @@ var require_router = __commonJS({
18119
18119
  } else if (route) {
18120
18120
  layer.handle_request(req, res, next);
18121
18121
  } else {
18122
- trim_prefix(layer, layerError, layerPath, path17);
18122
+ trim_prefix(layer, layerError, layerPath, path18);
18123
18123
  }
18124
18124
  sync = 0;
18125
18125
  });
18126
18126
  }
18127
- function trim_prefix(layer, layerError, layerPath, path17) {
18127
+ function trim_prefix(layer, layerError, layerPath, path18) {
18128
18128
  if (layerPath.length !== 0) {
18129
- if (layerPath !== path17.slice(0, layerPath.length)) {
18129
+ if (layerPath !== path18.slice(0, layerPath.length)) {
18130
18130
  next(layerError);
18131
18131
  return;
18132
18132
  }
18133
- var c = path17[layerPath.length];
18133
+ var c = path18[layerPath.length];
18134
18134
  if (c && c !== "/" && c !== ".") return next(layerError);
18135
18135
  debug2("trim prefix (%s) from url %s", layerPath, req.url);
18136
18136
  removed = layerPath;
@@ -18208,7 +18208,7 @@ var require_router = __commonJS({
18208
18208
  };
18209
18209
  proto.use = function use(fn) {
18210
18210
  var offset = 0;
18211
- var path17 = "/";
18211
+ var path18 = "/";
18212
18212
  if (typeof fn !== "function") {
18213
18213
  var arg = fn;
18214
18214
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -18216,7 +18216,7 @@ var require_router = __commonJS({
18216
18216
  }
18217
18217
  if (typeof arg !== "function") {
18218
18218
  offset = 1;
18219
- path17 = fn;
18219
+ path18 = fn;
18220
18220
  }
18221
18221
  }
18222
18222
  var callbacks = flatten(slice.call(arguments, offset));
@@ -18228,8 +18228,8 @@ var require_router = __commonJS({
18228
18228
  if (typeof fn !== "function") {
18229
18229
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
18230
18230
  }
18231
- debug2("use %o %s", path17, fn.name || "<anonymous>");
18232
- var layer = new Layer(path17, {
18231
+ debug2("use %o %s", path18, fn.name || "<anonymous>");
18232
+ var layer = new Layer(path18, {
18233
18233
  sensitive: this.caseSensitive,
18234
18234
  strict: false,
18235
18235
  end: false
@@ -18239,9 +18239,9 @@ var require_router = __commonJS({
18239
18239
  }
18240
18240
  return this;
18241
18241
  };
18242
- proto.route = function route(path17) {
18243
- var route2 = new Route(path17);
18244
- var layer = new Layer(path17, {
18242
+ proto.route = function route(path18) {
18243
+ var route2 = new Route(path18);
18244
+ var layer = new Layer(path18, {
18245
18245
  sensitive: this.caseSensitive,
18246
18246
  strict: this.strict,
18247
18247
  end: true
@@ -18251,8 +18251,8 @@ var require_router = __commonJS({
18251
18251
  return route2;
18252
18252
  };
18253
18253
  methods.concat("all").forEach(function(method) {
18254
- proto[method] = function(path17) {
18255
- var route = this.route(path17);
18254
+ proto[method] = function(path18) {
18255
+ var route = this.route(path18);
18256
18256
  route[method].apply(route, slice.call(arguments, 1));
18257
18257
  return this;
18258
18258
  };
@@ -18288,9 +18288,9 @@ var require_router = __commonJS({
18288
18288
  }
18289
18289
  return toString.call(obj).replace(objectRegExp, "$1");
18290
18290
  }
18291
- function matchLayer(layer, path17) {
18291
+ function matchLayer(layer, path18) {
18292
18292
  try {
18293
- return layer.match(path17);
18293
+ return layer.match(path18);
18294
18294
  } catch (err) {
18295
18295
  return err;
18296
18296
  }
@@ -18408,13 +18408,13 @@ var require_view = __commonJS({
18408
18408
  "node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports, module) {
18409
18409
  "use strict";
18410
18410
  var debug2 = require_src()("express:view");
18411
- var path17 = __require("path");
18412
- var fs13 = __require("fs");
18413
- var dirname7 = path17.dirname;
18414
- var basename2 = path17.basename;
18415
- var extname = path17.extname;
18416
- var join9 = path17.join;
18417
- var resolve7 = path17.resolve;
18411
+ var path18 = __require("path");
18412
+ var fs14 = __require("fs");
18413
+ var dirname7 = path18.dirname;
18414
+ var basename2 = path18.basename;
18415
+ var extname = path18.extname;
18416
+ var join9 = path18.join;
18417
+ var resolve7 = path18.resolve;
18418
18418
  module.exports = View;
18419
18419
  function View(name, options) {
18420
18420
  var opts = options || {};
@@ -18443,17 +18443,17 @@ var require_view = __commonJS({
18443
18443
  this.path = this.lookup(fileName);
18444
18444
  }
18445
18445
  View.prototype.lookup = function lookup(name) {
18446
- var path18;
18446
+ var path19;
18447
18447
  var roots = [].concat(this.root);
18448
18448
  debug2('lookup "%s"', name);
18449
- for (var i = 0; i < roots.length && !path18; i++) {
18449
+ for (var i = 0; i < roots.length && !path19; i++) {
18450
18450
  var root = roots[i];
18451
18451
  var loc = resolve7(root, name);
18452
18452
  var dir = dirname7(loc);
18453
18453
  var file = basename2(loc);
18454
- path18 = this.resolve(dir, file);
18454
+ path19 = this.resolve(dir, file);
18455
18455
  }
18456
- return path18;
18456
+ return path19;
18457
18457
  };
18458
18458
  View.prototype.render = function render(options, callback) {
18459
18459
  debug2('render "%s"', this.path);
@@ -18461,21 +18461,21 @@ var require_view = __commonJS({
18461
18461
  };
18462
18462
  View.prototype.resolve = function resolve8(dir, file) {
18463
18463
  var ext2 = this.ext;
18464
- var path18 = join9(dir, file);
18465
- var stat = tryStat(path18);
18464
+ var path19 = join9(dir, file);
18465
+ var stat = tryStat(path19);
18466
18466
  if (stat && stat.isFile()) {
18467
- return path18;
18467
+ return path19;
18468
18468
  }
18469
- path18 = join9(dir, basename2(file, ext2), "index" + ext2);
18470
- stat = tryStat(path18);
18469
+ path19 = join9(dir, basename2(file, ext2), "index" + ext2);
18470
+ stat = tryStat(path19);
18471
18471
  if (stat && stat.isFile()) {
18472
- return path18;
18472
+ return path19;
18473
18473
  }
18474
18474
  };
18475
- function tryStat(path18) {
18476
- debug2('stat "%s"', path18);
18475
+ function tryStat(path19) {
18476
+ debug2('stat "%s"', path19);
18477
18477
  try {
18478
- return fs13.statSync(path18);
18478
+ return fs14.statSync(path19);
18479
18479
  } catch (e) {
18480
18480
  return void 0;
18481
18481
  }
@@ -18829,8 +18829,8 @@ var require_types = __commonJS({
18829
18829
  // node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js
18830
18830
  var require_mime = __commonJS({
18831
18831
  "node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports, module) {
18832
- var path17 = __require("path");
18833
- var fs13 = __require("fs");
18832
+ var path18 = __require("path");
18833
+ var fs14 = __require("fs");
18834
18834
  function Mime() {
18835
18835
  this.types = /* @__PURE__ */ Object.create(null);
18836
18836
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -18851,7 +18851,7 @@ var require_mime = __commonJS({
18851
18851
  };
18852
18852
  Mime.prototype.load = function(file) {
18853
18853
  this._loading = file;
18854
- var map = {}, content = fs13.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
18854
+ var map = {}, content = fs14.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
18855
18855
  lines.forEach(function(line) {
18856
18856
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
18857
18857
  map[fields.shift()] = fields;
@@ -18859,8 +18859,8 @@ var require_mime = __commonJS({
18859
18859
  this.define(map);
18860
18860
  this._loading = null;
18861
18861
  };
18862
- Mime.prototype.lookup = function(path18, fallback) {
18863
- var ext2 = path18.replace(/^.*[\.\/\\]/, "").toLowerCase();
18862
+ Mime.prototype.lookup = function(path19, fallback) {
18863
+ var ext2 = path19.replace(/^.*[\.\/\\]/, "").toLowerCase();
18864
18864
  return this.types[ext2] || fallback || this.default_type;
18865
18865
  };
18866
18866
  Mime.prototype.extension = function(mimeType) {
@@ -19089,33 +19089,33 @@ var require_send = __commonJS({
19089
19089
  var escapeHtml = require_escape_html();
19090
19090
  var etag = require_etag();
19091
19091
  var fresh = require_fresh();
19092
- var fs13 = __require("fs");
19092
+ var fs14 = __require("fs");
19093
19093
  var mime = require_mime();
19094
19094
  var ms = require_ms2();
19095
19095
  var onFinished = require_on_finished();
19096
19096
  var parseRange = require_range_parser();
19097
- var path17 = __require("path");
19097
+ var path18 = __require("path");
19098
19098
  var statuses = require_statuses();
19099
19099
  var Stream = __require("stream");
19100
19100
  var util2 = __require("util");
19101
- var extname = path17.extname;
19102
- var join9 = path17.join;
19103
- var normalize2 = path17.normalize;
19104
- var resolve7 = path17.resolve;
19105
- var sep3 = path17.sep;
19101
+ var extname = path18.extname;
19102
+ var join9 = path18.join;
19103
+ var normalize2 = path18.normalize;
19104
+ var resolve7 = path18.resolve;
19105
+ var sep3 = path18.sep;
19106
19106
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
19107
19107
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
19108
19108
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
19109
19109
  module.exports = send;
19110
19110
  module.exports.mime = mime;
19111
- function send(req, path18, options) {
19112
- return new SendStream(req, path18, options);
19111
+ function send(req, path19, options) {
19112
+ return new SendStream(req, path19, options);
19113
19113
  }
19114
- function SendStream(req, path18, options) {
19114
+ function SendStream(req, path19, options) {
19115
19115
  Stream.call(this);
19116
19116
  var opts = options || {};
19117
19117
  this.options = opts;
19118
- this.path = path18;
19118
+ this.path = path19;
19119
19119
  this.req = req;
19120
19120
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
19121
19121
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -19161,8 +19161,8 @@ var require_send = __commonJS({
19161
19161
  this._index = index2;
19162
19162
  return this;
19163
19163
  }, "send.index: pass index as option");
19164
- SendStream.prototype.root = function root(path18) {
19165
- this._root = resolve7(String(path18));
19164
+ SendStream.prototype.root = function root(path19) {
19165
+ this._root = resolve7(String(path19));
19166
19166
  debug2("root %s", this._root);
19167
19167
  return this;
19168
19168
  };
@@ -19275,10 +19275,10 @@ var require_send = __commonJS({
19275
19275
  var lastModified = this.res.getHeader("Last-Modified");
19276
19276
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
19277
19277
  };
19278
- SendStream.prototype.redirect = function redirect(path18) {
19278
+ SendStream.prototype.redirect = function redirect(path19) {
19279
19279
  var res = this.res;
19280
19280
  if (hasListeners(this, "directory")) {
19281
- this.emit("directory", res, path18);
19281
+ this.emit("directory", res, path19);
19282
19282
  return;
19283
19283
  }
19284
19284
  if (this.hasTrailingSlash()) {
@@ -19298,42 +19298,42 @@ var require_send = __commonJS({
19298
19298
  SendStream.prototype.pipe = function pipe(res) {
19299
19299
  var root = this._root;
19300
19300
  this.res = res;
19301
- var path18 = decode(this.path);
19302
- if (path18 === -1) {
19301
+ var path19 = decode(this.path);
19302
+ if (path19 === -1) {
19303
19303
  this.error(400);
19304
19304
  return res;
19305
19305
  }
19306
- if (~path18.indexOf("\0")) {
19306
+ if (~path19.indexOf("\0")) {
19307
19307
  this.error(400);
19308
19308
  return res;
19309
19309
  }
19310
19310
  var parts;
19311
19311
  if (root !== null) {
19312
- if (path18) {
19313
- path18 = normalize2("." + sep3 + path18);
19312
+ if (path19) {
19313
+ path19 = normalize2("." + sep3 + path19);
19314
19314
  }
19315
- if (UP_PATH_REGEXP.test(path18)) {
19316
- debug2('malicious path "%s"', path18);
19315
+ if (UP_PATH_REGEXP.test(path19)) {
19316
+ debug2('malicious path "%s"', path19);
19317
19317
  this.error(403);
19318
19318
  return res;
19319
19319
  }
19320
- parts = path18.split(sep3);
19321
- path18 = normalize2(join9(root, path18));
19320
+ parts = path19.split(sep3);
19321
+ path19 = normalize2(join9(root, path19));
19322
19322
  } else {
19323
- if (UP_PATH_REGEXP.test(path18)) {
19324
- debug2('malicious path "%s"', path18);
19323
+ if (UP_PATH_REGEXP.test(path19)) {
19324
+ debug2('malicious path "%s"', path19);
19325
19325
  this.error(403);
19326
19326
  return res;
19327
19327
  }
19328
- parts = normalize2(path18).split(sep3);
19329
- path18 = resolve7(path18);
19328
+ parts = normalize2(path19).split(sep3);
19329
+ path19 = resolve7(path19);
19330
19330
  }
19331
19331
  if (containsDotFile(parts)) {
19332
19332
  var access = this._dotfiles;
19333
19333
  if (access === void 0) {
19334
19334
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
19335
19335
  }
19336
- debug2('%s dotfile "%s"', access, path18);
19336
+ debug2('%s dotfile "%s"', access, path19);
19337
19337
  switch (access) {
19338
19338
  case "allow":
19339
19339
  break;
@@ -19347,13 +19347,13 @@ var require_send = __commonJS({
19347
19347
  }
19348
19348
  }
19349
19349
  if (this._index.length && this.hasTrailingSlash()) {
19350
- this.sendIndex(path18);
19350
+ this.sendIndex(path19);
19351
19351
  return res;
19352
19352
  }
19353
- this.sendFile(path18);
19353
+ this.sendFile(path19);
19354
19354
  return res;
19355
19355
  };
19356
- SendStream.prototype.send = function send2(path18, stat) {
19356
+ SendStream.prototype.send = function send2(path19, stat) {
19357
19357
  var len = stat.size;
19358
19358
  var options = this.options;
19359
19359
  var opts = {};
@@ -19365,9 +19365,9 @@ var require_send = __commonJS({
19365
19365
  this.headersAlreadySent();
19366
19366
  return;
19367
19367
  }
19368
- debug2('pipe "%s"', path18);
19369
- this.setHeader(path18, stat);
19370
- this.type(path18);
19368
+ debug2('pipe "%s"', path19);
19369
+ this.setHeader(path19, stat);
19370
+ this.type(path19);
19371
19371
  if (this.isConditionalGET()) {
19372
19372
  if (this.isPreconditionFailure()) {
19373
19373
  this.error(412);
@@ -19416,28 +19416,28 @@ var require_send = __commonJS({
19416
19416
  res.end();
19417
19417
  return;
19418
19418
  }
19419
- this.stream(path18, opts);
19419
+ this.stream(path19, opts);
19420
19420
  };
19421
- SendStream.prototype.sendFile = function sendFile(path18) {
19421
+ SendStream.prototype.sendFile = function sendFile(path19) {
19422
19422
  var i = 0;
19423
19423
  var self2 = this;
19424
- debug2('stat "%s"', path18);
19425
- fs13.stat(path18, function onstat(err, stat) {
19426
- if (err && err.code === "ENOENT" && !extname(path18) && path18[path18.length - 1] !== sep3) {
19424
+ debug2('stat "%s"', path19);
19425
+ fs14.stat(path19, function onstat(err, stat) {
19426
+ if (err && err.code === "ENOENT" && !extname(path19) && path19[path19.length - 1] !== sep3) {
19427
19427
  return next(err);
19428
19428
  }
19429
19429
  if (err) return self2.onStatError(err);
19430
- if (stat.isDirectory()) return self2.redirect(path18);
19431
- self2.emit("file", path18, stat);
19432
- self2.send(path18, stat);
19430
+ if (stat.isDirectory()) return self2.redirect(path19);
19431
+ self2.emit("file", path19, stat);
19432
+ self2.send(path19, stat);
19433
19433
  });
19434
19434
  function next(err) {
19435
19435
  if (self2._extensions.length <= i) {
19436
19436
  return err ? self2.onStatError(err) : self2.error(404);
19437
19437
  }
19438
- var p = path18 + "." + self2._extensions[i++];
19438
+ var p = path19 + "." + self2._extensions[i++];
19439
19439
  debug2('stat "%s"', p);
19440
- fs13.stat(p, function(err2, stat) {
19440
+ fs14.stat(p, function(err2, stat) {
19441
19441
  if (err2) return next(err2);
19442
19442
  if (stat.isDirectory()) return next();
19443
19443
  self2.emit("file", p, stat);
@@ -19445,7 +19445,7 @@ var require_send = __commonJS({
19445
19445
  });
19446
19446
  }
19447
19447
  };
19448
- SendStream.prototype.sendIndex = function sendIndex(path18) {
19448
+ SendStream.prototype.sendIndex = function sendIndex(path19) {
19449
19449
  var i = -1;
19450
19450
  var self2 = this;
19451
19451
  function next(err) {
@@ -19453,9 +19453,9 @@ var require_send = __commonJS({
19453
19453
  if (err) return self2.onStatError(err);
19454
19454
  return self2.error(404);
19455
19455
  }
19456
- var p = join9(path18, self2._index[i]);
19456
+ var p = join9(path19, self2._index[i]);
19457
19457
  debug2('stat "%s"', p);
19458
- fs13.stat(p, function(err2, stat) {
19458
+ fs14.stat(p, function(err2, stat) {
19459
19459
  if (err2) return next(err2);
19460
19460
  if (stat.isDirectory()) return next();
19461
19461
  self2.emit("file", p, stat);
@@ -19464,10 +19464,10 @@ var require_send = __commonJS({
19464
19464
  }
19465
19465
  next();
19466
19466
  };
19467
- SendStream.prototype.stream = function stream(path18, options) {
19467
+ SendStream.prototype.stream = function stream(path19, options) {
19468
19468
  var self2 = this;
19469
19469
  var res = this.res;
19470
- var stream2 = fs13.createReadStream(path18, options);
19470
+ var stream2 = fs14.createReadStream(path19, options);
19471
19471
  this.emit("stream", stream2);
19472
19472
  stream2.pipe(res);
19473
19473
  function cleanup() {
@@ -19482,10 +19482,10 @@ var require_send = __commonJS({
19482
19482
  self2.emit("end");
19483
19483
  });
19484
19484
  };
19485
- SendStream.prototype.type = function type(path18) {
19485
+ SendStream.prototype.type = function type(path19) {
19486
19486
  var res = this.res;
19487
19487
  if (res.getHeader("Content-Type")) return;
19488
- var type2 = mime.lookup(path18);
19488
+ var type2 = mime.lookup(path19);
19489
19489
  if (!type2) {
19490
19490
  debug2("no content-type");
19491
19491
  return;
@@ -19494,9 +19494,9 @@ var require_send = __commonJS({
19494
19494
  debug2("content-type %s", type2);
19495
19495
  res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
19496
19496
  };
19497
- SendStream.prototype.setHeader = function setHeader(path18, stat) {
19497
+ SendStream.prototype.setHeader = function setHeader(path19, stat) {
19498
19498
  var res = this.res;
19499
- this.emit("headers", res, path18, stat);
19499
+ this.emit("headers", res, path19, stat);
19500
19500
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
19501
19501
  debug2("accept ranges");
19502
19502
  res.setHeader("Accept-Ranges", "bytes");
@@ -19555,9 +19555,9 @@ var require_send = __commonJS({
19555
19555
  }
19556
19556
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
19557
19557
  }
19558
- function decode(path18) {
19558
+ function decode(path19) {
19559
19559
  try {
19560
- return decodeURIComponent(path18);
19560
+ return decodeURIComponent(path19);
19561
19561
  } catch (err) {
19562
19562
  return -1;
19563
19563
  }
@@ -20466,10 +20466,10 @@ var require_utils2 = __commonJS({
20466
20466
  var querystring = __require("querystring");
20467
20467
  exports.etag = createETagGenerator({ weak: false });
20468
20468
  exports.wetag = createETagGenerator({ weak: true });
20469
- exports.isAbsolute = function(path17) {
20470
- if ("/" === path17[0]) return true;
20471
- if (":" === path17[1] && ("\\" === path17[2] || "/" === path17[2])) return true;
20472
- if ("\\\\" === path17.substring(0, 2)) return true;
20469
+ exports.isAbsolute = function(path18) {
20470
+ if ("/" === path18[0]) return true;
20471
+ if (":" === path18[1] && ("\\" === path18[2] || "/" === path18[2])) return true;
20472
+ if ("\\\\" === path18.substring(0, 2)) return true;
20473
20473
  };
20474
20474
  exports.flatten = deprecate.function(
20475
20475
  flatten,
@@ -20680,7 +20680,7 @@ var require_application = __commonJS({
20680
20680
  };
20681
20681
  app.use = function use(fn) {
20682
20682
  var offset = 0;
20683
- var path17 = "/";
20683
+ var path18 = "/";
20684
20684
  if (typeof fn !== "function") {
20685
20685
  var arg = fn;
20686
20686
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -20688,7 +20688,7 @@ var require_application = __commonJS({
20688
20688
  }
20689
20689
  if (typeof arg !== "function") {
20690
20690
  offset = 1;
20691
- path17 = fn;
20691
+ path18 = fn;
20692
20692
  }
20693
20693
  }
20694
20694
  var fns = flatten(slice.call(arguments, offset));
@@ -20699,12 +20699,12 @@ var require_application = __commonJS({
20699
20699
  var router10 = this._router;
20700
20700
  fns.forEach(function(fn2) {
20701
20701
  if (!fn2 || !fn2.handle || !fn2.set) {
20702
- return router10.use(path17, fn2);
20702
+ return router10.use(path18, fn2);
20703
20703
  }
20704
- debug2(".use app under %s", path17);
20705
- fn2.mountpath = path17;
20704
+ debug2(".use app under %s", path18);
20705
+ fn2.mountpath = path18;
20706
20706
  fn2.parent = this;
20707
- router10.use(path17, function mounted_app(req, res, next) {
20707
+ router10.use(path18, function mounted_app(req, res, next) {
20708
20708
  var orig = req.app;
20709
20709
  fn2.handle(req, res, function(err) {
20710
20710
  setPrototypeOf(req, orig.request);
@@ -20716,9 +20716,9 @@ var require_application = __commonJS({
20716
20716
  }, this);
20717
20717
  return this;
20718
20718
  };
20719
- app.route = function route(path17) {
20719
+ app.route = function route(path18) {
20720
20720
  this.lazyrouter();
20721
- return this._router.route(path17);
20721
+ return this._router.route(path18);
20722
20722
  };
20723
20723
  app.engine = function engine(ext2, fn) {
20724
20724
  if (typeof fn !== "function") {
@@ -20769,7 +20769,7 @@ var require_application = __commonJS({
20769
20769
  }
20770
20770
  return this;
20771
20771
  };
20772
- app.path = function path17() {
20772
+ app.path = function path18() {
20773
20773
  return this.parent ? this.parent.path() + this.mountpath : "";
20774
20774
  };
20775
20775
  app.enabled = function enabled(setting) {
@@ -20785,19 +20785,19 @@ var require_application = __commonJS({
20785
20785
  return this.set(setting, false);
20786
20786
  };
20787
20787
  methods.forEach(function(method) {
20788
- app[method] = function(path17) {
20788
+ app[method] = function(path18) {
20789
20789
  if (method === "get" && arguments.length === 1) {
20790
- return this.set(path17);
20790
+ return this.set(path18);
20791
20791
  }
20792
20792
  this.lazyrouter();
20793
- var route = this._router.route(path17);
20793
+ var route = this._router.route(path18);
20794
20794
  route[method].apply(route, slice.call(arguments, 1));
20795
20795
  return this;
20796
20796
  };
20797
20797
  });
20798
- app.all = function all(path17) {
20798
+ app.all = function all(path18) {
20799
20799
  this.lazyrouter();
20800
- var route = this._router.route(path17);
20800
+ var route = this._router.route(path18);
20801
20801
  var args = slice.call(arguments, 1);
20802
20802
  for (var i = 0; i < methods.length; i++) {
20803
20803
  route[methods[i]].apply(route, args);
@@ -21556,7 +21556,7 @@ var require_request = __commonJS({
21556
21556
  var subdomains2 = !isIP(hostname) ? hostname.split(".").reverse() : [hostname];
21557
21557
  return subdomains2.slice(offset);
21558
21558
  });
21559
- defineGetter(req, "path", function path17() {
21559
+ defineGetter(req, "path", function path18() {
21560
21560
  return parse2(this).pathname;
21561
21561
  });
21562
21562
  defineGetter(req, "hostname", function hostname() {
@@ -21878,7 +21878,7 @@ var require_response = __commonJS({
21878
21878
  var http = __require("http");
21879
21879
  var isAbsolute = require_utils2().isAbsolute;
21880
21880
  var onFinished = require_on_finished();
21881
- var path17 = __require("path");
21881
+ var path18 = __require("path");
21882
21882
  var statuses = require_statuses();
21883
21883
  var merge = require_utils_merge();
21884
21884
  var sign = require_cookie_signature().sign;
@@ -21887,9 +21887,9 @@ var require_response = __commonJS({
21887
21887
  var setCharset = require_utils2().setCharset;
21888
21888
  var cookie = require_cookie();
21889
21889
  var send = require_send();
21890
- var extname = path17.extname;
21890
+ var extname = path18.extname;
21891
21891
  var mime = send.mime;
21892
- var resolve7 = path17.resolve;
21892
+ var resolve7 = path18.resolve;
21893
21893
  var vary = require_vary();
21894
21894
  var res = Object.create(http.ServerResponse.prototype);
21895
21895
  module.exports = res;
@@ -22066,26 +22066,26 @@ var require_response = __commonJS({
22066
22066
  this.type("txt");
22067
22067
  return this.send(body);
22068
22068
  };
22069
- res.sendFile = function sendFile(path18, options, callback) {
22069
+ res.sendFile = function sendFile(path19, options, callback) {
22070
22070
  var done = callback;
22071
22071
  var req = this.req;
22072
22072
  var res2 = this;
22073
22073
  var next = req.next;
22074
22074
  var opts = options || {};
22075
- if (!path18) {
22075
+ if (!path19) {
22076
22076
  throw new TypeError("path argument is required to res.sendFile");
22077
22077
  }
22078
- if (typeof path18 !== "string") {
22078
+ if (typeof path19 !== "string") {
22079
22079
  throw new TypeError("path must be a string to res.sendFile");
22080
22080
  }
22081
22081
  if (typeof options === "function") {
22082
22082
  done = options;
22083
22083
  opts = {};
22084
22084
  }
22085
- if (!opts.root && !isAbsolute(path18)) {
22085
+ if (!opts.root && !isAbsolute(path19)) {
22086
22086
  throw new TypeError("path must be absolute or specify root to res.sendFile");
22087
22087
  }
22088
- var pathname = encodeURI(path18);
22088
+ var pathname = encodeURI(path19);
22089
22089
  var file = send(req, pathname, opts);
22090
22090
  sendfile(res2, file, opts, function(err) {
22091
22091
  if (done) return done(err);
@@ -22095,7 +22095,7 @@ var require_response = __commonJS({
22095
22095
  }
22096
22096
  });
22097
22097
  };
22098
- res.sendfile = function(path18, options, callback) {
22098
+ res.sendfile = function(path19, options, callback) {
22099
22099
  var done = callback;
22100
22100
  var req = this.req;
22101
22101
  var res2 = this;
@@ -22105,7 +22105,7 @@ var require_response = __commonJS({
22105
22105
  done = options;
22106
22106
  opts = {};
22107
22107
  }
22108
- var file = send(req, path18, opts);
22108
+ var file = send(req, path19, opts);
22109
22109
  sendfile(res2, file, opts, function(err) {
22110
22110
  if (done) return done(err);
22111
22111
  if (err && err.code === "EISDIR") return next();
@@ -22118,7 +22118,7 @@ var require_response = __commonJS({
22118
22118
  res.sendfile,
22119
22119
  "res.sendfile: Use res.sendFile instead"
22120
22120
  );
22121
- res.download = function download(path18, filename, options, callback) {
22121
+ res.download = function download(path19, filename, options, callback) {
22122
22122
  var done = callback;
22123
22123
  var name = filename;
22124
22124
  var opts = options || null;
@@ -22135,7 +22135,7 @@ var require_response = __commonJS({
22135
22135
  opts = filename;
22136
22136
  }
22137
22137
  var headers = {
22138
- "Content-Disposition": contentDisposition(name || path18)
22138
+ "Content-Disposition": contentDisposition(name || path19)
22139
22139
  };
22140
22140
  if (opts && opts.headers) {
22141
22141
  var keys = Object.keys(opts.headers);
@@ -22148,7 +22148,7 @@ var require_response = __commonJS({
22148
22148
  }
22149
22149
  opts = Object.create(opts);
22150
22150
  opts.headers = headers;
22151
- var fullPath = !opts.root ? resolve7(path18) : path18;
22151
+ var fullPath = !opts.root ? resolve7(path19) : path19;
22152
22152
  return this.sendFile(fullPath, opts, done);
22153
22153
  };
22154
22154
  res.contentType = res.type = function contentType(type) {
@@ -22449,11 +22449,11 @@ var require_serve_static = __commonJS({
22449
22449
  }
22450
22450
  var forwardError = !fallthrough;
22451
22451
  var originalUrl = parseUrl.original(req);
22452
- var path17 = parseUrl(req).pathname;
22453
- if (path17 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22454
- path17 = "";
22452
+ var path18 = parseUrl(req).pathname;
22453
+ if (path18 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22454
+ path18 = "";
22455
22455
  }
22456
- var stream = send(req, path17, opts);
22456
+ var stream = send(req, path18, opts);
22457
22457
  stream.on("directory", onDirectory);
22458
22458
  if (setHeaders) {
22459
22459
  stream.on("headers", setHeaders);
@@ -22938,8 +22938,8 @@ var require_package = __commonJS({
22938
22938
  // node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
22939
22939
  var require_main = __commonJS({
22940
22940
  "node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
22941
- var fs13 = __require("fs");
22942
- var path17 = __require("path");
22941
+ var fs14 = __require("fs");
22942
+ var path18 = __require("path");
22943
22943
  var os4 = __require("os");
22944
22944
  var crypto2 = __require("crypto");
22945
22945
  var packageJson = require_package();
@@ -23047,7 +23047,7 @@ var require_main = __commonJS({
23047
23047
  if (options && options.path && options.path.length > 0) {
23048
23048
  if (Array.isArray(options.path)) {
23049
23049
  for (const filepath of options.path) {
23050
- if (fs13.existsSync(filepath)) {
23050
+ if (fs14.existsSync(filepath)) {
23051
23051
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
23052
23052
  }
23053
23053
  }
@@ -23055,15 +23055,15 @@ var require_main = __commonJS({
23055
23055
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
23056
23056
  }
23057
23057
  } else {
23058
- possibleVaultPath = path17.resolve(process.cwd(), ".env.vault");
23058
+ possibleVaultPath = path18.resolve(process.cwd(), ".env.vault");
23059
23059
  }
23060
- if (fs13.existsSync(possibleVaultPath)) {
23060
+ if (fs14.existsSync(possibleVaultPath)) {
23061
23061
  return possibleVaultPath;
23062
23062
  }
23063
23063
  return null;
23064
23064
  }
23065
23065
  function _resolveHome(envPath) {
23066
- return envPath[0] === "~" ? path17.join(os4.homedir(), envPath.slice(1)) : envPath;
23066
+ return envPath[0] === "~" ? path18.join(os4.homedir(), envPath.slice(1)) : envPath;
23067
23067
  }
23068
23068
  function _configVault(options) {
23069
23069
  const debug2 = Boolean(options && options.debug);
@@ -23080,7 +23080,7 @@ var require_main = __commonJS({
23080
23080
  return { parsed };
23081
23081
  }
23082
23082
  function configDotenv(options) {
23083
- const dotenvPath = path17.resolve(process.cwd(), ".env");
23083
+ const dotenvPath = path18.resolve(process.cwd(), ".env");
23084
23084
  let encoding = "utf8";
23085
23085
  const debug2 = Boolean(options && options.debug);
23086
23086
  const quiet = options && "quiet" in options ? options.quiet : true;
@@ -23104,13 +23104,13 @@ var require_main = __commonJS({
23104
23104
  }
23105
23105
  let lastError;
23106
23106
  const parsedAll = {};
23107
- for (const path18 of optionPaths) {
23107
+ for (const path19 of optionPaths) {
23108
23108
  try {
23109
- const parsed = DotenvModule.parse(fs13.readFileSync(path18, { encoding }));
23109
+ const parsed = DotenvModule.parse(fs14.readFileSync(path19, { encoding }));
23110
23110
  DotenvModule.populate(parsedAll, parsed, options);
23111
23111
  } catch (e) {
23112
23112
  if (debug2) {
23113
- _debug(`Failed to load ${path18} ${e.message}`);
23113
+ _debug(`Failed to load ${path19} ${e.message}`);
23114
23114
  }
23115
23115
  lastError = e;
23116
23116
  }
@@ -23125,7 +23125,7 @@ var require_main = __commonJS({
23125
23125
  const shortPaths = [];
23126
23126
  for (const filePath of optionPaths) {
23127
23127
  try {
23128
- const relative2 = path17.relative(process.cwd(), filePath);
23128
+ const relative2 = path18.relative(process.cwd(), filePath);
23129
23129
  shortPaths.push(relative2);
23130
23130
  } catch (e) {
23131
23131
  if (debug2) {
@@ -29374,11 +29374,11 @@ var require_server = __commonJS({
29374
29374
  * @protected
29375
29375
  */
29376
29376
  _computePath(options) {
29377
- let path17 = (options.path || "/engine.io").replace(/\/$/, "");
29377
+ let path18 = (options.path || "/engine.io").replace(/\/$/, "");
29378
29378
  if (options.addTrailingSlash !== false) {
29379
- path17 += "/";
29379
+ path18 += "/";
29380
29380
  }
29381
- return path17;
29381
+ return path18;
29382
29382
  }
29383
29383
  /**
29384
29384
  * Returns a list of available transports for upgrade given a certain transport.
@@ -29877,10 +29877,10 @@ var require_server = __commonJS({
29877
29877
  * @param {Object} options
29878
29878
  */
29879
29879
  attach(server, options = {}) {
29880
- const path17 = this._computePath(options);
29880
+ const path18 = this._computePath(options);
29881
29881
  const destroyUpgradeTimeout = options.destroyUpgradeTimeout || 1e3;
29882
29882
  function check(req) {
29883
- return path17 === req.url.slice(0, path17.length);
29883
+ return path18 === req.url.slice(0, path18.length);
29884
29884
  }
29885
29885
  const listeners = server.listeners("request").slice(0);
29886
29886
  server.removeAllListeners("request");
@@ -29888,7 +29888,7 @@ var require_server = __commonJS({
29888
29888
  server.on("listening", this.init.bind(this));
29889
29889
  server.on("request", (req, res) => {
29890
29890
  if (check(req)) {
29891
- debug2('intercepting request for path "%s"', path17);
29891
+ debug2('intercepting request for path "%s"', path18);
29892
29892
  this.handleRequest(req, res);
29893
29893
  } else {
29894
29894
  let i = 0;
@@ -30727,8 +30727,8 @@ var require_userver = __commonJS({
30727
30727
  * @param options
30728
30728
  */
30729
30729
  attach(app, options = {}) {
30730
- const path17 = this._computePath(options);
30731
- app.any(path17, this.handleRequest.bind(this)).ws(path17, {
30730
+ const path18 = this._computePath(options);
30731
+ app.any(path18, this.handleRequest.bind(this)).ws(path18, {
30732
30732
  compression: options.compression,
30733
30733
  idleTimeout: options.idleTimeout,
30734
30734
  maxBackpressure: options.maxBackpressure,
@@ -35153,7 +35153,7 @@ var require_dist2 = __commonJS({
35153
35153
  var zlib_1 = __require("zlib");
35154
35154
  var accepts = require_accepts();
35155
35155
  var stream_1 = __require("stream");
35156
- var path17 = __require("path");
35156
+ var path18 = __require("path");
35157
35157
  var engine_io_1 = require_engine_io();
35158
35158
  var client_1 = require_client();
35159
35159
  var events_1 = __require("events");
@@ -35348,7 +35348,7 @@ var require_dist2 = __commonJS({
35348
35348
  res.writeHeader("cache-control", "public, max-age=0");
35349
35349
  res.writeHeader("content-type", "application/" + (isMap ? "json" : "javascript") + "; charset=utf-8");
35350
35350
  res.writeHeader("etag", expectedEtag);
35351
- const filepath = path17.join(__dirname, "../client-dist/", filename);
35351
+ const filepath = path18.join(__dirname, "../client-dist/", filename);
35352
35352
  (0, uws_1.serveFile)(res, filepath);
35353
35353
  });
35354
35354
  }
@@ -35430,7 +35430,7 @@ var require_dist2 = __commonJS({
35430
35430
  * @private
35431
35431
  */
35432
35432
  static sendFile(filename, req, res) {
35433
- const readStream = (0, fs_1.createReadStream)(path17.join(__dirname, "../client-dist/", filename));
35433
+ const readStream = (0, fs_1.createReadStream)(path18.join(__dirname, "../client-dist/", filename));
35434
35434
  const encoding = accepts(req).encodings(["br", "gzip", "deflate"]);
35435
35435
  const onError2 = (err) => {
35436
35436
  if (err) {
@@ -36276,8 +36276,8 @@ var init_parseUtil = __esm({
36276
36276
  init_errors();
36277
36277
  init_en();
36278
36278
  makeIssue = (params) => {
36279
- const { data, path: path17, errorMaps, issueData } = params;
36280
- const fullPath = [...path17, ...issueData.path || []];
36279
+ const { data, path: path18, errorMaps, issueData } = params;
36280
+ const fullPath = [...path18, ...issueData.path || []];
36281
36281
  const fullIssue = {
36282
36282
  ...issueData,
36283
36283
  path: fullPath
@@ -36585,11 +36585,11 @@ var init_types = __esm({
36585
36585
  init_parseUtil();
36586
36586
  init_util();
36587
36587
  ParseInputLazyPath = class {
36588
- constructor(parent, value, path17, key) {
36588
+ constructor(parent, value, path18, key) {
36589
36589
  this._cachedPath = [];
36590
36590
  this.parent = parent;
36591
36591
  this.data = value;
36592
- this._path = path17;
36592
+ this._path = path18;
36593
36593
  this._key = key;
36594
36594
  }
36595
36595
  get path() {
@@ -40070,10 +40070,10 @@ var require_src3 = __commonJS({
40070
40070
  var fs_1 = __require("fs");
40071
40071
  var debug_1 = __importDefault(require_src2());
40072
40072
  var log2 = debug_1.default("@kwsites/file-exists");
40073
- function check(path17, isFile, isDirectory) {
40074
- log2(`checking %s`, path17);
40073
+ function check(path18, isFile, isDirectory) {
40074
+ log2(`checking %s`, path18);
40075
40075
  try {
40076
- const stat = fs_1.statSync(path17);
40076
+ const stat = fs_1.statSync(path18);
40077
40077
  if (stat.isFile() && isFile) {
40078
40078
  log2(`[OK] path represents a file`);
40079
40079
  return true;
@@ -40093,8 +40093,8 @@ var require_src3 = __commonJS({
40093
40093
  throw e;
40094
40094
  }
40095
40095
  }
40096
- function exists2(path17, type = exports.READABLE) {
40097
- return check(path17, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
40096
+ function exists2(path18, type = exports.READABLE) {
40097
+ return check(path18, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
40098
40098
  }
40099
40099
  exports.exists = exists2;
40100
40100
  exports.FILE = 1;
@@ -40157,219 +40157,6 @@ var require_dist4 = __commonJS({
40157
40157
  }
40158
40158
  });
40159
40159
 
40160
- // apps/server/src/lib/atomic-write.ts
40161
- import fs6 from "node:fs";
40162
- import path5 from "node:path";
40163
- function atomicWriteJson(targetPath, data) {
40164
- fs6.mkdirSync(path5.dirname(targetPath), { recursive: true });
40165
- const tmp = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
40166
- fs6.writeFileSync(tmp, JSON.stringify(data, null, 2));
40167
- fs6.renameSync(tmp, targetPath);
40168
- }
40169
- function lockPath(repoPath) {
40170
- return path5.join(repoPath, ".truecourse", LOCK_FILENAME);
40171
- }
40172
- function acquireAnalyzeLock(repoPath) {
40173
- const file = lockPath(repoPath);
40174
- fs6.mkdirSync(path5.dirname(file), { recursive: true });
40175
- try {
40176
- const fd = fs6.openSync(file, "wx");
40177
- fs6.writeSync(fd, `${process.pid}
40178
- ${(/* @__PURE__ */ new Date()).toISOString()}
40179
- `);
40180
- fs6.closeSync(fd);
40181
- } catch (err) {
40182
- if (err.code === "EEXIST") {
40183
- let owner = null;
40184
- try {
40185
- owner = parseInt(fs6.readFileSync(file, "utf-8").split("\n")[0], 10) || null;
40186
- } catch {
40187
- }
40188
- throw new AnalyzeLockError(repoPath, owner);
40189
- }
40190
- throw err;
40191
- }
40192
- }
40193
- function releaseAnalyzeLock(repoPath) {
40194
- try {
40195
- fs6.unlinkSync(lockPath(repoPath));
40196
- } catch (err) {
40197
- if (err.code !== "ENOENT") throw err;
40198
- }
40199
- }
40200
- var LOCK_FILENAME, AnalyzeLockError;
40201
- var init_atomic_write = __esm({
40202
- "apps/server/src/lib/atomic-write.ts"() {
40203
- "use strict";
40204
- LOCK_FILENAME = ".analyze.lock";
40205
- AnalyzeLockError = class extends Error {
40206
- constructor(repoPath, ownerPid) {
40207
- const who = ownerPid != null ? ` (held by pid ${ownerPid})` : "";
40208
- super(
40209
- `Another analyze is already running for ${repoPath}${who}. If you're sure no analyze is in progress, remove ${lockPath(repoPath)} and retry.`
40210
- );
40211
- this.name = "AnalyzeLockError";
40212
- }
40213
- };
40214
- }
40215
- });
40216
-
40217
- // apps/server/src/lib/analysis-store.ts
40218
- var analysis_store_exports = {};
40219
- __export(analysis_store_exports, {
40220
- analysisFilePath: () => analysisFilePath,
40221
- appendHistory: () => appendHistory,
40222
- buildAnalysisFilename: () => buildAnalysisFilename,
40223
- clearLatestCache: () => clearLatestCache,
40224
- deleteAnalysis: () => deleteAnalysis,
40225
- deleteDiff: () => deleteDiff,
40226
- deleteLatest: () => deleteLatest,
40227
- diffPath: () => diffPath,
40228
- findAnalysisFilename: () => findAnalysisFilename,
40229
- historyPath: () => historyPath,
40230
- latestPath: () => latestPath,
40231
- listAnalyses: () => listAnalyses,
40232
- readAnalysis: () => readAnalysis,
40233
- readDiff: () => readDiff,
40234
- readHistory: () => readHistory,
40235
- readLatest: () => readLatest,
40236
- removeFromHistory: () => removeFromHistory,
40237
- writeAnalysis: () => writeAnalysis,
40238
- writeDiff: () => writeDiff,
40239
- writeLatest: () => writeLatest
40240
- });
40241
- import fs7 from "node:fs";
40242
- import path6 from "node:path";
40243
- function storeDir(repoPath) {
40244
- return path6.join(repoPath, TRUECOURSE_DIR2);
40245
- }
40246
- function analysesDir(repoPath) {
40247
- return path6.join(storeDir(repoPath), ANALYSES_DIR);
40248
- }
40249
- function analysisFilePath(repoPath, filename) {
40250
- return path6.join(analysesDir(repoPath), filename);
40251
- }
40252
- function latestPath(repoPath) {
40253
- return path6.join(storeDir(repoPath), LATEST_FILE);
40254
- }
40255
- function historyPath(repoPath) {
40256
- return path6.join(storeDir(repoPath), HISTORY_FILE);
40257
- }
40258
- function diffPath(repoPath) {
40259
- return path6.join(storeDir(repoPath), DIFF_FILE);
40260
- }
40261
- function buildAnalysisFilename(analysisId, createdAt) {
40262
- const iso = createdAt.replace(/[:.]/g, "-").replace(/-\d{3}Z$/, "Z");
40263
- const shortId = analysisId.replace(/-/g, "").slice(0, 8);
40264
- return `${iso}_${shortId}.json`;
40265
- }
40266
- function readLatest(repoPath) {
40267
- const file = latestPath(repoPath);
40268
- let mtime;
40269
- try {
40270
- mtime = fs7.statSync(file).mtimeMs;
40271
- } catch (err) {
40272
- if (err.code === "ENOENT") {
40273
- latestCache.delete(repoPath);
40274
- return null;
40275
- }
40276
- throw err;
40277
- }
40278
- const cached = latestCache.get(repoPath);
40279
- if (cached && cached.mtime === mtime) return cached.data;
40280
- const data = JSON.parse(fs7.readFileSync(file, "utf-8"));
40281
- latestCache.set(repoPath, { mtime, data });
40282
- return data;
40283
- }
40284
- function writeLatest(repoPath, latest) {
40285
- atomicWriteJson(latestPath(repoPath), latest);
40286
- latestCache.delete(repoPath);
40287
- }
40288
- function deleteLatest(repoPath) {
40289
- try {
40290
- fs7.unlinkSync(latestPath(repoPath));
40291
- } catch (err) {
40292
- if (err.code !== "ENOENT") throw err;
40293
- }
40294
- latestCache.delete(repoPath);
40295
- }
40296
- function writeAnalysis(repoPath, snapshot) {
40297
- const filename = buildAnalysisFilename(snapshot.id, snapshot.createdAt);
40298
- atomicWriteJson(analysisFilePath(repoPath, filename), snapshot);
40299
- return { filename, snapshot };
40300
- }
40301
- function readAnalysis(repoPath, filename) {
40302
- const file = analysisFilePath(repoPath, filename);
40303
- if (!fs7.existsSync(file)) return null;
40304
- return JSON.parse(fs7.readFileSync(file, "utf-8"));
40305
- }
40306
- function listAnalyses(repoPath) {
40307
- const dir = analysesDir(repoPath);
40308
- if (!fs7.existsSync(dir)) return [];
40309
- return fs7.readdirSync(dir).filter((name) => name.endsWith(".json")).sort();
40310
- }
40311
- function findAnalysisFilename(repoPath, analysisId) {
40312
- for (const name of listAnalyses(repoPath).reverse()) {
40313
- const snap = readAnalysis(repoPath, name);
40314
- if (snap?.id === analysisId) return name;
40315
- }
40316
- return null;
40317
- }
40318
- function deleteAnalysis(repoPath, filename) {
40319
- try {
40320
- fs7.unlinkSync(analysisFilePath(repoPath, filename));
40321
- } catch (err) {
40322
- if (err.code !== "ENOENT") throw err;
40323
- }
40324
- }
40325
- function readHistory(repoPath) {
40326
- const file = historyPath(repoPath);
40327
- if (!fs7.existsSync(file)) return { analyses: [] };
40328
- return JSON.parse(fs7.readFileSync(file, "utf-8"));
40329
- }
40330
- function appendHistory(repoPath, entry) {
40331
- const history = readHistory(repoPath);
40332
- history.analyses.push(entry);
40333
- atomicWriteJson(historyPath(repoPath), history);
40334
- }
40335
- function removeFromHistory(repoPath, analysisId) {
40336
- const history = readHistory(repoPath);
40337
- const next = history.analyses.filter((a) => a.id !== analysisId);
40338
- if (next.length === history.analyses.length) return;
40339
- atomicWriteJson(historyPath(repoPath), { analyses: next });
40340
- }
40341
- function readDiff(repoPath) {
40342
- const file = diffPath(repoPath);
40343
- if (!fs7.existsSync(file)) return null;
40344
- return JSON.parse(fs7.readFileSync(file, "utf-8"));
40345
- }
40346
- function writeDiff(repoPath, diff) {
40347
- atomicWriteJson(diffPath(repoPath), diff);
40348
- }
40349
- function deleteDiff(repoPath) {
40350
- try {
40351
- fs7.unlinkSync(diffPath(repoPath));
40352
- } catch (err) {
40353
- if (err.code !== "ENOENT") throw err;
40354
- }
40355
- }
40356
- function clearLatestCache() {
40357
- latestCache.clear();
40358
- }
40359
- var TRUECOURSE_DIR2, ANALYSES_DIR, LATEST_FILE, HISTORY_FILE, DIFF_FILE, latestCache;
40360
- var init_analysis_store = __esm({
40361
- "apps/server/src/lib/analysis-store.ts"() {
40362
- "use strict";
40363
- init_atomic_write();
40364
- TRUECOURSE_DIR2 = ".truecourse";
40365
- ANALYSES_DIR = "analyses";
40366
- LATEST_FILE = "LATEST.json";
40367
- HISTORY_FILE = "history.json";
40368
- DIFF_FILE = "diff.json";
40369
- latestCache = /* @__PURE__ */ new Map();
40370
- }
40371
- });
40372
-
40373
40160
  // node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
40374
40161
  var require_ignore = __commonJS({
40375
40162
  "node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js"(exports, module) {
@@ -40667,7 +40454,7 @@ var require_ignore = __commonJS({
40667
40454
  // path matching.
40668
40455
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
40669
40456
  // @returns {TestResult} true if a file is ignored
40670
- test(path17, checkUnignored, mode) {
40457
+ test(path18, checkUnignored, mode) {
40671
40458
  let ignored = false;
40672
40459
  let unignored = false;
40673
40460
  let matchedRule;
@@ -40676,7 +40463,7 @@ var require_ignore = __commonJS({
40676
40463
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
40677
40464
  return;
40678
40465
  }
40679
- const matched = rule[mode].test(path17);
40466
+ const matched = rule[mode].test(path18);
40680
40467
  if (!matched) {
40681
40468
  return;
40682
40469
  }
@@ -40697,17 +40484,17 @@ var require_ignore = __commonJS({
40697
40484
  var throwError = (message, Ctor) => {
40698
40485
  throw new Ctor(message);
40699
40486
  };
40700
- var checkPath = (path17, originalPath, doThrow) => {
40701
- if (!isString(path17)) {
40487
+ var checkPath = (path18, originalPath, doThrow) => {
40488
+ if (!isString(path18)) {
40702
40489
  return doThrow(
40703
40490
  `path must be a string, but got \`${originalPath}\``,
40704
40491
  TypeError
40705
40492
  );
40706
40493
  }
40707
- if (!path17) {
40494
+ if (!path18) {
40708
40495
  return doThrow(`path must not be empty`, TypeError);
40709
40496
  }
40710
- if (checkPath.isNotRelative(path17)) {
40497
+ if (checkPath.isNotRelative(path18)) {
40711
40498
  const r = "`path.relative()`d";
40712
40499
  return doThrow(
40713
40500
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -40716,7 +40503,7 @@ var require_ignore = __commonJS({
40716
40503
  }
40717
40504
  return true;
40718
40505
  };
40719
- var isNotRelative = (path17) => REGEX_TEST_INVALID_PATH.test(path17);
40506
+ var isNotRelative = (path18) => REGEX_TEST_INVALID_PATH.test(path18);
40720
40507
  checkPath.isNotRelative = isNotRelative;
40721
40508
  checkPath.convert = (p) => p;
40722
40509
  var Ignore = class {
@@ -40746,19 +40533,19 @@ var require_ignore = __commonJS({
40746
40533
  }
40747
40534
  // @returns {TestResult}
40748
40535
  _test(originalPath, cache2, checkUnignored, slices) {
40749
- const path17 = originalPath && checkPath.convert(originalPath);
40536
+ const path18 = originalPath && checkPath.convert(originalPath);
40750
40537
  checkPath(
40751
- path17,
40538
+ path18,
40752
40539
  originalPath,
40753
40540
  this._strictPathCheck ? throwError : RETURN_FALSE
40754
40541
  );
40755
- return this._t(path17, cache2, checkUnignored, slices);
40542
+ return this._t(path18, cache2, checkUnignored, slices);
40756
40543
  }
40757
- checkIgnore(path17) {
40758
- if (!REGEX_TEST_TRAILING_SLASH.test(path17)) {
40759
- return this.test(path17);
40544
+ checkIgnore(path18) {
40545
+ if (!REGEX_TEST_TRAILING_SLASH.test(path18)) {
40546
+ return this.test(path18);
40760
40547
  }
40761
- const slices = path17.split(SLASH).filter(Boolean);
40548
+ const slices = path18.split(SLASH).filter(Boolean);
40762
40549
  slices.pop();
40763
40550
  if (slices.length) {
40764
40551
  const parent = this._t(
@@ -40771,18 +40558,18 @@ var require_ignore = __commonJS({
40771
40558
  return parent;
40772
40559
  }
40773
40560
  }
40774
- return this._rules.test(path17, false, MODE_CHECK_IGNORE);
40561
+ return this._rules.test(path18, false, MODE_CHECK_IGNORE);
40775
40562
  }
40776
- _t(path17, cache2, checkUnignored, slices) {
40777
- if (path17 in cache2) {
40778
- return cache2[path17];
40563
+ _t(path18, cache2, checkUnignored, slices) {
40564
+ if (path18 in cache2) {
40565
+ return cache2[path18];
40779
40566
  }
40780
40567
  if (!slices) {
40781
- slices = path17.split(SLASH).filter(Boolean);
40568
+ slices = path18.split(SLASH).filter(Boolean);
40782
40569
  }
40783
40570
  slices.pop();
40784
40571
  if (!slices.length) {
40785
- return cache2[path17] = this._rules.test(path17, checkUnignored, MODE_IGNORE);
40572
+ return cache2[path18] = this._rules.test(path18, checkUnignored, MODE_IGNORE);
40786
40573
  }
40787
40574
  const parent = this._t(
40788
40575
  slices.join(SLASH) + SLASH,
@@ -40790,29 +40577,29 @@ var require_ignore = __commonJS({
40790
40577
  checkUnignored,
40791
40578
  slices
40792
40579
  );
40793
- return cache2[path17] = parent.ignored ? parent : this._rules.test(path17, checkUnignored, MODE_IGNORE);
40580
+ return cache2[path18] = parent.ignored ? parent : this._rules.test(path18, checkUnignored, MODE_IGNORE);
40794
40581
  }
40795
- ignores(path17) {
40796
- return this._test(path17, this._ignoreCache, false).ignored;
40582
+ ignores(path18) {
40583
+ return this._test(path18, this._ignoreCache, false).ignored;
40797
40584
  }
40798
40585
  createFilter() {
40799
- return (path17) => !this.ignores(path17);
40586
+ return (path18) => !this.ignores(path18);
40800
40587
  }
40801
40588
  filter(paths) {
40802
40589
  return makeArray(paths).filter(this.createFilter());
40803
40590
  }
40804
40591
  // @returns {TestResult}
40805
- test(path17) {
40806
- return this._test(path17, this._testCache, true);
40592
+ test(path18) {
40593
+ return this._test(path18, this._testCache, true);
40807
40594
  }
40808
40595
  };
40809
40596
  var factory = (options) => new Ignore(options);
40810
- var isPathValid = (path17) => checkPath(path17 && checkPath.convert(path17), path17, RETURN_FALSE);
40597
+ var isPathValid = (path18) => checkPath(path18 && checkPath.convert(path18), path18, RETURN_FALSE);
40811
40598
  var setupWindows = () => {
40812
40599
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
40813
40600
  checkPath.convert = makePosix;
40814
40601
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
40815
- checkPath.isNotRelative = (path17) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path17) || isNotRelative(path17);
40602
+ checkPath.isNotRelative = (path18) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path18) || isNotRelative(path18);
40816
40603
  };
40817
40604
  if (
40818
40605
  // Detect `process` so that it can run in browsers.
@@ -41092,30 +40879,52 @@ var init_file_discovery = __esm({
41092
40879
  });
41093
40880
 
41094
40881
  // packages/analyzer/dist/parser.js
41095
- import Parser from "tree-sitter";
41096
- import TypeScriptParser from "tree-sitter-typescript";
41097
- import JavaScriptParser from "tree-sitter-javascript";
41098
- import PythonParser from "tree-sitter-python";
41099
- function getTreeSitterLanguage(language) {
41100
- switch (language) {
41101
- case "typescript":
41102
- return TypeScriptParser.typescript;
41103
- case "tsx":
41104
- return TypeScriptParser.tsx;
41105
- case "javascript":
41106
- return JavaScriptParser;
41107
- case "python":
41108
- return PythonParser;
41109
- default:
41110
- throw new Error(`Unsupported language: ${language}`);
40882
+ import { Parser, Language } from "web-tree-sitter";
40883
+ import { createRequire as _createRequire } from "node:module";
40884
+ import { fileURLToPath } from "node:url";
40885
+ import path7 from "node:path";
40886
+ import fs8 from "node:fs";
40887
+ function resolveWasmPath(subpath) {
40888
+ const bundled = path7.join(BUNDLED_WASM_DIR, path7.basename(subpath));
40889
+ if (fs8.existsSync(bundled))
40890
+ return bundled;
40891
+ return _require.resolve(subpath);
40892
+ }
40893
+ function initParsers() {
40894
+ if (!initPromise) {
40895
+ initPromise = doInit().then(() => {
40896
+ initialized = true;
40897
+ });
40898
+ }
40899
+ return initPromise;
40900
+ }
40901
+ async function doInit() {
40902
+ await Parser.init({
40903
+ locateFile(file) {
40904
+ return resolveWasmPath(`web-tree-sitter/${file}`);
40905
+ }
40906
+ });
40907
+ await Promise.all(Object.keys(GRAMMAR_WASM).map(async (lang) => {
40908
+ const wasmPath = resolveWasmPath(GRAMMAR_WASM[lang]);
40909
+ const language = await Language.load(wasmPath);
40910
+ languageCache.set(lang, language);
40911
+ }));
40912
+ }
40913
+ function assertInitialized() {
40914
+ if (!initialized) {
40915
+ throw new Error("tree-sitter parsers are not loaded. Call `await initParsers()` from @truecourse/analyzer before using parseCode / parseFile / getParser. This is required once per process \u2014 the call is idempotent.");
41111
40916
  }
41112
40917
  }
41113
40918
  function getParser(language) {
40919
+ if (!(language in GRAMMAR_WASM)) {
40920
+ throw new Error(`Unsupported language: ${language}`);
40921
+ }
40922
+ assertInitialized();
41114
40923
  let parser4 = parserCache.get(language);
41115
40924
  if (!parser4) {
40925
+ const lang = languageCache.get(language);
41116
40926
  parser4 = new Parser();
41117
- const tsLanguage = getTreeSitterLanguage(language);
41118
- parser4.setLanguage(tsLanguage);
40927
+ parser4.setLanguage(lang);
41119
40928
  parserCache.set(language, parser4);
41120
40929
  }
41121
40930
  return parser4;
@@ -41135,11 +40944,22 @@ function parseFile(filePath, code, language) {
41135
40944
  throw new Error(`Failed to parse file ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
41136
40945
  }
41137
40946
  }
41138
- var parserCache;
40947
+ var _require, BUNDLED_WASM_DIR, GRAMMAR_WASM, languageCache, parserCache, initPromise, initialized;
41139
40948
  var init_parser = __esm({
41140
40949
  "packages/analyzer/dist/parser.js"() {
41141
40950
  "use strict";
40951
+ _require = _createRequire(import.meta.url);
40952
+ BUNDLED_WASM_DIR = path7.join(path7.dirname(fileURLToPath(import.meta.url)), "wasm");
40953
+ GRAMMAR_WASM = {
40954
+ typescript: "tree-sitter-typescript/tree-sitter-typescript.wasm",
40955
+ tsx: "tree-sitter-typescript/tree-sitter-tsx.wasm",
40956
+ javascript: "tree-sitter-javascript/tree-sitter-javascript.wasm",
40957
+ python: "tree-sitter-python/tree-sitter-python.wasm"
40958
+ };
40959
+ languageCache = /* @__PURE__ */ new Map();
41142
40960
  parserCache = /* @__PURE__ */ new Map();
40961
+ initPromise = null;
40962
+ initialized = false;
41143
40963
  }
41144
40964
  });
41145
40965
 
@@ -42078,18 +41898,18 @@ function extractRouterMount(callNode, filePath) {
42078
41898
  const routerName = args[0]?.type === "identifier" ? args[0].text : null;
42079
41899
  if (!routerName)
42080
41900
  return null;
42081
- let path17 = "/";
41901
+ let path18 = "/";
42082
41902
  for (const arg of args) {
42083
41903
  if (arg.type === "keyword_argument") {
42084
41904
  const key = arg.childForFieldName("name")?.text;
42085
41905
  const value = arg.childForFieldName("value");
42086
41906
  if ((key === "url_prefix" || key === "prefix") && value) {
42087
- path17 = value.text.replace(/^["']|["']$/g, "");
41907
+ path18 = value.text.replace(/^["']|["']$/g, "");
42088
41908
  }
42089
41909
  }
42090
41910
  }
42091
41911
  return {
42092
- path: path17,
41912
+ path: path18,
42093
41913
  routerName,
42094
41914
  location: {
42095
41915
  filePath,
@@ -42113,11 +41933,11 @@ function extractChainedRoute(outerCall, filePath) {
42113
41933
  const innerArgs = innerCall.childForFieldName("arguments");
42114
41934
  if (!innerArgs)
42115
41935
  return null;
42116
- let path17 = null;
41936
+ let path18 = null;
42117
41937
  let httpMethod = methodName === "route" ? "GET" : methodName.toUpperCase();
42118
41938
  for (const arg of innerArgs.namedChildren) {
42119
- if (!path17 && arg.type === "string") {
42120
- path17 = arg.text.replace(/^["']|["']$/g, "");
41939
+ if (!path18 && arg.type === "string") {
41940
+ path18 = arg.text.replace(/^["']|["']$/g, "");
42121
41941
  }
42122
41942
  if (arg.type === "keyword_argument") {
42123
41943
  const key = arg.childForFieldName("name")?.text;
@@ -42129,14 +41949,14 @@ function extractChainedRoute(outerCall, filePath) {
42129
41949
  }
42130
41950
  }
42131
41951
  }
42132
- if (!path17)
41952
+ if (!path18)
42133
41953
  return null;
42134
41954
  const outerArgs = outerCall.childForFieldName("arguments");
42135
41955
  const handlerArg = outerArgs?.namedChildren[0];
42136
41956
  const handlerName = handlerArg?.type === "identifier" ? handlerArg.text : "anonymous";
42137
41957
  return {
42138
41958
  httpMethod,
42139
- path: path17,
41959
+ path: path18,
42140
41960
  handlerName,
42141
41961
  location: {
42142
41962
  filePath,
@@ -42212,8 +42032,8 @@ function extractRoute(methodName, argsNode, filePath, callNode) {
42212
42032
  const firstArg = argsNode.namedChild(0);
42213
42033
  if (!firstArg)
42214
42034
  return null;
42215
- const path17 = extractStringLiteral(firstArg);
42216
- if (!path17)
42035
+ const path18 = extractStringLiteral(firstArg);
42036
+ if (!path18)
42217
42037
  return null;
42218
42038
  const argCount = argsNode.namedChildCount;
42219
42039
  if (argCount < 2)
@@ -42226,7 +42046,7 @@ function extractRoute(methodName, argsNode, filePath, callNode) {
42226
42046
  return null;
42227
42047
  return {
42228
42048
  httpMethod: methodName.toUpperCase(),
42229
- path: path17,
42049
+ path: path18,
42230
42050
  handlerName,
42231
42051
  location: {
42232
42052
  filePath,
@@ -42243,8 +42063,8 @@ function extractMount(argsNode, filePath, callNode) {
42243
42063
  const firstArg = argsNode.namedChild(0);
42244
42064
  if (!firstArg)
42245
42065
  return null;
42246
- const path17 = extractStringLiteral(firstArg);
42247
- if (!path17)
42066
+ const path18 = extractStringLiteral(firstArg);
42067
+ if (!path18)
42248
42068
  return null;
42249
42069
  const secondArg = argsNode.namedChild(1);
42250
42070
  if (!secondArg)
@@ -42253,7 +42073,7 @@ function extractMount(argsNode, filePath, callNode) {
42253
42073
  if (!routerName)
42254
42074
  return null;
42255
42075
  return {
42256
- path: path17,
42076
+ path: path18,
42257
42077
  routerName,
42258
42078
  location: {
42259
42079
  filePath,
@@ -42374,7 +42194,7 @@ var init_common = __esm({
42374
42194
  });
42375
42195
 
42376
42196
  // packages/analyzer/dist/extractors/languages/typescript.js
42377
- import Parser2 from "tree-sitter";
42197
+ import { Query as Query2 } from "web-tree-sitter";
42378
42198
  function isNestedInFunction(node2) {
42379
42199
  let current = node2.parent;
42380
42200
  while (current) {
@@ -42670,8 +42490,10 @@ function extractTypeScriptFunctions(tree, filePath, language = "typescript") {
42670
42490
  const seenLocations = /* @__PURE__ */ new Set();
42671
42491
  const queryString = config2.functionQuery || config2.functionNodeTypes.map((type) => `(${type}) @function`).join("\n");
42672
42492
  const parser4 = getParser(language);
42673
- const tsLanguage = parser4.getLanguage();
42674
- const query = new Parser2.Query(tsLanguage, queryString);
42493
+ const tsLanguage = parser4.language;
42494
+ if (!tsLanguage)
42495
+ throw new Error(`parser for '${language}' has no language set`);
42496
+ const query = new Query2(tsLanguage, queryString);
42675
42497
  const captures = query.captures(tree.rootNode);
42676
42498
  for (const capture of captures) {
42677
42499
  const node2 = capture.node;
@@ -42709,8 +42531,10 @@ function extractTypeScriptClasses(tree, filePath, language = "typescript") {
42709
42531
  const classes = [];
42710
42532
  const queryString = config2.classQuery || config2.classNodeTypes.map((type) => `(${type}) @class`).join("\n");
42711
42533
  const parser4 = getParser(language);
42712
- const tsLanguage = parser4.getLanguage();
42713
- const query = new Parser2.Query(tsLanguage, queryString);
42534
+ const tsLanguage = parser4.language;
42535
+ if (!tsLanguage)
42536
+ throw new Error(`parser for '${language}' has no language set`);
42537
+ const query = new Query2(tsLanguage, queryString);
42714
42538
  const captures = query.captures(tree.rootNode);
42715
42539
  for (const capture of captures) {
42716
42540
  const node2 = capture.node;
@@ -42749,8 +42573,10 @@ function extractTypeScriptImports(tree, filePath, language = "typescript") {
42749
42573
  const imports = [];
42750
42574
  const queryString = config2.importQuery || config2.importNodeTypes.map((type) => `(${type}) @import`).join("\n");
42751
42575
  const parser4 = getParser(language);
42752
- const tsLanguage = parser4.getLanguage();
42753
- const query = new Parser2.Query(tsLanguage, queryString);
42576
+ const tsLanguage = parser4.language;
42577
+ if (!tsLanguage)
42578
+ throw new Error(`parser for '${language}' has no language set`);
42579
+ const query = new Query2(tsLanguage, queryString);
42754
42580
  const captures = query.captures(tree.rootNode);
42755
42581
  for (const capture of captures) {
42756
42582
  const node2 = capture.node;
@@ -42775,8 +42601,10 @@ function extractTypeScriptExports(tree, _filePath, language = "typescript") {
42775
42601
  const exports = [];
42776
42602
  const queryString = config2.exportQuery || config2.exportNodeTypes.map((type) => `(${type}) @export`).join("\n");
42777
42603
  const parser4 = getParser(language);
42778
- const tsLanguage = parser4.getLanguage();
42779
- const query = new Parser2.Query(tsLanguage, queryString);
42604
+ const tsLanguage = parser4.language;
42605
+ if (!tsLanguage)
42606
+ throw new Error(`parser for '${language}' has no language set`);
42607
+ const query = new Query2(tsLanguage, queryString);
42780
42608
  const captures = query.captures(tree.rootNode);
42781
42609
  for (const capture of captures) {
42782
42610
  const node2 = capture.node;
@@ -42815,7 +42643,7 @@ var init_typescript = __esm({
42815
42643
  });
42816
42644
 
42817
42645
  // packages/analyzer/dist/extractors/languages/javascript.js
42818
- import Parser3 from "tree-sitter";
42646
+ import { Query as Query3 } from "web-tree-sitter";
42819
42647
  function extractFunctionName2(node2) {
42820
42648
  const nameNode = node2.childForFieldName("name");
42821
42649
  if (nameNode?.text)
@@ -42897,8 +42725,10 @@ function extractJavaScriptFunctions(tree, filePath) {
42897
42725
  const functions = [];
42898
42726
  const queryString = config2.functionQuery || config2.functionNodeTypes.map((type) => `(${type}) @function`).join("\n");
42899
42727
  const parser4 = getParser("javascript");
42900
- const jsLanguage = parser4.getLanguage();
42901
- const query = new Parser3.Query(jsLanguage, queryString);
42728
+ const jsLanguage = parser4.language;
42729
+ if (!jsLanguage)
42730
+ throw new Error("parser has no language set");
42731
+ const query = new Query3(jsLanguage, queryString);
42902
42732
  const captures = query.captures(tree.rootNode);
42903
42733
  for (const capture of captures) {
42904
42734
  const node2 = capture.node;
@@ -43033,8 +42863,10 @@ function extractJavaScriptClasses(tree, filePath) {
43033
42863
  const classes = [];
43034
42864
  const queryString = config2.classQuery || config2.classNodeTypes.map((type) => `(${type}) @class`).join("\n");
43035
42865
  const parser4 = getParser("javascript");
43036
- const jsLanguage = parser4.getLanguage();
43037
- const query = new Parser3.Query(jsLanguage, queryString);
42866
+ const jsLanguage = parser4.language;
42867
+ if (!jsLanguage)
42868
+ throw new Error("parser has no language set");
42869
+ const query = new Query3(jsLanguage, queryString);
43038
42870
  const captures = query.captures(tree.rootNode);
43039
42871
  for (const capture of captures) {
43040
42872
  const node2 = capture.node;
@@ -43118,8 +42950,10 @@ function extractJavaScriptImports(tree, _filePath) {
43118
42950
  const imports = [];
43119
42951
  const queryString = config2.importQuery || config2.importNodeTypes.map((type) => `(${type}) @import`).join("\n");
43120
42952
  const parser4 = getParser("javascript");
43121
- const jsLanguage = parser4.getLanguage();
43122
- const query = new Parser3.Query(jsLanguage, queryString);
42953
+ const jsLanguage = parser4.language;
42954
+ if (!jsLanguage)
42955
+ throw new Error("parser has no language set");
42956
+ const query = new Query3(jsLanguage, queryString);
43123
42957
  const captures = query.captures(tree.rootNode);
43124
42958
  for (const capture of captures) {
43125
42959
  const node2 = capture.node;
@@ -43175,8 +43009,10 @@ function extractJavaScriptExports(tree, _filePath) {
43175
43009
  const exports = [];
43176
43010
  const queryString = config2.exportQuery || config2.exportNodeTypes.map((type) => `(${type}) @export`).join("\n");
43177
43011
  const parser4 = getParser("javascript");
43178
- const jsLanguage = parser4.getLanguage();
43179
- const query = new Parser3.Query(jsLanguage, queryString);
43012
+ const jsLanguage = parser4.language;
43013
+ if (!jsLanguage)
43014
+ throw new Error("parser has no language set");
43015
+ const query = new Query3(jsLanguage, queryString);
43180
43016
  const captures = query.captures(tree.rootNode);
43181
43017
  for (const capture of captures) {
43182
43018
  const node2 = capture.node;
@@ -45529,7 +45365,7 @@ var init_escape = __esm({
45529
45365
  });
45530
45366
 
45531
45367
  // node_modules/.pnpm/minimatch@10.2.4/node_modules/minimatch/dist/esm/index.js
45532
- var minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path7, sep, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
45368
+ var minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path8, sep, GLOBSTAR, qmark2, star2, twoStarDot, twoStarNoDot, filter, ext, defaults, braceExpand, makeRe, match, globMagic, regExpEscape2, Minimatch;
45533
45369
  var init_esm3 = __esm({
45534
45370
  "node_modules/.pnpm/minimatch@10.2.4/node_modules/minimatch/dist/esm/index.js"() {
45535
45371
  init_esm2();
@@ -45598,11 +45434,11 @@ var init_esm3 = __esm({
45598
45434
  return (f2) => f2.length === len && f2 !== "." && f2 !== "..";
45599
45435
  };
45600
45436
  defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
45601
- path7 = {
45437
+ path8 = {
45602
45438
  win32: { sep: "\\" },
45603
45439
  posix: { sep: "/" }
45604
45440
  };
45605
- sep = defaultPlatform === "win32" ? path7.win32.sep : path7.posix.sep;
45441
+ sep = defaultPlatform === "win32" ? path8.win32.sep : path8.posix.sep;
45606
45442
  minimatch.sep = sep;
45607
45443
  GLOBSTAR = Symbol("globstar **");
45608
45444
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -46777,9 +46613,9 @@ function detectDockerComposeServices(rootPath, allFiles) {
46777
46613
  ];
46778
46614
  let composePath2 = null;
46779
46615
  for (const file of composeFiles) {
46780
- const path17 = join6(rootPath, file);
46781
- if (existsSync7(path17)) {
46782
- composePath2 = path17;
46616
+ const path18 = join6(rootPath, file);
46617
+ if (existsSync7(path18)) {
46618
+ composePath2 = path18;
46783
46619
  break;
46784
46620
  }
46785
46621
  }
@@ -47648,7 +47484,7 @@ var init_database_detector = __esm({
47648
47484
  });
47649
47485
 
47650
47486
  // packages/analyzer/dist/module-extractor.js
47651
- import path8 from "path";
47487
+ import path9 from "path";
47652
47488
  function extractModulesAndMethods(analyses, layerDetails, fileDependencies) {
47653
47489
  const modules = [];
47654
47490
  const methods = [];
@@ -47795,7 +47631,7 @@ function deriveModuleName(analysis) {
47795
47631
  return localExports[0].name;
47796
47632
  }
47797
47633
  const baseName = fileBaseName(analysis.filePath);
47798
- const strippedName = stripExtension(path8.basename(analysis.filePath));
47634
+ const strippedName = stripExtension(path9.basename(analysis.filePath));
47799
47635
  if (INDEX_NAMES.has(strippedName)) {
47800
47636
  return baseName;
47801
47637
  }
@@ -47812,10 +47648,10 @@ function deriveModuleName(analysis) {
47812
47648
  return baseName;
47813
47649
  }
47814
47650
  function deriveNextjsRouteName(filePath) {
47815
- const base = path8.basename(filePath).replace(/\.(ts|tsx|js|jsx)$/, "");
47651
+ const base = path9.basename(filePath).replace(/\.(ts|tsx|js|jsx)$/, "");
47816
47652
  if (base !== "route" && base !== "page")
47817
47653
  return null;
47818
- const parts = filePath.split(path8.sep);
47654
+ const parts = filePath.split(path9.sep);
47819
47655
  const appIdx = parts.lastIndexOf("app");
47820
47656
  if (appIdx === -1)
47821
47657
  return null;
@@ -47833,9 +47669,9 @@ function stripExtension(filename) {
47833
47669
  return filename;
47834
47670
  }
47835
47671
  function fileBaseName(filePath) {
47836
- const name = stripExtension(path8.basename(filePath));
47672
+ const name = stripExtension(path9.basename(filePath));
47837
47673
  if (INDEX_NAMES.has(name)) {
47838
- return path8.basename(path8.dirname(filePath));
47674
+ return path9.basename(path9.dirname(filePath));
47839
47675
  }
47840
47676
  return name;
47841
47677
  }
@@ -48532,7 +48368,11 @@ var init_entities = __esm({
48532
48368
  init_patterns();
48533
48369
  init_parser();
48534
48370
  TypeScriptEntityDetector = class {
48535
- parser = getParser("typescript");
48371
+ // Lazy: do not call getParser() at construction time — callers may
48372
+ // instantiate this before initParsers() has completed.
48373
+ get parser() {
48374
+ return getParser("typescript");
48375
+ }
48536
48376
  shouldScanFile(filePath) {
48537
48377
  if (!/\.(ts|tsx|js|jsx)$/.test(filePath)) {
48538
48378
  return false;
@@ -48549,6 +48389,8 @@ var init_entities = __esm({
48549
48389
  detectEntities(sourceCode, filePath, service) {
48550
48390
  const tree = this.parser.parse(sourceCode);
48551
48391
  const entities = [];
48392
+ if (!tree)
48393
+ return entities;
48552
48394
  const classNodes = this.findClassDeclarations(tree.rootNode);
48553
48395
  for (const classNode of classNodes) {
48554
48396
  const entity = this.detectEntityFromClass(classNode, sourceCode, filePath, service);
@@ -48836,7 +48678,7 @@ var init_entities = __esm({
48836
48678
  import { spawn as spawn2 } from "child_process";
48837
48679
  import { readFileSync as readFileSync7 } from "fs";
48838
48680
  import { resolve as resolve5 } from "path";
48839
- import { pathToFileURL, fileURLToPath } from "url";
48681
+ import { pathToFileURL, fileURLToPath as fileURLToPath2 } from "url";
48840
48682
  function encodeMessage(msg) {
48841
48683
  const body = JSON.stringify(msg);
48842
48684
  const header = `Content-Length: ${Buffer.byteLength(body)}\r
@@ -48981,7 +48823,7 @@ var init_lsp_client = __esm({
48981
48823
  if (!uri)
48982
48824
  return null;
48983
48825
  try {
48984
- return fileURLToPath(uri);
48826
+ return fileURLToPath2(uri);
48985
48827
  } catch {
48986
48828
  return null;
48987
48829
  }
@@ -49149,7 +48991,7 @@ var init_lsp_client = __esm({
49149
48991
  // packages/analyzer/dist/lsp-servers/pyright.js
49150
48992
  import { resolve as resolve6, dirname as dirname5 } from "path";
49151
48993
  import { existsSync as existsSync9 } from "fs";
49152
- import { fileURLToPath as fileURLToPath2 } from "url";
48994
+ import { fileURLToPath as fileURLToPath3 } from "url";
49153
48995
  function findPyrightBinary() {
49154
48996
  let dir = resolve6(__dirname2, "..");
49155
48997
  for (let i = 0; i < 10; i++) {
@@ -49181,7 +49023,7 @@ var __filename, __dirname2;
49181
49023
  var init_pyright = __esm({
49182
49024
  "packages/analyzer/dist/lsp-servers/pyright.js"() {
49183
49025
  "use strict";
49184
- __filename = fileURLToPath2(import.meta.url);
49026
+ __filename = fileURLToPath3(import.meta.url);
49185
49027
  __dirname2 = dirname5(__filename);
49186
49028
  }
49187
49029
  });
@@ -49808,9 +49650,9 @@ function findSimpleCycles(component, componentSet, adjacency) {
49808
49650
  for (const next of successors) {
49809
49651
  if (!componentSet.has(next))
49810
49652
  continue;
49811
- if (next === start && path17.length >= 2) {
49812
- const chain = [...path17, start];
49813
- const minNode = path17.reduce((a, b) => a < b ? a : b);
49653
+ if (next === start && path18.length >= 2) {
49654
+ const chain = [...path18, start];
49655
+ const minNode = path18.reduce((a, b) => a < b ? a : b);
49814
49656
  if (minNode === start) {
49815
49657
  cycles.push(chain);
49816
49658
  }
@@ -49818,15 +49660,15 @@ function findSimpleCycles(component, componentSet, adjacency) {
49818
49660
  }
49819
49661
  if (!visited.has(next) && !seen.has(next)) {
49820
49662
  visited.add(next);
49821
- path17.push(next);
49663
+ path18.push(next);
49822
49664
  dfs2(next);
49823
- path17.pop();
49665
+ path18.pop();
49824
49666
  visited.delete(next);
49825
49667
  }
49826
49668
  }
49827
49669
  };
49828
49670
  var dfs = dfs2;
49829
- const path17 = [start];
49671
+ const path18 = [start];
49830
49672
  const visited = /* @__PURE__ */ new Set([start]);
49831
49673
  dfs2(start);
49832
49674
  seen.add(start);
@@ -49848,7 +49690,7 @@ function findShortestCycle(start, componentSet, adjacency) {
49848
49690
  visited.add(next);
49849
49691
  }
49850
49692
  while (queue.length > 0) {
49851
- const { node: node2, path: path17 } = queue.shift();
49693
+ const { node: node2, path: path18 } = queue.shift();
49852
49694
  const nexts = adjacency.get(node2);
49853
49695
  if (!nexts)
49854
49696
  continue;
@@ -49856,11 +49698,11 @@ function findShortestCycle(start, componentSet, adjacency) {
49856
49698
  if (!componentSet.has(next))
49857
49699
  continue;
49858
49700
  if (next === start) {
49859
- return [...path17, start];
49701
+ return [...path18, start];
49860
49702
  }
49861
49703
  if (!visited.has(next)) {
49862
49704
  visited.add(next);
49863
- queue.push({ node: next, path: [...path17, next] });
49705
+ queue.push({ node: next, path: [...path18, next] });
49864
49706
  }
49865
49707
  }
49866
49708
  }
@@ -68656,7 +68498,8 @@ var init_python_helpers = __esm({
68656
68498
  // packages/analyzer/dist/rules/_shared/python-framework-detection.js
68657
68499
  function getPythonImportSources(node2) {
68658
68500
  const program = getPythonModuleNode(node2);
68659
- const cached = importSourceCache.get(program);
68501
+ const tree = program.tree;
68502
+ const cached = importSourceCache.get(tree);
68660
68503
  if (cached)
68661
68504
  return cached;
68662
68505
  const sources = /* @__PURE__ */ new Set();
@@ -68695,7 +68538,7 @@ function getPythonImportSources(node2) {
68695
68538
  walk(child);
68696
68539
  }
68697
68540
  walk(program);
68698
- importSourceCache.set(program, sources);
68541
+ importSourceCache.set(tree, sources);
68699
68542
  return sources;
68700
68543
  }
68701
68544
  function detectPythonOrm(node2) {
@@ -74598,10 +74441,10 @@ var init_secret_rules = __esm({
74598
74441
  });
74599
74442
 
74600
74443
  // packages/analyzer/dist/rules/security/secret-scanner.js
74601
- import path9 from "node:path";
74444
+ import path10 from "node:path";
74602
74445
  function isSensitiveFile(filePath) {
74603
- const basename2 = path9.basename(filePath);
74604
- const ext2 = path9.extname(filePath);
74446
+ const basename2 = path10.basename(filePath);
74447
+ const ext2 = path10.extname(filePath);
74605
74448
  if (basename2.startsWith(".env")) {
74606
74449
  const envVariant = basename2;
74607
74450
  if (SENSITIVE_FILE_EXTENSIONS.has(envVariant)) {
@@ -76769,7 +76612,8 @@ var init_fallthrough_case = __esm({
76769
76612
  const cases = body.namedChildren.filter((c) => c.type === "switch_case");
76770
76613
  for (let i = 0; i < cases.length - 1; i++) {
76771
76614
  const caseNode = cases[i];
76772
- const statements = caseNode.namedChildren.filter((c) => c.type !== "comment" && c !== caseNode.childForFieldName("value"));
76615
+ const valueNode = caseNode.childForFieldName("value");
76616
+ const statements = caseNode.namedChildren.filter((c) => c.type !== "comment" && (!valueNode || c.id !== valueNode.id));
76773
76617
  if (statements.length === 0)
76774
76618
  continue;
76775
76619
  const last2 = statements[statements.length - 1];
@@ -98272,7 +98116,7 @@ var init_case_without_break = __esm({
98272
98116
  nodeTypes: ["switch_case"],
98273
98117
  visit(node2, filePath, sourceCode) {
98274
98118
  const valueNode = node2.childForFieldName("value");
98275
- const stmts = node2.namedChildren.filter((c) => c !== valueNode);
98119
+ const stmts = node2.namedChildren.filter((c) => !valueNode || c.id !== valueNode.id);
98276
98120
  if (stmts.length === 0)
98277
98121
  return null;
98278
98122
  let last2 = stmts[stmts.length - 1];
@@ -121200,8 +121044,8 @@ var init_missing_error_status_code = __esm({
121200
121044
  });
121201
121045
 
121202
121046
  // packages/analyzer/dist/rules/architecture/visitors/javascript/route-without-auth-middleware.js
121203
- function isPublicPath(path17) {
121204
- return PUBLIC_PATH_PATTERNS.some((re) => re.test(path17));
121047
+ function isPublicPath(path18) {
121048
+ return PUBLIC_PATH_PATTERNS.some((re) => re.test(path18));
121205
121049
  }
121206
121050
  function extractMiddlewareNames(callNode) {
121207
121051
  const args = callNode.childForFieldName("arguments");
@@ -121327,8 +121171,8 @@ var init_route_without_auth_middleware = __esm({
121327
121171
  return null;
121328
121172
  const firstArg = args.namedChildren[0];
121329
121173
  if (firstArg?.type === "string") {
121330
- const path17 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
121331
- if (isPublicPath(path17))
121174
+ const path18 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
121175
+ if (isPublicPath(path18))
121332
121176
  return null;
121333
121177
  }
121334
121178
  const middleware = extractMiddlewareNames(node2);
@@ -121725,7 +121569,7 @@ var init_declarations_in_global_scope2 = __esm({
121725
121569
 
121726
121570
  // packages/analyzer/dist/rules/architecture/visitors/python/unused-import.js
121727
121571
  function hasIdentifierOutside(root, name, excludeNode) {
121728
- if (root === excludeNode)
121572
+ if (root.id === excludeNode.id)
121729
121573
  return false;
121730
121574
  if (root.type === "identifier" && root.text === name)
121731
121575
  return true;
@@ -124101,6 +123945,7 @@ __export(dist_exports, {
124101
123945
  hasLspServer: () => hasLspServer,
124102
123946
  hasSchemaAwareVisitors: () => hasSchemaAwareVisitors,
124103
123947
  hasTypeAwareVisitors: () => hasTypeAwareVisitors,
123948
+ initParsers: () => initParsers,
124104
123949
  isBootstrapEntry: () => isBootstrapEntry,
124105
123950
  makeViolation: () => makeViolation,
124106
123951
  matchesPattern: () => matchesPattern,
@@ -124120,6 +123965,7 @@ __export(dist_exports, {
124120
123965
  walkAstWithVisitors: () => walkAstWithVisitors
124121
123966
  });
124122
123967
  async function analyzeRepository(rootPath) {
123968
+ await initParsers();
124123
123969
  const files = discoverFiles(rootPath);
124124
123970
  if (files.length === 0) {
124125
123971
  return {
@@ -124163,6 +124009,7 @@ var init_dist2 = __esm({
124163
124009
  init_file_analyzer();
124164
124010
  init_dependency_graph();
124165
124011
  init_split_analyzer();
124012
+ init_parser();
124166
124013
  init_file_analyzer();
124167
124014
  init_dependency_graph();
124168
124015
  init_service_detector();
@@ -126560,8 +126407,8 @@ var init_cli_provider = __esm({
126560
126407
  this._repoId = repoId;
126561
126408
  }
126562
126409
  /** Set target repo path — used as cwd when spawning CLI so Read tool accesses the right files. */
126563
- setRepoPath(path17) {
126564
- this._repoPath = path17;
126410
+ setRepoPath(path18) {
126411
+ this._repoPath = path18;
126565
126412
  }
126566
126413
  flushUsage() {
126567
126414
  if (this._usageRecords.length === 0) return [];
@@ -127740,11 +127587,11 @@ var require_form_data = __commonJS({
127740
127587
  "use strict";
127741
127588
  var CombinedStream = require_combined_stream();
127742
127589
  var util2 = __require("util");
127743
- var path17 = __require("path");
127590
+ var path18 = __require("path");
127744
127591
  var http = __require("http");
127745
127592
  var https = __require("https");
127746
127593
  var parseUrl = __require("url").parse;
127747
- var fs13 = __require("fs");
127594
+ var fs14 = __require("fs");
127748
127595
  var Stream = __require("stream").Stream;
127749
127596
  var crypto2 = __require("crypto");
127750
127597
  var mime = require_mime_types();
@@ -127811,7 +127658,7 @@ var require_form_data = __commonJS({
127811
127658
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
127812
127659
  callback(null, value.end + 1 - (value.start ? value.start : 0));
127813
127660
  } else {
127814
- fs13.stat(value.path, function(err, stat) {
127661
+ fs14.stat(value.path, function(err, stat) {
127815
127662
  if (err) {
127816
127663
  callback(err);
127817
127664
  return;
@@ -127868,11 +127715,11 @@ var require_form_data = __commonJS({
127868
127715
  FormData2.prototype._getContentDisposition = function(value, options) {
127869
127716
  var filename;
127870
127717
  if (typeof options.filepath === "string") {
127871
- filename = path17.normalize(options.filepath).replace(/\\/g, "/");
127718
+ filename = path18.normalize(options.filepath).replace(/\\/g, "/");
127872
127719
  } else if (options.filename || value && (value.name || value.path)) {
127873
- filename = path17.basename(options.filename || value && (value.name || value.path));
127720
+ filename = path18.basename(options.filename || value && (value.name || value.path));
127874
127721
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
127875
- filename = path17.basename(value.client._httpMessage.path || "");
127722
+ filename = path18.basename(value.client._httpMessage.path || "");
127876
127723
  }
127877
127724
  if (filename) {
127878
127725
  return 'filename="' + filename + '"';
@@ -129102,9 +128949,9 @@ var require_axios = __commonJS({
129102
128949
  function removeBrackets(key) {
129103
128950
  return utils$1.endsWith(key, "[]") ? key.slice(0, -2) : key;
129104
128951
  }
129105
- function renderKey(path17, key, dots) {
129106
- if (!path17) return key;
129107
- return path17.concat(key).map(function each(token, i) {
128952
+ function renderKey(path18, key, dots) {
128953
+ if (!path18) return key;
128954
+ return path18.concat(key).map(function each(token, i) {
129108
128955
  token = removeBrackets(token);
129109
128956
  return !dots && i ? "[" + token + "]" : token;
129110
128957
  }).join(dots ? "." : "");
@@ -129152,13 +128999,13 @@ var require_axios = __commonJS({
129152
128999
  }
129153
129000
  return value;
129154
129001
  }
129155
- function defaultVisitor(value, key, path17) {
129002
+ function defaultVisitor(value, key, path18) {
129156
129003
  let arr = value;
129157
129004
  if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
129158
- formData.append(renderKey(path17, key, dots), convertValue(value));
129005
+ formData.append(renderKey(path18, key, dots), convertValue(value));
129159
129006
  return false;
129160
129007
  }
129161
- if (value && !path17 && typeof value === "object") {
129008
+ if (value && !path18 && typeof value === "object") {
129162
129009
  if (utils$1.endsWith(key, "{}")) {
129163
129010
  key = metaTokens ? key : key.slice(0, -2);
129164
129011
  value = JSON.stringify(value);
@@ -129177,7 +129024,7 @@ var require_axios = __commonJS({
129177
129024
  if (isVisitable(value)) {
129178
129025
  return true;
129179
129026
  }
129180
- formData.append(renderKey(path17, key, dots), convertValue(value));
129027
+ formData.append(renderKey(path18, key, dots), convertValue(value));
129181
129028
  return false;
129182
129029
  }
129183
129030
  const stack2 = [];
@@ -129186,16 +129033,16 @@ var require_axios = __commonJS({
129186
129033
  convertValue,
129187
129034
  isVisitable
129188
129035
  });
129189
- function build(value, path17) {
129036
+ function build(value, path18) {
129190
129037
  if (utils$1.isUndefined(value)) return;
129191
129038
  if (stack2.indexOf(value) !== -1) {
129192
- throw Error("Circular reference detected in " + path17.join("."));
129039
+ throw Error("Circular reference detected in " + path18.join("."));
129193
129040
  }
129194
129041
  stack2.push(value);
129195
129042
  utils$1.forEach(value, function each(el, key) {
129196
- const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path17, exposedHelpers);
129043
+ const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path18, exposedHelpers);
129197
129044
  if (result === true) {
129198
- build(el, path17 ? path17.concat(key) : [key]);
129045
+ build(el, path18 ? path18.concat(key) : [key]);
129199
129046
  }
129200
129047
  });
129201
129048
  stack2.pop();
@@ -129384,7 +129231,7 @@ var require_axios = __commonJS({
129384
129231
  };
129385
129232
  function toURLEncodedForm(data, options) {
129386
129233
  return toFormData(data, new platform.classes.URLSearchParams(), {
129387
- visitor: function(value, key, path17, helpers) {
129234
+ visitor: function(value, key, path18, helpers) {
129388
129235
  if (platform.isNode && utils$1.isBuffer(value)) {
129389
129236
  this.append(key, value.toString("base64"));
129390
129237
  return false;
@@ -129412,11 +129259,11 @@ var require_axios = __commonJS({
129412
129259
  return obj;
129413
129260
  }
129414
129261
  function formDataToJSON(formData) {
129415
- function buildPath(path17, value, target, index) {
129416
- let name = path17[index++];
129262
+ function buildPath(path18, value, target, index) {
129263
+ let name = path18[index++];
129417
129264
  if (name === "__proto__") return true;
129418
129265
  const isNumericKey = Number.isFinite(+name);
129419
- const isLast = index >= path17.length;
129266
+ const isLast = index >= path18.length;
129420
129267
  name = !name && utils$1.isArray(target) ? target.length : name;
129421
129268
  if (isLast) {
129422
129269
  if (utils$1.hasOwnProp(target, name)) {
@@ -129429,7 +129276,7 @@ var require_axios = __commonJS({
129429
129276
  if (!target[name] || !utils$1.isObject(target[name])) {
129430
129277
  target[name] = [];
129431
129278
  }
129432
- const result = buildPath(path17, value, target[name], index);
129279
+ const result = buildPath(path18, value, target[name], index);
129433
129280
  if (result && utils$1.isArray(target[name])) {
129434
129281
  target[name] = arrayToObject(target[name]);
129435
129282
  }
@@ -130747,9 +130594,9 @@ var require_axios = __commonJS({
130747
130594
  auth = urlUsername + ":" + urlPassword;
130748
130595
  }
130749
130596
  auth && headers.delete("authorization");
130750
- let path17;
130597
+ let path18;
130751
130598
  try {
130752
- path17 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
130599
+ path18 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
130753
130600
  } catch (err) {
130754
130601
  const customErr = new Error(err.message);
130755
130602
  customErr.config = config2;
@@ -130759,7 +130606,7 @@ var require_axios = __commonJS({
130759
130606
  }
130760
130607
  headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
130761
130608
  const options = {
130762
- path: path17,
130609
+ path: path18,
130763
130610
  method,
130764
130611
  headers: headers.toJSON(),
130765
130612
  agents: {
@@ -130965,14 +130812,14 @@ var require_axios = __commonJS({
130965
130812
  var cookies = platform.hasStandardBrowserEnv ? (
130966
130813
  // Standard browser envs support document.cookie
130967
130814
  {
130968
- write(name, value, expires, path17, domain, secure, sameSite) {
130815
+ write(name, value, expires, path18, domain, secure, sameSite) {
130969
130816
  if (typeof document === "undefined") return;
130970
130817
  const cookie = [`${name}=${encodeURIComponent(value)}`];
130971
130818
  if (utils$1.isNumber(expires)) {
130972
130819
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
130973
130820
  }
130974
- if (utils$1.isString(path17)) {
130975
- cookie.push(`path=${path17}`);
130821
+ if (utils$1.isString(path18)) {
130822
+ cookie.push(`path=${path18}`);
130976
130823
  }
130977
130824
  if (utils$1.isString(domain)) {
130978
130825
  cookie.push(`domain=${domain}`);
@@ -134701,11 +134548,11 @@ var require_baseGet = __commonJS({
134701
134548
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/_baseGet.js"(exports, module) {
134702
134549
  var castPath = require_castPath();
134703
134550
  var toKey = require_toKey();
134704
- function baseGet(object, path17) {
134705
- path17 = castPath(path17, object);
134706
- var index = 0, length = path17.length;
134551
+ function baseGet(object, path18) {
134552
+ path18 = castPath(path18, object);
134553
+ var index = 0, length = path18.length;
134707
134554
  while (object != null && index < length) {
134708
- object = object[toKey(path17[index++])];
134555
+ object = object[toKey(path18[index++])];
134709
134556
  }
134710
134557
  return index && index == length ? object : void 0;
134711
134558
  }
@@ -134717,8 +134564,8 @@ var require_baseGet = __commonJS({
134717
134564
  var require_get2 = __commonJS({
134718
134565
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/get.js"(exports, module) {
134719
134566
  var baseGet = require_baseGet();
134720
- function get(object, path17, defaultValue) {
134721
- var result = object == null ? void 0 : baseGet(object, path17);
134567
+ function get(object, path18, defaultValue) {
134568
+ var result = object == null ? void 0 : baseGet(object, path18);
134722
134569
  return result === void 0 ? defaultValue : result;
134723
134570
  }
134724
134571
  module.exports = get;
@@ -134744,11 +134591,11 @@ var require_hasPath = __commonJS({
134744
134591
  var isIndex = require_isIndex();
134745
134592
  var isLength = require_isLength();
134746
134593
  var toKey = require_toKey();
134747
- function hasPath(object, path17, hasFunc) {
134748
- path17 = castPath(path17, object);
134749
- var index = -1, length = path17.length, result = false;
134594
+ function hasPath(object, path18, hasFunc) {
134595
+ path18 = castPath(path18, object);
134596
+ var index = -1, length = path18.length, result = false;
134750
134597
  while (++index < length) {
134751
- var key = toKey(path17[index]);
134598
+ var key = toKey(path18[index]);
134752
134599
  if (!(result = object != null && hasFunc(object, key))) {
134753
134600
  break;
134754
134601
  }
@@ -134769,8 +134616,8 @@ var require_hasIn = __commonJS({
134769
134616
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/hasIn.js"(exports, module) {
134770
134617
  var baseHasIn = require_baseHasIn();
134771
134618
  var hasPath = require_hasPath();
134772
- function hasIn(object, path17) {
134773
- return object != null && hasPath(object, path17, baseHasIn);
134619
+ function hasIn(object, path18) {
134620
+ return object != null && hasPath(object, path18, baseHasIn);
134774
134621
  }
134775
134622
  module.exports = hasIn;
134776
134623
  }
@@ -134788,13 +134635,13 @@ var require_baseMatchesProperty = __commonJS({
134788
134635
  var toKey = require_toKey();
134789
134636
  var COMPARE_PARTIAL_FLAG = 1;
134790
134637
  var COMPARE_UNORDERED_FLAG = 2;
134791
- function baseMatchesProperty(path17, srcValue) {
134792
- if (isKey(path17) && isStrictComparable(srcValue)) {
134793
- return matchesStrictComparable(toKey(path17), srcValue);
134638
+ function baseMatchesProperty(path18, srcValue) {
134639
+ if (isKey(path18) && isStrictComparable(srcValue)) {
134640
+ return matchesStrictComparable(toKey(path18), srcValue);
134794
134641
  }
134795
134642
  return function(object) {
134796
- var objValue = get(object, path17);
134797
- return objValue === void 0 && objValue === srcValue ? hasIn(object, path17) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
134643
+ var objValue = get(object, path18);
134644
+ return objValue === void 0 && objValue === srcValue ? hasIn(object, path18) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
134798
134645
  };
134799
134646
  }
134800
134647
  module.exports = baseMatchesProperty;
@@ -134817,9 +134664,9 @@ var require_baseProperty = __commonJS({
134817
134664
  var require_basePropertyDeep = __commonJS({
134818
134665
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/_basePropertyDeep.js"(exports, module) {
134819
134666
  var baseGet = require_baseGet();
134820
- function basePropertyDeep(path17) {
134667
+ function basePropertyDeep(path18) {
134821
134668
  return function(object) {
134822
- return baseGet(object, path17);
134669
+ return baseGet(object, path18);
134823
134670
  };
134824
134671
  }
134825
134672
  module.exports = basePropertyDeep;
@@ -134833,8 +134680,8 @@ var require_property = __commonJS({
134833
134680
  var basePropertyDeep = require_basePropertyDeep();
134834
134681
  var isKey = require_isKey();
134835
134682
  var toKey = require_toKey();
134836
- function property(path17) {
134837
- return isKey(path17) ? baseProperty(toKey(path17)) : basePropertyDeep(path17);
134683
+ function property(path18) {
134684
+ return isKey(path18) ? baseProperty(toKey(path18)) : basePropertyDeep(path18);
134838
134685
  }
134839
134686
  module.exports = property;
134840
134687
  }
@@ -134896,8 +134743,8 @@ var require_has = __commonJS({
134896
134743
  "node_modules/.pnpm/lodash@4.17.23/node_modules/lodash/has.js"(exports, module) {
134897
134744
  var baseHas = require_baseHas();
134898
134745
  var hasPath = require_hasPath();
134899
- function has(object, path17) {
134900
- return object != null && hasPath(object, path17, baseHas);
134746
+ function has(object, path18) {
134747
+ return object != null && hasPath(object, path18, baseHas);
134901
134748
  }
134902
134749
  module.exports = has;
134903
134750
  }
@@ -137171,14 +137018,14 @@ var require_baseSet = __commonJS({
137171
137018
  var isIndex = require_isIndex();
137172
137019
  var isObject = require_isObject();
137173
137020
  var toKey = require_toKey();
137174
- function baseSet(object, path17, value, customizer) {
137021
+ function baseSet(object, path18, value, customizer) {
137175
137022
  if (!isObject(object)) {
137176
137023
  return object;
137177
137024
  }
137178
- path17 = castPath(path17, object);
137179
- var index = -1, length = path17.length, lastIndex = length - 1, nested = object;
137025
+ path18 = castPath(path18, object);
137026
+ var index = -1, length = path18.length, lastIndex = length - 1, nested = object;
137180
137027
  while (nested != null && ++index < length) {
137181
- var key = toKey(path17[index]), newValue = value;
137028
+ var key = toKey(path18[index]), newValue = value;
137182
137029
  if (key === "__proto__" || key === "constructor" || key === "prototype") {
137183
137030
  return object;
137184
137031
  }
@@ -137186,7 +137033,7 @@ var require_baseSet = __commonJS({
137186
137033
  var objValue = nested[key];
137187
137034
  newValue = customizer ? customizer(objValue, key, nested) : void 0;
137188
137035
  if (newValue === void 0) {
137189
- newValue = isObject(objValue) ? objValue : isIndex(path17[index + 1]) ? [] : {};
137036
+ newValue = isObject(objValue) ? objValue : isIndex(path18[index + 1]) ? [] : {};
137190
137037
  }
137191
137038
  }
137192
137039
  assignValue(nested, key, newValue);
@@ -137207,9 +137054,9 @@ var require_basePickBy = __commonJS({
137207
137054
  function basePickBy(object, paths, predicate) {
137208
137055
  var index = -1, length = paths.length, result = {};
137209
137056
  while (++index < length) {
137210
- var path17 = paths[index], value = baseGet(object, path17);
137211
- if (predicate(value, path17)) {
137212
- baseSet(result, castPath(path17, object), value);
137057
+ var path18 = paths[index], value = baseGet(object, path18);
137058
+ if (predicate(value, path18)) {
137059
+ baseSet(result, castPath(path18, object), value);
137213
137060
  }
137214
137061
  }
137215
137062
  return result;
@@ -137224,8 +137071,8 @@ var require_basePick = __commonJS({
137224
137071
  var basePickBy = require_basePickBy();
137225
137072
  var hasIn = require_hasIn();
137226
137073
  function basePick(object, paths) {
137227
- return basePickBy(object, paths, function(value, path17) {
137228
- return hasIn(object, path17);
137074
+ return basePickBy(object, paths, function(value, path18) {
137075
+ return hasIn(object, path18);
137229
137076
  });
137230
137077
  }
137231
137078
  module.exports = basePick;
@@ -138279,15 +138126,15 @@ var require_parent_dummy_chains = __commonJS({
138279
138126
  var node2 = g.node(v);
138280
138127
  var edgeObj = node2.edgeObj;
138281
138128
  var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w);
138282
- var path17 = pathData.path;
138129
+ var path18 = pathData.path;
138283
138130
  var lca = pathData.lca;
138284
138131
  var pathIdx = 0;
138285
- var pathV = path17[pathIdx];
138132
+ var pathV = path18[pathIdx];
138286
138133
  var ascending = true;
138287
138134
  while (v !== edgeObj.w) {
138288
138135
  node2 = g.node(v);
138289
138136
  if (ascending) {
138290
- while ((pathV = path17[pathIdx]) !== lca && g.node(pathV).maxRank < node2.rank) {
138137
+ while ((pathV = path18[pathIdx]) !== lca && g.node(pathV).maxRank < node2.rank) {
138291
138138
  pathIdx++;
138292
138139
  }
138293
138140
  if (pathV === lca) {
@@ -138295,10 +138142,10 @@ var require_parent_dummy_chains = __commonJS({
138295
138142
  }
138296
138143
  }
138297
138144
  if (!ascending) {
138298
- while (pathIdx < path17.length - 1 && g.node(pathV = path17[pathIdx + 1]).minRank <= node2.rank) {
138145
+ while (pathIdx < path18.length - 1 && g.node(pathV = path18[pathIdx + 1]).minRank <= node2.rank) {
138299
138146
  pathIdx++;
138300
138147
  }
138301
- pathV = path17[pathIdx];
138148
+ pathV = path18[pathIdx];
138302
138149
  }
138303
138150
  g.setParent(v, pathV);
138304
138151
  v = g.successors(v)[0];
@@ -139801,10 +139648,10 @@ var require_dagre = __commonJS({
139801
139648
  var import_express10 = __toESM(require_express2(), 1);
139802
139649
  var import_cors = __toESM(require_lib3(), 1);
139803
139650
  init_config();
139804
- import fs12 from "node:fs";
139651
+ import fs13 from "node:fs";
139805
139652
  import { createServer } from "http";
139806
- import { fileURLToPath as fileURLToPath3 } from "node:url";
139807
- import path16 from "node:path";
139653
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
139654
+ import path17 from "node:path";
139808
139655
 
139809
139656
  // node_modules/.pnpm/socket.io@4.8.3/node_modules/socket.io/wrapper.mjs
139810
139657
  var import_dist = __toESM(require_dist2(), 1);
@@ -140682,8 +140529,8 @@ function pathspec(...paths) {
140682
140529
  cache.set(key, paths);
140683
140530
  return key;
140684
140531
  }
140685
- function isPathSpec(path17) {
140686
- return path17 instanceof String && cache.has(path17);
140532
+ function isPathSpec(path18) {
140533
+ return path18 instanceof String && cache.has(path18);
140687
140534
  }
140688
140535
  function toPaths(pathSpec) {
140689
140536
  return cache.get(pathSpec) || [];
@@ -140772,8 +140619,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
140772
140619
  function forEachLineWithContent(input, callback) {
140773
140620
  return toLinesWithContent(input, true).map((line) => callback(line));
140774
140621
  }
140775
- function folderExists(path17) {
140776
- return (0, import_file_exists.exists)(path17, import_file_exists.FOLDER);
140622
+ function folderExists(path18) {
140623
+ return (0, import_file_exists.exists)(path18, import_file_exists.FOLDER);
140777
140624
  }
140778
140625
  function append(target, item) {
140779
140626
  if (Array.isArray(target)) {
@@ -141177,8 +141024,8 @@ function checkIsRepoRootTask() {
141177
141024
  commands,
141178
141025
  format: "utf-8",
141179
141026
  onError,
141180
- parser(path17) {
141181
- return /^\.(git)?$/.test(path17.trim());
141027
+ parser(path18) {
141028
+ return /^\.(git)?$/.test(path18.trim());
141182
141029
  }
141183
141030
  };
141184
141031
  }
@@ -141612,11 +141459,11 @@ function parseGrep(grep) {
141612
141459
  const paths = /* @__PURE__ */ new Set();
141613
141460
  const results = {};
141614
141461
  forEachLineWithContent(grep, (input) => {
141615
- const [path17, line, preview] = input.split(NULL);
141616
- paths.add(path17);
141617
- (results[path17] = results[path17] || []).push({
141462
+ const [path18, line, preview] = input.split(NULL);
141463
+ paths.add(path18);
141464
+ (results[path18] = results[path18] || []).push({
141618
141465
  line: asNumber(line),
141619
- path: path17,
141466
+ path: path18,
141620
141467
  preview
141621
141468
  });
141622
141469
  });
@@ -142381,14 +142228,14 @@ var init_hash_object = __esm2({
142381
142228
  init_task();
142382
142229
  }
142383
142230
  });
142384
- function parseInit(bare, path17, text) {
142231
+ function parseInit(bare, path18, text) {
142385
142232
  const response = String(text).trim();
142386
142233
  let result;
142387
142234
  if (result = initResponseRegex.exec(response)) {
142388
- return new InitSummary(bare, path17, false, result[1]);
142235
+ return new InitSummary(bare, path18, false, result[1]);
142389
142236
  }
142390
142237
  if (result = reInitResponseRegex.exec(response)) {
142391
- return new InitSummary(bare, path17, true, result[1]);
142238
+ return new InitSummary(bare, path18, true, result[1]);
142392
142239
  }
142393
142240
  let gitDir = "";
142394
142241
  const tokens = response.split(" ");
@@ -142399,7 +142246,7 @@ function parseInit(bare, path17, text) {
142399
142246
  break;
142400
142247
  }
142401
142248
  }
142402
- return new InitSummary(bare, path17, /^re/i.test(response), gitDir);
142249
+ return new InitSummary(bare, path18, /^re/i.test(response), gitDir);
142403
142250
  }
142404
142251
  var InitSummary;
142405
142252
  var initResponseRegex;
@@ -142408,9 +142255,9 @@ var init_InitSummary = __esm2({
142408
142255
  "src/lib/responses/InitSummary.ts"() {
142409
142256
  "use strict";
142410
142257
  InitSummary = class {
142411
- constructor(bare, path17, existing, gitDir) {
142258
+ constructor(bare, path18, existing, gitDir) {
142412
142259
  this.bare = bare;
142413
- this.path = path17;
142260
+ this.path = path18;
142414
142261
  this.existing = existing;
142415
142262
  this.gitDir = gitDir;
142416
142263
  }
@@ -142422,7 +142269,7 @@ var init_InitSummary = __esm2({
142422
142269
  function hasBareCommand(command) {
142423
142270
  return command.includes(bareCommand);
142424
142271
  }
142425
- function initTask(bare = false, path17, customArgs) {
142272
+ function initTask(bare = false, path18, customArgs) {
142426
142273
  const commands = ["init", ...customArgs];
142427
142274
  if (bare && !hasBareCommand(commands)) {
142428
142275
  commands.splice(1, 0, bareCommand);
@@ -142431,7 +142278,7 @@ function initTask(bare = false, path17, customArgs) {
142431
142278
  commands,
142432
142279
  format: "utf-8",
142433
142280
  parser(text) {
142434
- return parseInit(commands.includes("--bare"), path17, text);
142281
+ return parseInit(commands.includes("--bare"), path18, text);
142435
142282
  }
142436
142283
  };
142437
142284
  }
@@ -143247,12 +143094,12 @@ var init_FileStatusSummary = __esm2({
143247
143094
  "use strict";
143248
143095
  fromPathRegex = /^(.+)\0(.+)$/;
143249
143096
  FileStatusSummary = class {
143250
- constructor(path17, index, working_dir) {
143251
- this.path = path17;
143097
+ constructor(path18, index, working_dir) {
143098
+ this.path = path18;
143252
143099
  this.index = index;
143253
143100
  this.working_dir = working_dir;
143254
143101
  if (index === "R" || working_dir === "R") {
143255
- const detail = fromPathRegex.exec(path17) || [null, path17, path17];
143102
+ const detail = fromPathRegex.exec(path18) || [null, path18, path18];
143256
143103
  this.from = detail[2] || "";
143257
143104
  this.path = detail[1] || "";
143258
143105
  }
@@ -143283,14 +143130,14 @@ function splitLine(result, lineStr) {
143283
143130
  default:
143284
143131
  return;
143285
143132
  }
143286
- function data(index, workingDir, path17) {
143133
+ function data(index, workingDir, path18) {
143287
143134
  const raw = `${index}${workingDir}`;
143288
143135
  const handler = parsers6.get(raw);
143289
143136
  if (handler) {
143290
- handler(result, path17);
143137
+ handler(result, path18);
143291
143138
  }
143292
143139
  if (raw !== "##" && raw !== "!!") {
143293
- result.files.push(new FileStatusSummary(path17, index, workingDir));
143140
+ result.files.push(new FileStatusSummary(path18, index, workingDir));
143294
143141
  }
143295
143142
  }
143296
143143
  }
@@ -143642,9 +143489,9 @@ var init_simple_git_api = __esm2({
143642
143489
  next
143643
143490
  );
143644
143491
  }
143645
- hashObject(path17, write) {
143492
+ hashObject(path18, write) {
143646
143493
  return this._runTask(
143647
- hashObjectTask(path17, write === true),
143494
+ hashObjectTask(path18, write === true),
143648
143495
  trailingFunctionArgument(arguments)
143649
143496
  );
143650
143497
  }
@@ -143998,8 +143845,8 @@ var init_branch = __esm2({
143998
143845
  }
143999
143846
  });
144000
143847
  function toPath(input) {
144001
- const path17 = input.trim().replace(/^["']|["']$/g, "");
144002
- return path17 && normalize(path17);
143848
+ const path18 = input.trim().replace(/^["']|["']$/g, "");
143849
+ return path18 && normalize(path18);
144003
143850
  }
144004
143851
  var parseCheckIgnore;
144005
143852
  var init_CheckIgnore = __esm2({
@@ -144284,8 +144131,8 @@ __export2(sub_module_exports, {
144284
144131
  subModuleTask: () => subModuleTask,
144285
144132
  updateSubModuleTask: () => updateSubModuleTask
144286
144133
  });
144287
- function addSubModuleTask(repo, path17) {
144288
- return subModuleTask(["add", repo, path17]);
144134
+ function addSubModuleTask(repo, path18) {
144135
+ return subModuleTask(["add", repo, path18]);
144289
144136
  }
144290
144137
  function initSubModuleTask(customArgs) {
144291
144138
  return subModuleTask(["init", ...customArgs]);
@@ -144599,8 +144446,8 @@ var require_git = __commonJS2({
144599
144446
  }
144600
144447
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
144601
144448
  };
144602
- Git2.prototype.submoduleAdd = function(repo, path17, then) {
144603
- return this._runTask(addSubModuleTask2(repo, path17), trailingFunctionArgument2(arguments));
144449
+ Git2.prototype.submoduleAdd = function(repo, path18, then) {
144450
+ return this._runTask(addSubModuleTask2(repo, path18), trailingFunctionArgument2(arguments));
144604
144451
  };
144605
144452
  Git2.prototype.submoduleUpdate = function(args, then) {
144606
144453
  return this._runTask(
@@ -145378,7 +145225,7 @@ var repos_default = router;
145378
145225
 
145379
145226
  // apps/server/src/routes/analyses.ts
145380
145227
  var import_express2 = __toESM(require_express2(), 1);
145381
- import path14 from "node:path";
145228
+ import path15 from "node:path";
145382
145229
 
145383
145230
  // apps/server/src/config/current-project.ts
145384
145231
  function resolveProjectForRequest(slug) {
@@ -145391,15 +145238,188 @@ function resolveProjectForRequest(slug) {
145391
145238
  return entry;
145392
145239
  }
145393
145240
 
145394
- // apps/server/src/commands/analyze-in-process.ts
145395
- init_analysis_store();
145241
+ // apps/server/src/lib/analysis-store.ts
145242
+ import fs7 from "node:fs";
145243
+ import path6 from "node:path";
145244
+
145245
+ // apps/server/src/lib/atomic-write.ts
145246
+ import fs6 from "node:fs";
145247
+ import path5 from "node:path";
145248
+ function atomicWriteJson(targetPath, data) {
145249
+ fs6.mkdirSync(path5.dirname(targetPath), { recursive: true });
145250
+ const tmp = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
145251
+ fs6.writeFileSync(tmp, JSON.stringify(data, null, 2));
145252
+ fs6.renameSync(tmp, targetPath);
145253
+ }
145254
+ var LOCK_FILENAME = ".analyze.lock";
145255
+ function lockPath(repoPath) {
145256
+ return path5.join(repoPath, ".truecourse", LOCK_FILENAME);
145257
+ }
145258
+ var AnalyzeLockError = class extends Error {
145259
+ constructor(repoPath, ownerPid) {
145260
+ const who = ownerPid != null ? ` (held by pid ${ownerPid})` : "";
145261
+ super(
145262
+ `Another analyze is already running for ${repoPath}${who}. If you're sure no analyze is in progress, remove ${lockPath(repoPath)} and retry.`
145263
+ );
145264
+ this.name = "AnalyzeLockError";
145265
+ }
145266
+ };
145267
+ function acquireAnalyzeLock(repoPath) {
145268
+ const file = lockPath(repoPath);
145269
+ fs6.mkdirSync(path5.dirname(file), { recursive: true });
145270
+ try {
145271
+ const fd = fs6.openSync(file, "wx");
145272
+ fs6.writeSync(fd, `${process.pid}
145273
+ ${(/* @__PURE__ */ new Date()).toISOString()}
145274
+ `);
145275
+ fs6.closeSync(fd);
145276
+ } catch (err) {
145277
+ if (err.code === "EEXIST") {
145278
+ let owner = null;
145279
+ try {
145280
+ owner = parseInt(fs6.readFileSync(file, "utf-8").split("\n")[0], 10) || null;
145281
+ } catch {
145282
+ }
145283
+ throw new AnalyzeLockError(repoPath, owner);
145284
+ }
145285
+ throw err;
145286
+ }
145287
+ }
145288
+ function releaseAnalyzeLock(repoPath) {
145289
+ try {
145290
+ fs6.unlinkSync(lockPath(repoPath));
145291
+ } catch (err) {
145292
+ if (err.code !== "ENOENT") throw err;
145293
+ }
145294
+ }
145295
+
145296
+ // apps/server/src/lib/analysis-store.ts
145297
+ var TRUECOURSE_DIR2 = ".truecourse";
145298
+ var ANALYSES_DIR = "analyses";
145299
+ var LATEST_FILE = "LATEST.json";
145300
+ var HISTORY_FILE = "history.json";
145301
+ var DIFF_FILE = "diff.json";
145302
+ function storeDir(repoPath) {
145303
+ return path6.join(repoPath, TRUECOURSE_DIR2);
145304
+ }
145305
+ function analysesDir(repoPath) {
145306
+ return path6.join(storeDir(repoPath), ANALYSES_DIR);
145307
+ }
145308
+ function analysisFilePath(repoPath, filename) {
145309
+ return path6.join(analysesDir(repoPath), filename);
145310
+ }
145311
+ function latestPath(repoPath) {
145312
+ return path6.join(storeDir(repoPath), LATEST_FILE);
145313
+ }
145314
+ function historyPath(repoPath) {
145315
+ return path6.join(storeDir(repoPath), HISTORY_FILE);
145316
+ }
145317
+ function diffPath(repoPath) {
145318
+ return path6.join(storeDir(repoPath), DIFF_FILE);
145319
+ }
145320
+ function buildAnalysisFilename(analysisId, createdAt) {
145321
+ const iso = createdAt.replace(/[:.]/g, "-").replace(/-\d{3}Z$/, "Z");
145322
+ const shortId = analysisId.replace(/-/g, "").slice(0, 8);
145323
+ return `${iso}_${shortId}.json`;
145324
+ }
145325
+ var latestCache = /* @__PURE__ */ new Map();
145326
+ function readLatest(repoPath) {
145327
+ const file = latestPath(repoPath);
145328
+ let mtime;
145329
+ try {
145330
+ mtime = fs7.statSync(file).mtimeMs;
145331
+ } catch (err) {
145332
+ if (err.code === "ENOENT") {
145333
+ latestCache.delete(repoPath);
145334
+ return null;
145335
+ }
145336
+ throw err;
145337
+ }
145338
+ const cached = latestCache.get(repoPath);
145339
+ if (cached && cached.mtime === mtime) return cached.data;
145340
+ const data = JSON.parse(fs7.readFileSync(file, "utf-8"));
145341
+ latestCache.set(repoPath, { mtime, data });
145342
+ return data;
145343
+ }
145344
+ function writeLatest(repoPath, latest) {
145345
+ atomicWriteJson(latestPath(repoPath), latest);
145346
+ latestCache.delete(repoPath);
145347
+ }
145348
+ function deleteLatest(repoPath) {
145349
+ try {
145350
+ fs7.unlinkSync(latestPath(repoPath));
145351
+ } catch (err) {
145352
+ if (err.code !== "ENOENT") throw err;
145353
+ }
145354
+ latestCache.delete(repoPath);
145355
+ }
145356
+ function writeAnalysis(repoPath, snapshot) {
145357
+ const filename = buildAnalysisFilename(snapshot.id, snapshot.createdAt);
145358
+ atomicWriteJson(analysisFilePath(repoPath, filename), snapshot);
145359
+ return { filename, snapshot };
145360
+ }
145361
+ function readAnalysis(repoPath, filename) {
145362
+ const file = analysisFilePath(repoPath, filename);
145363
+ if (!fs7.existsSync(file)) return null;
145364
+ return JSON.parse(fs7.readFileSync(file, "utf-8"));
145365
+ }
145366
+ function listAnalyses(repoPath) {
145367
+ const dir = analysesDir(repoPath);
145368
+ if (!fs7.existsSync(dir)) return [];
145369
+ return fs7.readdirSync(dir).filter((name) => name.endsWith(".json")).sort();
145370
+ }
145371
+ function findAnalysisFilename(repoPath, analysisId) {
145372
+ for (const name of listAnalyses(repoPath).reverse()) {
145373
+ const snap = readAnalysis(repoPath, name);
145374
+ if (snap?.id === analysisId) return name;
145375
+ }
145376
+ return null;
145377
+ }
145378
+ function deleteAnalysis(repoPath, filename) {
145379
+ try {
145380
+ fs7.unlinkSync(analysisFilePath(repoPath, filename));
145381
+ } catch (err) {
145382
+ if (err.code !== "ENOENT") throw err;
145383
+ }
145384
+ }
145385
+ function readHistory(repoPath) {
145386
+ const file = historyPath(repoPath);
145387
+ if (!fs7.existsSync(file)) return { analyses: [] };
145388
+ return JSON.parse(fs7.readFileSync(file, "utf-8"));
145389
+ }
145390
+ function appendHistory(repoPath, entry) {
145391
+ const history = readHistory(repoPath);
145392
+ history.analyses.push(entry);
145393
+ atomicWriteJson(historyPath(repoPath), history);
145394
+ }
145395
+ function removeFromHistory(repoPath, analysisId) {
145396
+ const history = readHistory(repoPath);
145397
+ const next = history.analyses.filter((a) => a.id !== analysisId);
145398
+ if (next.length === history.analyses.length) return;
145399
+ atomicWriteJson(historyPath(repoPath), { analyses: next });
145400
+ }
145401
+ function readDiff(repoPath) {
145402
+ const file = diffPath(repoPath);
145403
+ if (!fs7.existsSync(file)) return null;
145404
+ return JSON.parse(fs7.readFileSync(file, "utf-8"));
145405
+ }
145406
+ function writeDiff(repoPath, diff) {
145407
+ atomicWriteJson(diffPath(repoPath), diff);
145408
+ }
145409
+ function deleteDiff(repoPath) {
145410
+ try {
145411
+ fs7.unlinkSync(diffPath(repoPath));
145412
+ } catch (err) {
145413
+ if (err.code !== "ENOENT") throw err;
145414
+ }
145415
+ }
145396
145416
 
145397
145417
  // apps/server/src/commands/analyze-core.ts
145398
145418
  init_logger();
145399
145419
  import { randomUUID as randomUUID6 } from "node:crypto";
145400
145420
 
145401
145421
  // apps/server/src/services/analyzer.service.ts
145402
- import path10 from "node:path";
145422
+ import path11 from "node:path";
145403
145423
  init_logger();
145404
145424
  init_dist2();
145405
145425
  function runDeterministicModuleChecks(result, enabledDeterministic) {
@@ -145467,7 +145487,7 @@ async function runAnalysis(repoPath, _branch, onProgress, options) {
145467
145487
  const statusResult = await git.status();
145468
145488
  hasChanges = !statusResult.isClean();
145469
145489
  const gitRoot = (await git.revparse(["--show-toplevel"])).trim();
145470
- isSubdirectory = path10.resolve(repoPath) !== path10.resolve(gitRoot);
145490
+ isSubdirectory = path11.resolve(repoPath) !== path11.resolve(gitRoot);
145471
145491
  }
145472
145492
  if (hasChanges && !options?.skipStash && !isSubdirectory && git) {
145473
145493
  onProgress({ step: "stash", percent: 2, detail: "Stashing pending changes to analyze committed state..." });
@@ -145481,6 +145501,7 @@ async function runAnalysis(repoPath, _branch, onProgress, options) {
145481
145501
  try {
145482
145502
  onProgress({ step: "discover", percent: 10, detail: "Discovering files..." });
145483
145503
  const analyzer = await Promise.resolve().then(() => (init_dist2(), dist_exports));
145504
+ await analyzer.initParsers();
145484
145505
  const files = await analyzer.discoverFiles(repoPath);
145485
145506
  onProgress({
145486
145507
  step: "discover",
@@ -145797,7 +145818,6 @@ function buildGraph(result) {
145797
145818
  // apps/server/src/services/flow.service.ts
145798
145819
  init_logger();
145799
145820
  init_dist2();
145800
- init_analysis_store();
145801
145821
  import { randomUUID as randomUUID3 } from "node:crypto";
145802
145822
  function detectFlows(result) {
145803
145823
  const dbTypeMap = /* @__PURE__ */ new Map();
@@ -145991,7 +146011,7 @@ function getFlowFromLatest(repoPath, flowId) {
145991
146011
  return latest?.graph.flows.find((f2) => f2.id === flowId) ?? null;
145992
146012
  }
145993
146013
  var SEVERITY_ORDER = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
145994
- function computeFlowSeverities(latest) {
146014
+ function computeFlowSeverities(graph, violations) {
145995
146015
  const nameSev = /* @__PURE__ */ new Map();
145996
146016
  const bump = (key, sev) => {
145997
146017
  const existing = nameSev.get(key);
@@ -145999,9 +146019,9 @@ function computeFlowSeverities(latest) {
145999
146019
  nameSev.set(key, sev);
146000
146020
  }
146001
146021
  };
146002
- const moduleIdToName = new Map(latest.graph.modules.map((m) => [m.id, m.name]));
146003
- const methodIdToName = new Map(latest.graph.methods.map((m) => [m.id, m.name]));
146004
- for (const v of latest.violations) {
146022
+ const moduleIdToName = new Map(graph.modules.map((m) => [m.id, m.name]));
146023
+ const methodIdToName = new Map(graph.methods.map((m) => [m.id, m.name]));
146024
+ for (const v of violations) {
146005
146025
  if (v.targetMethodId) {
146006
146026
  const name = methodIdToName.get(v.targetMethodId);
146007
146027
  if (name) bump(`method:${name}`, v.severity);
@@ -146012,7 +146032,7 @@ function computeFlowSeverities(latest) {
146012
146032
  }
146013
146033
  }
146014
146034
  const out = {};
146015
- for (const flow of latest.graph.flows) {
146035
+ for (const flow of graph.flows) {
146016
146036
  let highest = null;
146017
146037
  for (const step of flow.steps) {
146018
146038
  for (const sev of [nameSev.get(`method:${step.targetMethod}`), nameSev.get(`module:${step.targetModule}`)]) {
@@ -146061,8 +146081,8 @@ async function enrichFlowWithLLM(repoPath, flowId) {
146061
146081
  // apps/server/src/services/violation-pipeline.service.ts
146062
146082
  init_dist2();
146063
146083
  import { randomUUID as randomUUID5 } from "node:crypto";
146064
- import fs8 from "node:fs";
146065
- import path11 from "node:path";
146084
+ import fs9 from "node:fs";
146085
+ import path12 from "node:path";
146066
146086
 
146067
146087
  // apps/server/src/services/rules.service.ts
146068
146088
  init_dist2();
@@ -146869,6 +146889,7 @@ function compareDeterministicViolations(current, previous) {
146869
146889
  return { newDetections, unchangedDetections, resolvedDetections };
146870
146890
  }
146871
146891
  async function runViolationPipeline(input) {
146892
+ await initParsers();
146872
146893
  const {
146873
146894
  repoPath,
146874
146895
  analysisId,
@@ -146910,27 +146931,33 @@ async function runViolationPipeline(input) {
146910
146931
  const enabledLlmCodeRules = enableLlmRules !== false ? allRules.filter((r) => (r.domain ? codeDomains.has(r.domain) : r.category === "code") && r.type === "llm" && r.prompt) : [];
146911
146932
  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 }));
146912
146933
  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 }));
146913
- const filesToScan = changedFileSet ? [...changedFileSet].map((relPath) => ({ filePath: relPath, resolve: true })) : (result.fileAnalyses || []).map((fa) => ({ filePath: fa.filePath, resolve: !path11.isAbsolute(fa.filePath) }));
146934
+ const filesToScan = changedFileSet ? [...changedFileSet].map((relPath) => ({ filePath: relPath, resolve: true })) : (result.fileAnalyses || []).map((fa) => ({ filePath: fa.filePath, resolve: !path12.isAbsolute(fa.filePath) }));
146914
146935
  const hasLlm = enabledLlm.length > 0;
146915
146936
  if (hasLlm) tracker?.start("scan", "Reading files...");
146916
146937
  const fileContents = /* @__PURE__ */ new Map();
146938
+ const totalToScan = filesToScan.length;
146939
+ let scanned = 0;
146917
146940
  for (const { filePath, resolve: resolve7 } of filesToScan) {
146918
146941
  try {
146919
146942
  const lang = detectLanguage(filePath);
146920
146943
  if (!lang) continue;
146921
- const absPath = resolve7 ? path11.resolve(repoPath, filePath) : path11.isAbsolute(filePath) ? filePath : path11.join(repoPath, filePath);
146922
- if (!fs8.existsSync(absPath)) continue;
146923
- const content = fs8.readFileSync(absPath, "utf-8");
146944
+ const absPath = resolve7 ? path12.resolve(repoPath, filePath) : path12.isAbsolute(filePath) ? filePath : path12.join(repoPath, filePath);
146945
+ if (!fs9.existsSync(absPath)) continue;
146946
+ const content = fs9.readFileSync(absPath, "utf-8");
146924
146947
  const lineCount = content.split("\n").length;
146925
146948
  fileContents.set(changedFileSet ? absPath : filePath, { content, lineCount });
146926
146949
  } catch {
146927
146950
  }
146951
+ scanned++;
146952
+ if (hasLlm && (scanned % 20 === 0 || scanned === totalToScan)) {
146953
+ tracker?.detail("scan", `Reading ${scanned}/${totalToScan} files...`);
146954
+ }
146928
146955
  }
146929
146956
  let typeQuery;
146930
146957
  const enabledCodeKeys = new Set(enabledCodeRules.filter((r) => r.type === "deterministic" && r.enabled).map((r) => r.key));
146931
146958
  if (hasTypeAwareVisitors(enabledCodeKeys)) {
146932
146959
  const tsFiles = filesToScan.filter(({ filePath: fp }) => /\.(ts|tsx|js|jsx)$/.test(fp)).map(
146933
- ({ filePath: fp, resolve: res }) => res ? path11.resolve(repoPath, fp) : path11.isAbsolute(fp) ? fp : path11.join(repoPath, fp)
146960
+ ({ filePath: fp, resolve: res }) => res ? path12.resolve(repoPath, fp) : path12.isAbsolute(fp) ? fp : path12.join(repoPath, fp)
146934
146961
  );
146935
146962
  if (tsFiles.length > 0) {
146936
146963
  const scoped = buildScopedCompilerOptions(repoPath);
@@ -147004,7 +147031,7 @@ async function runViolationPipeline(input) {
147004
147031
  try {
147005
147032
  const lang = detectLanguage(filePath);
147006
147033
  if (!lang) continue;
147007
- const absPath = resolve7 ? path11.resolve(repoPath, filePath) : path11.isAbsolute(filePath) ? filePath : path11.join(repoPath, filePath);
147034
+ const absPath = resolve7 ? path12.resolve(repoPath, filePath) : path12.isAbsolute(filePath) ? filePath : path12.join(repoPath, filePath);
147008
147035
  const key = changedFileSet ? absPath : filePath;
147009
147036
  const fc = fileContents.get(key);
147010
147037
  if (!fc) continue;
@@ -147017,11 +147044,11 @@ async function runViolationPipeline(input) {
147017
147044
  }
147018
147045
  log.info(`[Pipeline] Code scan: ${allCodeViolations.length} violations from ${filesToScan.length} files (${enabledCodeRules.length} det rules, ${enabledLlmCodeRules.length} LLM rules)`);
147019
147046
  if (enabledCodeRules.some((r) => r.key === "bugs/deterministic/invalid-pyproject-toml")) {
147020
- const pyprojectPath = path11.join(repoPath, "pyproject.toml");
147021
- if (fs8.existsSync(pyprojectPath)) {
147047
+ const pyprojectPath = path12.join(repoPath, "pyproject.toml");
147048
+ if (fs9.existsSync(pyprojectPath)) {
147022
147049
  try {
147023
147050
  const { checkPyprojectToml: checkPyprojectToml2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
147024
- const content = fs8.readFileSync(pyprojectPath, "utf-8");
147051
+ const content = fs9.readFileSync(pyprojectPath, "utf-8");
147025
147052
  const tomlViolations = checkPyprojectToml2(pyprojectPath, content);
147026
147053
  allCodeViolations.push(...tomlViolations);
147027
147054
  } catch {
@@ -147824,7 +147851,7 @@ function processLlmCodeViolations(codeResult, validFilePaths, fileContents, allC
147824
147851
  for (const v of codeResult.violations) {
147825
147852
  let filePath = v.filePath;
147826
147853
  if (!validFilePaths.has(filePath)) {
147827
- const resolved = path11.resolve(repoPath, filePath);
147854
+ const resolved = path12.resolve(repoPath, filePath);
147828
147855
  if (validFilePaths.has(resolved)) {
147829
147856
  filePath = resolved;
147830
147857
  } else {
@@ -147877,8 +147904,6 @@ function toUsageRecords(records) {
147877
147904
  }
147878
147905
 
147879
147906
  // apps/server/src/commands/analyze-core.ts
147880
- init_analysis_store();
147881
- init_atomic_write();
147882
147907
  async function analyzeCore(project, options) {
147883
147908
  try {
147884
147909
  acquireAnalyzeLock(project.path);
@@ -148054,8 +148079,7 @@ function enforceLocationInvariant(violations) {
148054
148079
 
148055
148080
  // apps/server/src/commands/analyze-persist.ts
148056
148081
  init_logger();
148057
- import path12 from "node:path";
148058
- init_analysis_store();
148082
+ import path13 from "node:path";
148059
148083
  function persistFullAnalysis(project, core, startedAt) {
148060
148084
  const filename = buildAnalysisFilename(core.analysisId, core.now);
148061
148085
  const snapshot = {
@@ -148190,8 +148214,8 @@ function buildDiffSnapshot(repoPath, core, baseline) {
148190
148214
  const newViolations = pipelineResult.added.map(denormalize);
148191
148215
  const latestById = new Map(baseline.violations.map((v) => [v.id, v]));
148192
148216
  const resolvedViolations = pipelineResult.resolvedRefs.map((r) => latestById.get(r.id)).filter((v) => !!v);
148193
- const changedAbs = new Set(changedFiles.map((c) => path12.resolve(repoPath, c.path)));
148194
- const matchesChanged = (p) => !!p && (changedAbs.has(p) || changedAbs.has(path12.resolve(repoPath, p)));
148217
+ const changedAbs = new Set(changedFiles.map((c) => path13.resolve(repoPath, c.path)));
148218
+ const matchesChanged = (p) => !!p && (changedAbs.has(p) || changedAbs.has(path13.resolve(repoPath, p)));
148195
148219
  const affectedModules = graph.modules.filter((m) => matchesChanged(m.filePath));
148196
148220
  const affectedModuleIdSet = new Set(affectedModules.map((m) => m.id));
148197
148221
  const serviceNameById = new Map(graph.services.map((s) => [s.id, s.name]));
@@ -148275,8 +148299,8 @@ init_analysis_registry();
148275
148299
  init_provider();
148276
148300
 
148277
148301
  // apps/server/src/services/telemetry.service.ts
148278
- import fs9 from "node:fs";
148279
- import path13 from "node:path";
148302
+ import fs10 from "node:fs";
148303
+ import path14 from "node:path";
148280
148304
  import os3 from "node:os";
148281
148305
  import crypto from "node:crypto";
148282
148306
 
@@ -149015,8 +149039,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname6(proce
149015
149039
  return decodedFile;
149016
149040
  };
149017
149041
  }
149018
- function normalizeWindowsPath(path17) {
149019
- return path17.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
149042
+ function normalizeWindowsPath(path18) {
149043
+ return path18.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
149020
149044
  }
149021
149045
  var ReduceableCache = class {
149022
149046
  constructor(_maxSize) {
@@ -149095,9 +149119,9 @@ async function addSourceContext(frames) {
149095
149119
  LRU_FILE_CONTENTS_CACHE.reduce();
149096
149120
  return frames;
149097
149121
  }
149098
- function getContextLinesFromFile(path17, ranges, output) {
149122
+ function getContextLinesFromFile(path18, ranges, output) {
149099
149123
  return new Promise((resolve7) => {
149100
- const stream = createReadStream(path17);
149124
+ const stream = createReadStream(path18);
149101
149125
  const lineReaded = createInterface({
149102
149126
  input: stream
149103
149127
  });
@@ -149115,7 +149139,7 @@ function getContextLinesFromFile(path17, ranges, output) {
149115
149139
  let rangeStart = range2[0];
149116
149140
  let rangeEnd = range2[1];
149117
149141
  function onStreamError() {
149118
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path17, 1);
149142
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path18, 1);
149119
149143
  lineReaded.close();
149120
149144
  lineReaded.removeAllListeners();
149121
149145
  destroyStreamAndResolve();
@@ -149192,8 +149216,8 @@ function clearLineContext(frame) {
149192
149216
  delete frame.context_line;
149193
149217
  delete frame.post_context;
149194
149218
  }
149195
- function shouldSkipContextLinesForFile(path17) {
149196
- return path17.startsWith("node:") || path17.endsWith(".min.js") || path17.endsWith(".min.cjs") || path17.endsWith(".min.mjs") || path17.startsWith("data:");
149219
+ function shouldSkipContextLinesForFile(path18) {
149220
+ return path18.startsWith("node:") || path18.endsWith(".min.js") || path18.endsWith(".min.cjs") || path18.endsWith(".min.mjs") || path18.startsWith("data:");
149197
149221
  }
149198
149222
  function shouldSkipContextLinesForFrame(frame) {
149199
149223
  if (frame.lineno !== void 0 && frame.lineno > MAX_CONTEXTLINES_LINENO) {
@@ -152065,12 +152089,12 @@ var DEFAULT_CONFIG = {
152065
152089
  var POSTHOG_API_KEY = "phc_ys9Ykf49KmNqAC3fhq3jugTejc4BDqyKqRS8qRoYZYew";
152066
152090
  var TOOL_VERSION = "0.2.2";
152067
152091
  function getTelemetryConfigPath() {
152068
- return path13.join(os3.homedir(), ".truecourse", "telemetry.json");
152092
+ return path14.join(os3.homedir(), ".truecourse", "telemetry.json");
152069
152093
  }
152070
152094
  function readTelemetryConfig() {
152071
152095
  const configPath = getTelemetryConfigPath();
152072
152096
  try {
152073
- const raw = fs9.readFileSync(configPath, "utf-8");
152097
+ const raw = fs10.readFileSync(configPath, "utf-8");
152074
152098
  const parsed = JSON.parse(raw);
152075
152099
  const config2 = { ...DEFAULT_CONFIG, ...parsed };
152076
152100
  if (!config2.anonymousId) {
@@ -152089,17 +152113,17 @@ function readTelemetryConfig() {
152089
152113
  }
152090
152114
  function writeTelemetryConfig(partial) {
152091
152115
  const configPath = getTelemetryConfigPath();
152092
- const dir = path13.dirname(configPath);
152093
- fs9.mkdirSync(dir, { recursive: true });
152116
+ const dir = path14.dirname(configPath);
152117
+ fs10.mkdirSync(dir, { recursive: true });
152094
152118
  let current;
152095
152119
  try {
152096
- const raw = fs9.readFileSync(configPath, "utf-8");
152120
+ const raw = fs10.readFileSync(configPath, "utf-8");
152097
152121
  current = { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
152098
152122
  } catch {
152099
152123
  current = { ...DEFAULT_CONFIG };
152100
152124
  }
152101
152125
  const merged = { ...current, ...partial };
152102
- fs9.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
152126
+ fs10.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
152103
152127
  }
152104
152128
  var posthogClient = null;
152105
152129
  function isTelemetryEnabled() {
@@ -152158,7 +152182,6 @@ function trackEvent(event, properties) {
152158
152182
  }
152159
152183
 
152160
152184
  // apps/server/src/services/violation-query.service.ts
152161
- init_analysis_store();
152162
152185
  var SEVERITY_ORDER2 = {
152163
152186
  critical: 0,
152164
152187
  high: 1,
@@ -152169,18 +152192,23 @@ var SEVERITY_ORDER2 = {
152169
152192
  function listViolations(repoPath, options = {}) {
152170
152193
  const latest = readLatest(repoPath);
152171
152194
  if (!latest) return { violations: [], total: 0 };
152172
- if (options.analysisId && latest.analysis.id !== options.analysisId) {
152173
- return { violations: [], total: 0 };
152195
+ let violations;
152196
+ if (!options.analysisId || latest.analysis.id === options.analysisId) {
152197
+ violations = latest.violations;
152198
+ } else {
152199
+ const historical = readActiveViolationsAt(repoPath, options.analysisId);
152200
+ if (!historical) return { violations: [], total: 0 };
152201
+ violations = historical;
152174
152202
  }
152175
152203
  const statusMode = options.status ?? "active";
152176
152204
  let filtered;
152177
152205
  if (statusMode === "resolved") {
152178
- filtered = latest.violations.filter((v) => v.status === "resolved");
152206
+ filtered = violations.filter((v) => v.status === "resolved");
152179
152207
  } else if (statusMode === "all") {
152180
- filtered = latest.violations;
152208
+ filtered = violations;
152181
152209
  } else {
152182
152210
  const active = ["new", "unchanged"];
152183
- filtered = latest.violations.filter((v) => active.includes(v.status));
152211
+ filtered = violations.filter((v) => active.includes(v.status));
152184
152212
  }
152185
152213
  if (options.filePath) {
152186
152214
  const absPath = options.filePath.startsWith("/") ? options.filePath : `${repoPath}/${options.filePath}`;
@@ -152188,6 +152216,10 @@ function listViolations(repoPath, options = {}) {
152188
152216
  (v) => v.type === "code" && (v.filePath === absPath || v.filePath === options.filePath)
152189
152217
  );
152190
152218
  }
152219
+ if (options.severity !== void 0) {
152220
+ const allowed = (Array.isArray(options.severity) ? options.severity : [options.severity]).map((s) => s.toLowerCase());
152221
+ filtered = filtered.filter((v) => allowed.includes(v.severity.toLowerCase()));
152222
+ }
152191
152223
  filtered.sort((a, b) => {
152192
152224
  const sa = SEVERITY_ORDER2[a.severity] ?? 5;
152193
152225
  const sb = SEVERITY_ORDER2[b.severity] ?? 5;
@@ -152200,6 +152232,69 @@ function listViolations(repoPath, options = {}) {
152200
152232
  const paged = limit > 0 ? filtered.slice(offset, offset + limit) : filtered;
152201
152233
  return { violations: paged, total };
152202
152234
  }
152235
+ function readActiveViolationsAt(repoPath, analysisId) {
152236
+ const targetFile = findAnalysisFilename(repoPath, analysisId);
152237
+ if (!targetFile) return null;
152238
+ const targetSnap = readAnalysis(repoPath, targetFile);
152239
+ if (!targetSnap) return null;
152240
+ const files = listAnalyses(repoPath);
152241
+ const targetIdx = files.indexOf(targetFile);
152242
+ if (targetIdx === -1) return null;
152243
+ const active = /* @__PURE__ */ new Map();
152244
+ for (let i = 0; i <= targetIdx; i++) {
152245
+ const snap = readAnalysis(repoPath, files[i]);
152246
+ if (!snap) continue;
152247
+ for (const r of snap.violations.resolved) active.delete(r.id);
152248
+ for (const a of snap.violations.added) active.set(a.id, a);
152249
+ }
152250
+ return [...active.values()].map(denormalizeAgainst(targetSnap.graph));
152251
+ }
152252
+ function denormalizeAgainst(graph) {
152253
+ const serviceById = new Map(graph.services.map((s) => [s.id, s.name]));
152254
+ const moduleById = new Map(graph.modules.map((m) => [m.id, m.name]));
152255
+ const methodById = new Map(graph.methods.map((m) => [m.id, m.name]));
152256
+ const databaseById = new Map(graph.databases.map((d) => [d.id, d.name]));
152257
+ return (v) => ({
152258
+ ...v,
152259
+ targetServiceName: v.targetServiceId ? serviceById.get(v.targetServiceId) ?? null : null,
152260
+ targetModuleName: v.targetModuleId ? moduleById.get(v.targetModuleId) ?? null : null,
152261
+ targetMethodName: v.targetMethodId ? methodById.get(v.targetMethodId) ?? null : null,
152262
+ targetDatabaseName: v.targetDatabaseId ? databaseById.get(v.targetDatabaseId) ?? null : null
152263
+ });
152264
+ }
152265
+ function readActiveViolationsForAnalysisId(repoPath, analysisId) {
152266
+ const latest = readLatest(repoPath);
152267
+ if (!analysisId || latest && latest.analysis.id === analysisId) {
152268
+ if (!latest) return null;
152269
+ return latest.violations.filter((v) => v.status === "new" || v.status === "unchanged");
152270
+ }
152271
+ const diff = readDiff(repoPath);
152272
+ if (diff && diff.id === analysisId) {
152273
+ if (!latest) return null;
152274
+ const resolvedIds = new Set(diff.resolvedViolations.map((v) => v.id));
152275
+ const carried = latest.violations.filter(
152276
+ (v) => !resolvedIds.has(v.id) && (v.status === "new" || v.status === "unchanged")
152277
+ );
152278
+ return [...carried, ...diff.newViolations];
152279
+ }
152280
+ return readActiveViolationsAt(repoPath, analysisId);
152281
+ }
152282
+ function resolveGraphForAnalysisId(repoPath, analysisId) {
152283
+ const latest = readLatest(repoPath);
152284
+ if (!analysisId || latest && latest.analysis.id === analysisId) {
152285
+ if (!latest) return null;
152286
+ return { graph: latest.graph, source: "latest", analysisId: latest.analysis.id };
152287
+ }
152288
+ const diff = readDiff(repoPath);
152289
+ if (diff && diff.id === analysisId) {
152290
+ return { graph: diff.graph, source: "diff", analysisId: diff.id };
152291
+ }
152292
+ const filename = findAnalysisFilename(repoPath, analysisId);
152293
+ if (!filename) return null;
152294
+ const snap = readAnalysis(repoPath, filename);
152295
+ if (!snap) return null;
152296
+ return { graph: snap.graph, source: "historical", analysisId: snap.id };
152297
+ }
152203
152298
  function getDiffResult(repoPath) {
152204
152299
  const diff = readDiff(repoPath);
152205
152300
  if (!diff) return null;
@@ -152209,7 +152304,6 @@ function getDiffResult(repoPath) {
152209
152304
  }
152210
152305
 
152211
152306
  // apps/server/src/routes/analyses.ts
152212
- init_analysis_store();
152213
152307
  init_logger();
152214
152308
  var router2 = (0, import_express2.Router)();
152215
152309
  router2.post("/:id/analyses", async (req, res, next) => {
@@ -152230,7 +152324,7 @@ router2.post("/:id/analyses", async (req, res, next) => {
152230
152324
  const trackerSteps = buildAnalysisSteps(effectiveCategories, effectiveLlmRules);
152231
152325
  const tracker = createSocketTracker(id, trackerSteps);
152232
152326
  pushLogger({
152233
- filePath: path14.join(repo.path, ".truecourse/logs/analyze.log"),
152327
+ filePath: path15.join(repo.path, ".truecourse/logs/analyze.log"),
152234
152328
  tee: process.env.TRUECOURSE_DEV === "1"
152235
152329
  });
152236
152330
  try {
@@ -152462,16 +152556,16 @@ var analyses_default = router2;
152462
152556
  var import_express3 = __toESM(require_express2(), 1);
152463
152557
 
152464
152558
  // apps/server/src/config/ui-state.ts
152465
- import fs10 from "node:fs";
152559
+ import fs11 from "node:fs";
152466
152560
  var EMPTY_STATE = { positions: {}, collapsed: {} };
152467
152561
  function scopeKey(branch, level) {
152468
152562
  return `${branch || "HEAD"}/${level}`;
152469
152563
  }
152470
152564
  function readUiState(repoDir) {
152471
152565
  const file = getRepoUiStatePath(repoDir);
152472
- if (!fs10.existsSync(file)) return structuredClone(EMPTY_STATE);
152566
+ if (!fs11.existsSync(file)) return structuredClone(EMPTY_STATE);
152473
152567
  try {
152474
- const parsed = JSON.parse(fs10.readFileSync(file, "utf-8"));
152568
+ const parsed = JSON.parse(fs11.readFileSync(file, "utf-8"));
152475
152569
  return {
152476
152570
  positions: parsed.positions ?? {},
152477
152571
  collapsed: parsed.collapsed ?? {}
@@ -152482,7 +152576,7 @@ function readUiState(repoDir) {
152482
152576
  }
152483
152577
  function writeUiState(repoDir, state) {
152484
152578
  ensureRepoTruecourseDir(repoDir);
152485
- fs10.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
152579
+ fs11.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
152486
152580
  }
152487
152581
  function setPositions(repoDir, branch, level, positions) {
152488
152582
  const state = readUiState(repoDir);
@@ -153188,7 +153282,6 @@ function markDependencyViolations(edges, detViolations) {
153188
153282
  }
153189
153283
 
153190
153284
  // apps/server/src/routes/graph.ts
153191
- init_analysis_store();
153192
153285
  var router3 = (0, import_express3.Router)();
153193
153286
  router3.get("/:id/graph", async (req, res, next) => {
153194
153287
  try {
@@ -153380,9 +153473,8 @@ var graph_default = router3;
153380
153473
 
153381
153474
  // apps/server/src/routes/files.ts
153382
153475
  var import_express4 = __toESM(require_express2(), 1);
153383
- import fs11 from "node:fs";
153384
- import path15 from "node:path";
153385
- init_analysis_store();
153476
+ import fs12 from "node:fs";
153477
+ import path16 from "node:path";
153386
153478
  var router4 = (0, import_express4.Router)();
153387
153479
  router4.get("/:id/files", async (req, res, next) => {
153388
153480
  try {
@@ -153411,28 +153503,28 @@ router4.get("/:id/file-content", async (req, res, next) => {
153411
153503
  const ref = req.query.ref;
153412
153504
  if (!filePath) throw createAppError('Missing "path" query parameter', 400);
153413
153505
  const repo = resolveProjectForRequest(id);
153414
- const resolved = path15.resolve(repo.path, filePath);
153415
- if (!resolved.startsWith(path15.resolve(repo.path) + path15.sep) && resolved !== path15.resolve(repo.path)) {
153506
+ const resolved = path16.resolve(repo.path, filePath);
153507
+ if (!resolved.startsWith(path16.resolve(repo.path) + path16.sep) && resolved !== path16.resolve(repo.path)) {
153416
153508
  throw createAppError("Path traversal not allowed", 403);
153417
153509
  }
153418
153510
  let content;
153419
153511
  if (ref === "working-tree") {
153420
- if (!fs11.existsSync(resolved)) throw createAppError("File not found", 404);
153421
- const stat = fs11.statSync(resolved);
153512
+ if (!fs12.existsSync(resolved)) throw createAppError("File not found", 404);
153513
+ const stat = fs12.statSync(resolved);
153422
153514
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
153423
- content = fs11.readFileSync(resolved, "utf-8");
153515
+ content = fs12.readFileSync(resolved, "utf-8");
153424
153516
  } else {
153425
153517
  const git = await getGit(repo.path);
153426
153518
  try {
153427
153519
  content = await git.show([`HEAD:${filePath}`]);
153428
153520
  } catch {
153429
- if (!fs11.existsSync(resolved)) throw createAppError("File not found", 404);
153430
- const stat = fs11.statSync(resolved);
153521
+ if (!fs12.existsSync(resolved)) throw createAppError("File not found", 404);
153522
+ const stat = fs12.statSync(resolved);
153431
153523
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
153432
- content = fs11.readFileSync(resolved, "utf-8");
153524
+ content = fs12.readFileSync(resolved, "utf-8");
153433
153525
  }
153434
153526
  }
153435
- const ext2 = path15.extname(resolved).slice(1).toLowerCase();
153527
+ const ext2 = path16.extname(resolved).slice(1).toLowerCase();
153436
153528
  const langMap = {
153437
153529
  ts: "typescript",
153438
153530
  tsx: "typescript",
@@ -153497,7 +153589,6 @@ var files_default = router4;
153497
153589
 
153498
153590
  // apps/server/src/routes/violations.ts
153499
153591
  var import_express5 = __toESM(require_express2(), 1);
153500
- init_analysis_store();
153501
153592
  var router5 = (0, import_express5.Router)();
153502
153593
  router5.get(
153503
153594
  "/:id/violations",
@@ -153509,10 +153600,15 @@ router5.get(
153509
153600
  const offsetParam = parseInt(req.query.offset) || 0;
153510
153601
  const statusParam = req.query.status;
153511
153602
  const status = statusParam === "resolved" ? "resolved" : statusParam === "all" ? "all" : "active";
153603
+ const severityParam = req.query.severity;
153604
+ const severity = severityParam ? severityParam.split(",").map((s) => s.trim().toLowerCase()).filter(
153605
+ (s) => ["critical", "high", "medium", "low", "info"].includes(s)
153606
+ ) : void 0;
153512
153607
  const { violations, total } = listViolations(repo.path, {
153513
153608
  analysisId: req.query.analysisId,
153514
153609
  filePath: req.query.file,
153515
153610
  status,
153611
+ severity: severity && severity.length > 0 ? severity : void 0,
153516
153612
  limit: limitParam,
153517
153613
  offset: offsetParam
153518
153614
  });
@@ -153534,20 +153630,19 @@ router5.get(
153534
153630
  const repo = resolveProjectForRequest(id);
153535
153631
  const analysisIdParam = req.query.analysisId;
153536
153632
  const latest = readLatest(repo.path);
153537
- if (!latest || analysisIdParam && latest.analysis.id !== analysisIdParam) {
153538
- if (analysisIdParam) {
153539
- const file = await findAnalysisFilename2(repo.path, analysisIdParam);
153540
- if (file) {
153541
- const snap = readAnalysis(repo.path, file);
153542
- if (snap) {
153543
- res.json(summarizeViolations(snap.violations.added));
153544
- return;
153545
- }
153546
- }
153547
- }
153633
+ if (!latest) {
153548
153634
  res.json({ total: 0, byFile: {}, bySeverity: {}, highestSeverityByFile: {} });
153549
153635
  return;
153550
153636
  }
153637
+ if (analysisIdParam && latest.analysis.id !== analysisIdParam) {
153638
+ const historical = readActiveViolationsAt(repo.path, analysisIdParam);
153639
+ if (!historical) {
153640
+ res.json({ total: 0, byFile: {}, bySeverity: {}, highestSeverityByFile: {} });
153641
+ return;
153642
+ }
153643
+ res.json(summarizeViolations(historical));
153644
+ return;
153645
+ }
153551
153646
  res.json(summarizeViolations(latest.violations));
153552
153647
  } catch (error) {
153553
153648
  next(error);
@@ -153574,19 +153669,10 @@ function summarizeViolations(violations) {
153574
153669
  }
153575
153670
  return { total, byFile, bySeverity, highestSeverityByFile };
153576
153671
  }
153577
- async function findAnalysisFilename2(repoPath, analysisId) {
153578
- const { listAnalyses: listAnalyses2, readAnalysis: readAnalysis2 } = await Promise.resolve().then(() => (init_analysis_store(), analysis_store_exports));
153579
- for (const name of listAnalyses2(repoPath).reverse()) {
153580
- const snap = readAnalysis2(repoPath, name);
153581
- if (snap?.id === analysisId) return name;
153582
- }
153583
- return null;
153584
- }
153585
153672
  var violations_default = router5;
153586
153673
 
153587
153674
  // apps/server/src/routes/databases.ts
153588
153675
  var import_express6 = __toESM(require_express2(), 1);
153589
- init_analysis_store();
153590
153676
  var router6 = (0, import_express6.Router)();
153591
153677
  router6.get(
153592
153678
  "/:id/databases",
@@ -153594,19 +153680,21 @@ router6.get(
153594
153680
  try {
153595
153681
  const id = req.params.id;
153596
153682
  const repo = resolveProjectForRequest(id);
153597
- const latest = readLatest(repo.path);
153598
- if (!latest) {
153683
+ const analysisId = req.query.analysisId;
153684
+ const resolved = resolveGraphForAnalysisId(repo.path, analysisId);
153685
+ if (!resolved) {
153599
153686
  res.json([]);
153600
153687
  return;
153601
153688
  }
153602
- const result = latest.graph.databases.map((dbRow) => ({
153689
+ const { graph } = resolved;
153690
+ const result = graph.databases.map((dbRow) => ({
153603
153691
  id: dbRow.id,
153604
153692
  name: dbRow.name,
153605
153693
  type: dbRow.type,
153606
153694
  driver: dbRow.driver,
153607
153695
  tableCount: Array.isArray(dbRow.tables) ? dbRow.tables.length : 0,
153608
153696
  connectedServices: dbRow.connectedServices,
153609
- connections: latest.graph.databaseConnections.filter((c) => c.databaseId === dbRow.id).map((c) => ({ serviceId: c.serviceId, driver: c.driver }))
153697
+ connections: graph.databaseConnections.filter((c) => c.databaseId === dbRow.id).map((c) => ({ serviceId: c.serviceId, driver: c.driver }))
153610
153698
  }));
153611
153699
  res.json(result);
153612
153700
  } catch (error) {
@@ -153621,9 +153709,10 @@ router6.get(
153621
153709
  const id = req.params.id;
153622
153710
  const dbId = req.params.dbId;
153623
153711
  const repo = resolveProjectForRequest(id);
153624
- const latest = readLatest(repo.path);
153625
- if (!latest) throw createAppError("Database not found", 404);
153626
- const dbRow = latest.graph.databases.find((d) => d.id === dbId);
153712
+ const analysisId = req.query.analysisId;
153713
+ const resolved = resolveGraphForAnalysisId(repo.path, analysisId);
153714
+ if (!resolved) throw createAppError("Database not found", 404);
153715
+ const dbRow = resolved.graph.databases.find((d) => d.id === dbId);
153627
153716
  if (!dbRow) throw createAppError("Database not found", 404);
153628
153717
  res.json({
153629
153718
  id: dbRow.id,
@@ -153650,7 +153739,6 @@ var rules_default = router7;
153650
153739
 
153651
153740
  // apps/server/src/routes/flows.ts
153652
153741
  var import_express8 = __toESM(require_express2(), 1);
153653
- init_analysis_store();
153654
153742
  var router8 = (0, import_express8.Router)();
153655
153743
  router8.get(
153656
153744
  "/:id/flows",
@@ -153658,11 +153746,13 @@ router8.get(
153658
153746
  try {
153659
153747
  const id = req.params.id;
153660
153748
  const repo = resolveProjectForRequest(id);
153661
- const latest = readLatest(repo.path);
153662
- if (!latest) return res.json({ flows: [], severities: {} });
153749
+ const analysisId = req.query.analysisId;
153750
+ const resolved = resolveGraphForAnalysisId(repo.path, analysisId);
153751
+ if (!resolved) return res.json({ flows: [], severities: {} });
153752
+ const violations = readActiveViolationsForAnalysisId(repo.path, analysisId) ?? [];
153663
153753
  res.json({
153664
- flows: latest.graph.flows,
153665
- severities: computeFlowSeverities(latest)
153754
+ flows: resolved.graph.flows,
153755
+ severities: computeFlowSeverities(resolved.graph, violations)
153666
153756
  });
153667
153757
  } catch (err) {
153668
153758
  next(err);
@@ -153676,7 +153766,10 @@ router8.get(
153676
153766
  const id = req.params.id;
153677
153767
  const flowId = req.params.flowId;
153678
153768
  const repo = resolveProjectForRequest(id);
153679
- const flow = getFlowFromLatest(repo.path, flowId);
153769
+ const analysisId = req.query.analysisId;
153770
+ const resolved = resolveGraphForAnalysisId(repo.path, analysisId);
153771
+ if (!resolved) throw createAppError("Flow not found", 404);
153772
+ const flow = resolved.graph.flows.find((f2) => f2.id === flowId);
153680
153773
  if (!flow) throw createAppError("Flow not found", 404);
153681
153774
  res.json(flow);
153682
153775
  } catch (err) {
@@ -153707,11 +153800,16 @@ var flows_default = router8;
153707
153800
  var import_express9 = __toESM(require_express2(), 1);
153708
153801
 
153709
153802
  // apps/server/src/services/analytics.service.ts
153710
- init_analysis_store();
153711
153803
  var STALE_DAYS = 7;
153712
- function getTrend(repoPath, branch, limit = 20) {
153804
+ function getTrend(repoPath, branch, limit = 20, upToAnalysisId) {
153713
153805
  const history = readHistory(repoPath);
153714
- const entries = history.analyses.filter((e) => (!branch || e.branch === branch) && !isDiff(e)).slice(-limit);
153806
+ const eligible = history.analyses.filter((e) => (!branch || e.branch === branch) && !isDiff(e));
153807
+ let windowed = eligible;
153808
+ if (upToAnalysisId) {
153809
+ const idx = eligible.findIndex((e) => e.id === upToAnalysisId);
153810
+ if (idx >= 0) windowed = eligible.slice(0, idx + 1);
153811
+ }
153812
+ const entries = windowed.slice(-limit);
153715
153813
  const points = entries.map((e) => {
153716
153814
  const sev = e.counts.violations.bySeverity;
153717
153815
  const total = e.counts.violations.new + e.counts.violations.unchanged;
@@ -153782,7 +153880,7 @@ function getTopOffenders(repoPath, branch, specificAnalysisId) {
153782
153880
  const offenders = [...services, ...modules].sort((a, b) => b.violationCount - a.violationCount).slice(0, 10);
153783
153881
  return { offenders, analysisId };
153784
153882
  }
153785
- function getResolution(repoPath, branch) {
153883
+ function getResolution(repoPath, branch, upToAnalysisId) {
153786
153884
  const files = listAnalyses(repoPath);
153787
153885
  const staleThresholdMs = Date.now() - STALE_DAYS * 24 * 60 * 60 * 1e3;
153788
153886
  let totalResolved = 0;
@@ -153810,14 +153908,13 @@ function getResolution(repoPath, branch) {
153810
153908
  }
153811
153909
  }
153812
153910
  }
153911
+ if (upToAnalysisId && snap.id === upToAnalysisId) break;
153813
153912
  }
153814
- const latest = readLatest(repoPath);
153815
- if (latest) {
153816
- for (const v of latest.violations) {
153817
- if (v.status === "new" || v.status === "unchanged") {
153818
- totalActive++;
153819
- if (v.firstSeenAt && Date.parse(v.firstSeenAt) < staleThresholdMs) staleCount++;
153820
- }
153913
+ const activeSet = upToAnalysisId ? readActiveViolationsForAnalysisId(repoPath, upToAnalysisId) : readLatest(repoPath)?.violations.filter((v) => v.status === "new" || v.status === "unchanged") ?? null;
153914
+ if (activeSet) {
153915
+ for (const v of activeSet) {
153916
+ totalActive++;
153917
+ if (v.firstSeenAt && Date.parse(v.firstSeenAt) < staleThresholdMs) staleCount++;
153821
153918
  }
153822
153919
  }
153823
153920
  const resolutionRate = totalResolved + totalActive > 0 ? totalResolved / (totalResolved + totalActive) : 0;
@@ -153834,29 +153931,12 @@ function isDiff(entry) {
153834
153931
  return entry.metadata?.isDiffAnalysis === true;
153835
153932
  }
153836
153933
  function loadActiveViolations(repoPath, branch, specificAnalysisId) {
153837
- const latest = readLatest(repoPath);
153838
- if (!latest) return [];
153839
- if (specificAnalysisId && latest.analysis.id !== specificAnalysisId) {
153840
- for (const name of listAnalyses(repoPath).reverse()) {
153841
- const snap = readAnalysis(repoPath, name);
153842
- if (snap?.id === specificAnalysisId) {
153843
- const serviceById = new Map(snap.graph.services.map((s) => [s.id, s.name]));
153844
- const moduleById = new Map(snap.graph.modules.map((m) => [m.id, m.name]));
153845
- const methodById = new Map(snap.graph.methods.map((m) => [m.id, m.name]));
153846
- const databaseById = new Map(snap.graph.databases.map((d) => [d.id, d.name]));
153847
- return snap.violations.added.map((v) => ({
153848
- ...v,
153849
- targetServiceName: v.targetServiceId ? serviceById.get(v.targetServiceId) ?? null : null,
153850
- targetModuleName: v.targetModuleId ? moduleById.get(v.targetModuleId) ?? null : null,
153851
- targetMethodName: v.targetMethodId ? methodById.get(v.targetMethodId) ?? null : null,
153852
- targetDatabaseName: v.targetDatabaseId ? databaseById.get(v.targetDatabaseId) ?? null : null
153853
- }));
153854
- }
153855
- }
153856
- return [];
153934
+ if (!specificAnalysisId) {
153935
+ const latest = readLatest(repoPath);
153936
+ if (!latest) return [];
153937
+ if (branch && latest.analysis.branch !== branch) return [];
153857
153938
  }
153858
- if (branch && latest.analysis.branch !== branch) return [];
153859
- return latest.violations.filter((v) => v.status === "new" || v.status === "unchanged");
153939
+ return readActiveViolationsForAnalysisId(repoPath, specificAnalysisId) ?? [];
153860
153940
  }
153861
153941
 
153862
153942
  // apps/server/src/routes/analytics.ts
@@ -153867,9 +153947,10 @@ router9.get(
153867
153947
  try {
153868
153948
  const id = req.params.id;
153869
153949
  const branch = req.query.branch;
153950
+ const analysisId = req.query.analysisId;
153870
153951
  const limit = req.query.limit ? parseInt(req.query.limit, 10) : 20;
153871
153952
  const repo = resolveProjectForRequest(id);
153872
- res.json(getTrend(repo.path, branch, limit));
153953
+ res.json(getTrend(repo.path, branch, limit, analysisId));
153873
153954
  } catch (err) {
153874
153955
  next(err);
153875
153956
  }
@@ -153909,8 +153990,9 @@ router9.get(
153909
153990
  try {
153910
153991
  const id = req.params.id;
153911
153992
  const branch = req.query.branch;
153993
+ const analysisId = req.query.analysisId;
153912
153994
  const repo = resolveProjectForRequest(id);
153913
- res.json(getResolution(repo.path, branch));
153995
+ res.json(getResolution(repo.path, branch, analysisId));
153914
153996
  } catch (err) {
153915
153997
  next(err);
153916
153998
  }
@@ -153943,10 +154025,10 @@ function stopAllWatchers() {
153943
154025
 
153944
154026
  // apps/server/src/index.ts
153945
154027
  init_logger();
153946
- var __dirname3 = path16.dirname(fileURLToPath3(import.meta.url));
154028
+ var __dirname3 = path17.dirname(fileURLToPath4(import.meta.url));
153947
154029
  async function main() {
153948
154030
  configureLogger({
153949
- filePath: path16.join(getLogDir(), "dashboard.log"),
154031
+ filePath: path17.join(getLogDir(), "dashboard.log"),
153950
154032
  tee: process.env.TRUECOURSE_DEV === "1"
153951
154033
  });
153952
154034
  if (wipeLegacyPostgresData()) {
@@ -153971,11 +154053,11 @@ async function main() {
153971
154053
  res.json({ status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
153972
154054
  });
153973
154055
  app.use(errorHandler);
153974
- const staticDir = path16.join(__dirname3, "public");
153975
- if (fs12.existsSync(staticDir)) {
154056
+ const staticDir = path17.join(__dirname3, "public");
154057
+ if (fs13.existsSync(staticDir)) {
153976
154058
  app.use(import_express10.default.static(staticDir));
153977
154059
  app.get("*", (_req, res) => {
153978
- res.sendFile(path16.join(staticDir, "index.html"));
154060
+ res.sendFile(path17.join(staticDir, "index.html"));
153979
154061
  });
153980
154062
  }
153981
154063
  await new Promise((resolve7, reject) => {