terminal-commands 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -15237,11 +15237,11 @@ var require_mime_types = __commonJS({
15237
15237
  }
15238
15238
  return exts[0];
15239
15239
  }
15240
- function lookup(path2) {
15241
- if (!path2 || typeof path2 !== "string") {
15240
+ function lookup(path4) {
15241
+ if (!path4 || typeof path4 !== "string") {
15242
15242
  return false;
15243
15243
  }
15244
- var extension2 = extname("x." + path2).toLowerCase().slice(1);
15244
+ var extension2 = extname("x." + path4).toLowerCase().slice(1);
15245
15245
  if (!extension2) {
15246
15246
  return false;
15247
15247
  }
@@ -18390,11 +18390,11 @@ var require_parse = __commonJS({
18390
18390
  segments[segments.length] = parent;
18391
18391
  }
18392
18392
  var n = key.length;
18393
- var open3 = first;
18393
+ var open2 = first;
18394
18394
  var collected = 0;
18395
- while (open3 >= 0 && collected < options.depth) {
18395
+ while (open2 >= 0 && collected < options.depth) {
18396
18396
  var level = 1;
18397
- var i = open3 + 1;
18397
+ var i = open2 + 1;
18398
18398
  var close = -1;
18399
18399
  while (i < n && close < 0) {
18400
18400
  var cu = key.charCodeAt(i);
@@ -18409,23 +18409,23 @@ var require_parse = __commonJS({
18409
18409
  i += 1;
18410
18410
  }
18411
18411
  if (close < 0) {
18412
- segments[segments.length] = "[" + key.slice(open3) + "]";
18412
+ segments[segments.length] = "[" + key.slice(open2) + "]";
18413
18413
  return segments;
18414
18414
  }
18415
- var seg = key.slice(open3, close + 1);
18415
+ var seg = key.slice(open2, close + 1);
18416
18416
  var content = seg.slice(1, -1);
18417
18417
  if (!options.plainObjects && has.call(Object.prototype, content) && !options.allowPrototypes) {
18418
18418
  return;
18419
18419
  }
18420
18420
  segments[segments.length] = seg;
18421
18421
  collected += 1;
18422
- open3 = key.indexOf("[", close + 1);
18422
+ open2 = key.indexOf("[", close + 1);
18423
18423
  }
18424
- if (open3 >= 0) {
18424
+ if (open2 >= 0) {
18425
18425
  if (options.strictDepth === true) {
18426
18426
  throw new RangeError("Input depth exceeded depth option of " + options.depth + " and strictDepth is true");
18427
18427
  }
18428
- segments[segments.length] = "[" + key.slice(open3) + "]";
18428
+ segments[segments.length] = "[" + key.slice(open2) + "]";
18429
18429
  }
18430
18430
  return segments;
18431
18431
  };
@@ -18928,13 +18928,13 @@ var require_view = __commonJS({
18928
18928
  "node_modules/express/lib/view.js"(exports, module) {
18929
18929
  "use strict";
18930
18930
  var debug = require_src()("express:view");
18931
- var path2 = __require("node:path");
18931
+ var path4 = __require("node:path");
18932
18932
  var fs = __require("node:fs");
18933
- var dirname = path2.dirname;
18934
- var basename = path2.basename;
18935
- var extname = path2.extname;
18936
- var join = path2.join;
18937
- var resolve = path2.resolve;
18933
+ var dirname = path4.dirname;
18934
+ var basename = path4.basename;
18935
+ var extname = path4.extname;
18936
+ var join = path4.join;
18937
+ var resolve = path4.resolve;
18938
18938
  module.exports = View;
18939
18939
  function View(name, options) {
18940
18940
  var opts = options || {};
@@ -18963,17 +18963,17 @@ var require_view = __commonJS({
18963
18963
  this.path = this.lookup(fileName);
18964
18964
  }
18965
18965
  View.prototype.lookup = function lookup(name) {
18966
- var path3;
18966
+ var path5;
18967
18967
  var roots2 = [].concat(this.root);
18968
18968
  debug('lookup "%s"', name);
18969
- for (var i = 0; i < roots2.length && !path3; i++) {
18969
+ for (var i = 0; i < roots2.length && !path5; i++) {
18970
18970
  var root = roots2[i];
18971
18971
  var loc = resolve(root, name);
18972
18972
  var dir = dirname(loc);
18973
18973
  var file2 = basename(loc);
18974
- path3 = this.resolve(dir, file2);
18974
+ path5 = this.resolve(dir, file2);
18975
18975
  }
18976
- return path3;
18976
+ return path5;
18977
18977
  };
18978
18978
  View.prototype.render = function render(options, callback) {
18979
18979
  var sync = true;
@@ -18995,21 +18995,21 @@ var require_view = __commonJS({
18995
18995
  };
18996
18996
  View.prototype.resolve = function resolve2(dir, file2) {
18997
18997
  var ext = this.ext;
18998
- var path3 = join(dir, file2);
18999
- var stat = tryStat(path3);
18998
+ var path5 = join(dir, file2);
18999
+ var stat = tryStat(path5);
19000
19000
  if (stat && stat.isFile()) {
19001
- return path3;
19001
+ return path5;
19002
19002
  }
19003
- path3 = join(dir, basename(file2, ext), "index" + ext);
19004
- stat = tryStat(path3);
19003
+ path5 = join(dir, basename(file2, ext), "index" + ext);
19004
+ stat = tryStat(path5);
19005
19005
  if (stat && stat.isFile()) {
19006
- return path3;
19006
+ return path5;
19007
19007
  }
19008
19008
  };
19009
- function tryStat(path3) {
19010
- debug('stat "%s"', path3);
19009
+ function tryStat(path5) {
19010
+ debug('stat "%s"', path5);
19011
19011
  try {
19012
- return fs.statSync(path3);
19012
+ return fs.statSync(path5);
19013
19013
  } catch (e) {
19014
19014
  return void 0;
19015
19015
  }
@@ -19946,6 +19946,9 @@ var require_proxy_addr = __commonJS({
19946
19946
  return function trust(addr) {
19947
19947
  if (!isip(addr)) return false;
19948
19948
  var ip = parseip(addr);
19949
+ if (ip.kind() === "ipv6" && ip.isIPv4MappedAddress()) {
19950
+ ip = ip.toIPv4Address();
19951
+ }
19949
19952
  var ipconv;
19950
19953
  var kind = ip.kind();
19951
19954
  for (var i = 0; i < subnets.length; i++) {
@@ -19958,10 +19961,15 @@ var require_proxy_addr = __commonJS({
19958
19961
  if (subnetkind === "ipv4" && !ip.isIPv4MappedAddress()) {
19959
19962
  continue;
19960
19963
  }
19964
+ if (subnetkind !== "ipv4" && !(subnetrange >= 96 && subnetip.isIPv4MappedAddress())) {
19965
+ continue;
19966
+ }
19961
19967
  if (!ipconv) {
19962
19968
  ipconv = subnetkind === "ipv4" ? ip.toIPv4Address() : ip.toIPv4MappedAddress();
19963
19969
  }
19964
19970
  trusted = ipconv;
19971
+ } else if (kind === "ipv6" && subnetip.isIPv4MappedAddress()) {
19972
+ continue;
19965
19973
  }
19966
19974
  if (trusted.match(subnetip, subnetrange)) {
19967
19975
  return true;
@@ -19978,12 +19986,20 @@ var require_proxy_addr = __commonJS({
19978
19986
  return function trust(addr) {
19979
19987
  if (!isip(addr)) return false;
19980
19988
  var ip = parseip(addr);
19989
+ if (ip.kind() === "ipv6" && ip.isIPv4MappedAddress()) {
19990
+ ip = ip.toIPv4Address();
19991
+ }
19981
19992
  var kind = ip.kind();
19982
19993
  if (kind !== subnetkind) {
19983
19994
  if (subnetisipv4 && !ip.isIPv4MappedAddress()) {
19984
19995
  return false;
19985
19996
  }
19997
+ if (!subnetisipv4 && !(subnetrange >= 96 && subnetip.isIPv4MappedAddress())) {
19998
+ return false;
19999
+ }
19986
20000
  ip = subnetisipv4 ? ip.toIPv4Address() : ip.toIPv4MappedAddress();
20001
+ } else if (kind === "ipv6" && subnetip.isIPv4MappedAddress()) {
20002
+ return false;
19987
20003
  }
19988
20004
  return ip.match(subnetip, subnetrange);
19989
20005
  };
@@ -20249,15 +20265,15 @@ var require_dist3 = __commonJS({
20249
20265
  let index = 0;
20250
20266
  function consumeUntil(end) {
20251
20267
  const output2 = [];
20252
- let path2 = "";
20268
+ let path4 = "";
20253
20269
  function writePath() {
20254
- if (!path2)
20270
+ if (!path4)
20255
20271
  return;
20256
20272
  output2.push({
20257
20273
  type: "text",
20258
- value: encodePath(path2)
20274
+ value: encodePath(path4)
20259
20275
  });
20260
- path2 = "";
20276
+ path4 = "";
20261
20277
  }
20262
20278
  while (index < chars.length) {
20263
20279
  const value = chars[index++];
@@ -20269,7 +20285,7 @@ var require_dist3 = __commonJS({
20269
20285
  if (index === chars.length) {
20270
20286
  throw new PathError(`Unexpected end after \\ at index ${index}`, str);
20271
20287
  }
20272
- path2 += chars[index++];
20288
+ path4 += chars[index++];
20273
20289
  continue;
20274
20290
  }
20275
20291
  if (value === ":" || value === "*") {
@@ -20313,7 +20329,7 @@ var require_dist3 = __commonJS({
20313
20329
  if (value === "}" || value === "(" || value === ")" || value === "[" || value === "]" || value === "+" || value === "?" || value === "!") {
20314
20330
  throw new PathError(`Unexpected ${value} at index ${index - 1}`, str);
20315
20331
  }
20316
- path2 += value;
20332
+ path4 += value;
20317
20333
  }
20318
20334
  if (end) {
20319
20335
  throw new PathError(`Unexpected end at index ${index}, expected ${end}`, str);
@@ -20323,17 +20339,17 @@ var require_dist3 = __commonJS({
20323
20339
  }
20324
20340
  return new TokenData(consumeUntil(""), str);
20325
20341
  }
20326
- function compile2(path2, options = {}) {
20342
+ function compile2(path4, options = {}) {
20327
20343
  const { encode: encode3 = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
20328
- const data = typeof path2 === "object" ? path2 : parse3(path2, options);
20344
+ const data = typeof path4 === "object" ? path4 : parse3(path4, options);
20329
20345
  const fn = tokensToFunction(data.tokens, delimiter, encode3);
20330
- return function path3(params = {}) {
20346
+ return function path5(params = {}) {
20331
20347
  const missing = [];
20332
- const path4 = fn(params, missing);
20348
+ const path6 = fn(params, missing);
20333
20349
  if (missing.length) {
20334
20350
  throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
20335
20351
  }
20336
- return path4;
20352
+ return path6;
20337
20353
  };
20338
20354
  }
20339
20355
  function tokensToFunction(tokens, delimiter, encode3) {
@@ -20395,9 +20411,9 @@ var require_dist3 = __commonJS({
20395
20411
  return encodeValue(value);
20396
20412
  };
20397
20413
  }
20398
- function match(path2, options = {}) {
20414
+ function match(path4, options = {}) {
20399
20415
  const { decode: decode3 = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
20400
- const { regexp, keys } = pathToRegexp(path2, options);
20416
+ const { regexp, keys } = pathToRegexp(path4, options);
20401
20417
  const decoders = keys.map((key) => {
20402
20418
  if (decode3 === false)
20403
20419
  return NOOP_VALUE;
@@ -20409,7 +20425,7 @@ var require_dist3 = __commonJS({
20409
20425
  const m = regexp.exec(input2);
20410
20426
  if (!m)
20411
20427
  return false;
20412
- const path3 = m[0];
20428
+ const path5 = m[0];
20413
20429
  const params = /* @__PURE__ */ Object.create(null);
20414
20430
  for (let i = 1; i < m.length; i++) {
20415
20431
  if (m[i] === void 0)
@@ -20418,21 +20434,21 @@ var require_dist3 = __commonJS({
20418
20434
  const decoder = decoders[i - 1];
20419
20435
  params[key.name] = decoder(m[i]);
20420
20436
  }
20421
- return { path: path3, params };
20437
+ return { path: path5, params };
20422
20438
  };
20423
20439
  }
20424
- function pathToRegexp(path2, options = {}) {
20440
+ function pathToRegexp(path4, options = {}) {
20425
20441
  const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true } = options;
20426
20442
  const keys = [];
20427
20443
  let source = "";
20428
20444
  let combinations = 0;
20429
- function process2(path3) {
20430
- if (Array.isArray(path3)) {
20431
- for (const p of path3)
20445
+ function process2(path5) {
20446
+ if (Array.isArray(path5)) {
20447
+ for (const p of path5)
20432
20448
  process2(p);
20433
20449
  return;
20434
20450
  }
20435
- const data = typeof path3 === "object" ? path3 : parse3(path3, options);
20451
+ const data = typeof path5 === "object" ? path5 : parse3(path5, options);
20436
20452
  flatten(data.tokens, 0, [], (tokens) => {
20437
20453
  if (combinations >= 256) {
20438
20454
  throw new PathError("Too many path combinations", data.originalPath);
@@ -20443,7 +20459,7 @@ var require_dist3 = __commonJS({
20443
20459
  combinations++;
20444
20460
  });
20445
20461
  }
20446
- process2(path2);
20462
+ process2(path4);
20447
20463
  let pattern = `^(?:${source})`;
20448
20464
  if (trailing)
20449
20465
  pattern += "(?:" + escape2(delimiter) + "$)?";
@@ -20583,18 +20599,18 @@ var require_layer = __commonJS({
20583
20599
  var TRAILING_SLASH_REGEXP = /\/+$/;
20584
20600
  var MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g;
20585
20601
  module.exports = Layer;
20586
- function Layer(path2, options, fn) {
20602
+ function Layer(path4, options, fn) {
20587
20603
  if (!(this instanceof Layer)) {
20588
- return new Layer(path2, options, fn);
20604
+ return new Layer(path4, options, fn);
20589
20605
  }
20590
- debug("new %o", path2);
20606
+ debug("new %o", path4);
20591
20607
  const opts = options || {};
20592
20608
  this.handle = fn;
20593
20609
  this.keys = [];
20594
20610
  this.name = fn.name || "<anonymous>";
20595
20611
  this.params = void 0;
20596
20612
  this.path = void 0;
20597
- this.slash = path2 === "/" && opts.end === false;
20613
+ this.slash = path4 === "/" && opts.end === false;
20598
20614
  function matcher(_path) {
20599
20615
  if (_path instanceof RegExp) {
20600
20616
  const keys = [];
@@ -20633,7 +20649,7 @@ var require_layer = __commonJS({
20633
20649
  decode: decodeParam
20634
20650
  });
20635
20651
  }
20636
- this.matchers = Array.isArray(path2) ? path2.map(matcher) : [matcher(path2)];
20652
+ this.matchers = Array.isArray(path4) ? path4.map(matcher) : [matcher(path4)];
20637
20653
  }
20638
20654
  Layer.prototype.handleError = function handleError(error62, req, res, next) {
20639
20655
  const fn = this.handle;
@@ -20673,9 +20689,9 @@ var require_layer = __commonJS({
20673
20689
  next(err);
20674
20690
  }
20675
20691
  };
20676
- Layer.prototype.match = function match(path2) {
20692
+ Layer.prototype.match = function match(path4) {
20677
20693
  let match2;
20678
- if (path2 != null) {
20694
+ if (path4 != null) {
20679
20695
  if (this.slash) {
20680
20696
  this.params = {};
20681
20697
  this.path = "";
@@ -20683,7 +20699,7 @@ var require_layer = __commonJS({
20683
20699
  }
20684
20700
  let i = 0;
20685
20701
  while (!match2 && i < this.matchers.length) {
20686
- match2 = this.matchers[i](path2);
20702
+ match2 = this.matchers[i](path4);
20687
20703
  i++;
20688
20704
  }
20689
20705
  }
@@ -20711,13 +20727,13 @@ var require_layer = __commonJS({
20711
20727
  throw err;
20712
20728
  }
20713
20729
  }
20714
- function loosen(path2) {
20715
- if (path2 instanceof RegExp || path2 === "/") {
20716
- return path2;
20730
+ function loosen(path4) {
20731
+ if (path4 instanceof RegExp || path4 === "/") {
20732
+ return path4;
20717
20733
  }
20718
- return Array.isArray(path2) ? path2.map(function(p) {
20734
+ return Array.isArray(path4) ? path4.map(function(p) {
20719
20735
  return loosen(p);
20720
- }) : String(path2).replace(TRAILING_SLASH_REGEXP, "");
20736
+ }) : String(path4).replace(TRAILING_SLASH_REGEXP, "");
20721
20737
  }
20722
20738
  }
20723
20739
  });
@@ -20733,9 +20749,9 @@ var require_route = __commonJS({
20733
20749
  var flatten = Array.prototype.flat;
20734
20750
  var methods = METHODS.map((method) => method.toLowerCase());
20735
20751
  module.exports = Route;
20736
- function Route(path2) {
20737
- debug("new %o", path2);
20738
- this.path = path2;
20752
+ function Route(path4) {
20753
+ debug("new %o", path4);
20754
+ this.path = path4;
20739
20755
  this.stack = [];
20740
20756
  this.methods = /* @__PURE__ */ Object.create(null);
20741
20757
  }
@@ -20943,8 +20959,8 @@ var require_router = __commonJS({
20943
20959
  if (++sync > 100) {
20944
20960
  return setImmediate(next, err);
20945
20961
  }
20946
- const path2 = getPathname(req);
20947
- if (path2 == null) {
20962
+ const path4 = getPathname(req);
20963
+ if (path4 == null) {
20948
20964
  return done(layerError);
20949
20965
  }
20950
20966
  let layer;
@@ -20952,7 +20968,7 @@ var require_router = __commonJS({
20952
20968
  let route;
20953
20969
  while (match !== true && idx < stack.length) {
20954
20970
  layer = stack[idx++];
20955
- match = matchLayer(layer, path2);
20971
+ match = matchLayer(layer, path4);
20956
20972
  route = layer.route;
20957
20973
  if (typeof match !== "boolean") {
20958
20974
  layerError = layerError || match;
@@ -20990,18 +21006,18 @@ var require_router = __commonJS({
20990
21006
  } else if (route) {
20991
21007
  layer.handleRequest(req, res, next);
20992
21008
  } else {
20993
- trimPrefix(layer, layerError, layerPath, path2);
21009
+ trimPrefix(layer, layerError, layerPath, path4);
20994
21010
  }
20995
21011
  sync = 0;
20996
21012
  });
20997
21013
  }
20998
- function trimPrefix(layer, layerError, layerPath, path2) {
21014
+ function trimPrefix(layer, layerError, layerPath, path4) {
20999
21015
  if (layerPath.length !== 0) {
21000
- if (layerPath !== path2.substring(0, layerPath.length)) {
21016
+ if (layerPath !== path4.substring(0, layerPath.length)) {
21001
21017
  next(layerError);
21002
21018
  return;
21003
21019
  }
21004
- const c = path2[layerPath.length];
21020
+ const c = path4[layerPath.length];
21005
21021
  if (c && c !== "/") {
21006
21022
  next(layerError);
21007
21023
  return;
@@ -21025,7 +21041,7 @@ var require_router = __commonJS({
21025
21041
  };
21026
21042
  Router.prototype.use = function use(handler) {
21027
21043
  let offset = 0;
21028
- let path2 = "/";
21044
+ let path4 = "/";
21029
21045
  if (typeof handler !== "function") {
21030
21046
  let arg = handler;
21031
21047
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -21033,7 +21049,7 @@ var require_router = __commonJS({
21033
21049
  }
21034
21050
  if (typeof arg !== "function") {
21035
21051
  offset = 1;
21036
- path2 = handler;
21052
+ path4 = handler;
21037
21053
  }
21038
21054
  }
21039
21055
  const callbacks = flatten.call(slice.call(arguments, offset), Infinity);
@@ -21045,8 +21061,8 @@ var require_router = __commonJS({
21045
21061
  if (typeof fn !== "function") {
21046
21062
  throw new TypeError("argument handler must be a function");
21047
21063
  }
21048
- debug("use %o %s", path2, fn.name || "<anonymous>");
21049
- const layer = new Layer(path2, {
21064
+ debug("use %o %s", path4, fn.name || "<anonymous>");
21065
+ const layer = new Layer(path4, {
21050
21066
  sensitive: this.caseSensitive,
21051
21067
  strict: false,
21052
21068
  end: false
@@ -21056,9 +21072,9 @@ var require_router = __commonJS({
21056
21072
  }
21057
21073
  return this;
21058
21074
  };
21059
- Router.prototype.route = function route(path2) {
21060
- const route2 = new Route(path2);
21061
- const layer = new Layer(path2, {
21075
+ Router.prototype.route = function route(path4) {
21076
+ const route2 = new Route(path4);
21077
+ const layer = new Layer(path4, {
21062
21078
  sensitive: this.caseSensitive,
21063
21079
  strict: this.strict,
21064
21080
  end: true
@@ -21071,8 +21087,8 @@ var require_router = __commonJS({
21071
21087
  return route2;
21072
21088
  };
21073
21089
  methods.concat("all").forEach(function(method) {
21074
- Router.prototype[method] = function(path2) {
21075
- const route = this.route(path2);
21090
+ Router.prototype[method] = function(path4) {
21091
+ const route = this.route(path4);
21076
21092
  route[method].apply(route, slice.call(arguments, 1));
21077
21093
  return this;
21078
21094
  };
@@ -21101,9 +21117,9 @@ var require_router = __commonJS({
21101
21117
  const fqdnIndex = url2.substring(0, pathLength).indexOf("://");
21102
21118
  return fqdnIndex !== -1 ? url2.substring(0, url2.indexOf("/", 3 + fqdnIndex)) : void 0;
21103
21119
  }
21104
- function matchLayer(layer, path2) {
21120
+ function matchLayer(layer, path4) {
21105
21121
  try {
21106
- return layer.match(path2);
21122
+ return layer.match(path4);
21107
21123
  } catch (err) {
21108
21124
  return err;
21109
21125
  }
@@ -21331,7 +21347,7 @@ var require_application = __commonJS({
21331
21347
  };
21332
21348
  app2.use = function use(fn) {
21333
21349
  var offset = 0;
21334
- var path2 = "/";
21350
+ var path4 = "/";
21335
21351
  if (typeof fn !== "function") {
21336
21352
  var arg = fn;
21337
21353
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -21339,7 +21355,7 @@ var require_application = __commonJS({
21339
21355
  }
21340
21356
  if (typeof arg !== "function") {
21341
21357
  offset = 1;
21342
- path2 = fn;
21358
+ path4 = fn;
21343
21359
  }
21344
21360
  }
21345
21361
  var fns = flatten.call(slice.call(arguments, offset), Infinity);
@@ -21349,12 +21365,12 @@ var require_application = __commonJS({
21349
21365
  var router = this.router;
21350
21366
  fns.forEach(function(fn2) {
21351
21367
  if (!fn2 || !fn2.handle || !fn2.set) {
21352
- return router.use(path2, fn2);
21368
+ return router.use(path4, fn2);
21353
21369
  }
21354
- debug(".use app under %s", path2);
21355
- fn2.mountpath = path2;
21370
+ debug(".use app under %s", path4);
21371
+ fn2.mountpath = path4;
21356
21372
  fn2.parent = this;
21357
- router.use(path2, function mounted_app(req, res, next) {
21373
+ router.use(path4, function mounted_app(req, res, next) {
21358
21374
  var orig = req.app;
21359
21375
  fn2.handle(req, res, function(err) {
21360
21376
  Object.setPrototypeOf(req, orig.request);
@@ -21366,8 +21382,8 @@ var require_application = __commonJS({
21366
21382
  }, this);
21367
21383
  return this;
21368
21384
  };
21369
- app2.route = function route(path2) {
21370
- return this.router.route(path2);
21385
+ app2.route = function route(path4) {
21386
+ return this.router.route(path4);
21371
21387
  };
21372
21388
  app2.engine = function engine(ext, fn) {
21373
21389
  if (typeof fn !== "function") {
@@ -21410,7 +21426,7 @@ var require_application = __commonJS({
21410
21426
  }
21411
21427
  return this;
21412
21428
  };
21413
- app2.path = function path2() {
21429
+ app2.path = function path4() {
21414
21430
  return this.parent ? this.parent.path() + this.mountpath : "";
21415
21431
  };
21416
21432
  app2.enabled = function enabled(setting) {
@@ -21426,17 +21442,17 @@ var require_application = __commonJS({
21426
21442
  return this.set(setting, false);
21427
21443
  };
21428
21444
  methods.forEach(function(method) {
21429
- app2[method] = function(path2) {
21445
+ app2[method] = function(path4) {
21430
21446
  if (method === "get" && arguments.length === 1) {
21431
- return this.set(path2);
21447
+ return this.set(path4);
21432
21448
  }
21433
- var route = this.route(path2);
21449
+ var route = this.route(path4);
21434
21450
  route[method].apply(route, slice.call(arguments, 1));
21435
21451
  return this;
21436
21452
  };
21437
21453
  });
21438
- app2.all = function all(path2) {
21439
- var route = this.route(path2);
21454
+ app2.all = function all(path4) {
21455
+ var route = this.route(path4);
21440
21456
  var args = slice.call(arguments, 1);
21441
21457
  for (var i = 0; i < methods.length; i++) {
21442
21458
  route[methods[i]].apply(route, args);
@@ -22421,7 +22437,7 @@ var require_request = __commonJS({
22421
22437
  var subdomains2 = !isIP(hostname3) ? hostname3.split(".").reverse() : [hostname3];
22422
22438
  return subdomains2.slice(offset);
22423
22439
  });
22424
- defineGetter(req, "path", function path2() {
22440
+ defineGetter(req, "path", function path4() {
22425
22441
  return parse3(this).pathname;
22426
22442
  });
22427
22443
  defineGetter(req, "host", function host2() {
@@ -22632,8 +22648,8 @@ var require_content_disposition = __commonJS({
22632
22648
  this.type = type;
22633
22649
  this.parameters = parameters;
22634
22650
  }
22635
- function basename(path2) {
22636
- const normalized = path2.replaceAll("\\", "/");
22651
+ function basename(path4) {
22652
+ const normalized = path4.replaceAll("\\", "/");
22637
22653
  let end = normalized.length;
22638
22654
  while (end > 0 && normalized[end - 1] === "/") {
22639
22655
  end--;
@@ -22879,27 +22895,27 @@ var require_send = __commonJS({
22879
22895
  var ms = require_ms();
22880
22896
  var onFinished = require_on_finished();
22881
22897
  var parseRange = require_range_parser();
22882
- var path2 = __require("path");
22898
+ var path4 = __require("path");
22883
22899
  var statuses = require_statuses();
22884
22900
  var Stream = __require("stream");
22885
22901
  var util2 = __require("util");
22886
- var extname = path2.extname;
22887
- var join = path2.join;
22888
- var normalize = path2.normalize;
22889
- var resolve = path2.resolve;
22890
- var sep = path2.sep;
22902
+ var extname = path4.extname;
22903
+ var join = path4.join;
22904
+ var normalize = path4.normalize;
22905
+ var resolve = path4.resolve;
22906
+ var sep = path4.sep;
22891
22907
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
22892
22908
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
22893
22909
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
22894
22910
  module.exports = send;
22895
- function send(req, path3, options) {
22896
- return new SendStream(req, path3, options);
22911
+ function send(req, path5, options) {
22912
+ return new SendStream(req, path5, options);
22897
22913
  }
22898
- function SendStream(req, path3, options) {
22914
+ function SendStream(req, path5, options) {
22899
22915
  Stream.call(this);
22900
22916
  var opts = options || {};
22901
22917
  this.options = opts;
22902
- this.path = path3;
22918
+ this.path = path5;
22903
22919
  this.req = req;
22904
22920
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
22905
22921
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -23013,10 +23029,10 @@ var require_send = __commonJS({
23013
23029
  var lastModified = this.res.getHeader("Last-Modified");
23014
23030
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
23015
23031
  };
23016
- SendStream.prototype.redirect = function redirect2(path3) {
23032
+ SendStream.prototype.redirect = function redirect2(path5) {
23017
23033
  var res = this.res;
23018
23034
  if (hasListeners(this, "directory")) {
23019
- this.emit("directory", res, path3);
23035
+ this.emit("directory", res, path5);
23020
23036
  return;
23021
23037
  }
23022
23038
  if (this.hasTrailingSlash()) {
@@ -23036,38 +23052,38 @@ var require_send = __commonJS({
23036
23052
  SendStream.prototype.pipe = function pipe2(res) {
23037
23053
  var root = this._root;
23038
23054
  this.res = res;
23039
- var path3 = decode3(this.path);
23040
- if (path3 === -1) {
23055
+ var path5 = decode3(this.path);
23056
+ if (path5 === -1) {
23041
23057
  this.error(400);
23042
23058
  return res;
23043
23059
  }
23044
- if (~path3.indexOf("\0")) {
23060
+ if (~path5.indexOf("\0")) {
23045
23061
  this.error(400);
23046
23062
  return res;
23047
23063
  }
23048
23064
  var parts;
23049
23065
  if (root !== null) {
23050
- if (path3) {
23051
- path3 = normalize("." + sep + path3);
23066
+ if (path5) {
23067
+ path5 = normalize("." + sep + path5);
23052
23068
  }
23053
- if (UP_PATH_REGEXP.test(path3)) {
23054
- debug('malicious path "%s"', path3);
23069
+ if (UP_PATH_REGEXP.test(path5)) {
23070
+ debug('malicious path "%s"', path5);
23055
23071
  this.error(403);
23056
23072
  return res;
23057
23073
  }
23058
- parts = path3.split(sep);
23059
- path3 = normalize(join(root, path3));
23074
+ parts = path5.split(sep);
23075
+ path5 = normalize(join(root, path5));
23060
23076
  } else {
23061
- if (UP_PATH_REGEXP.test(path3)) {
23062
- debug('malicious path "%s"', path3);
23077
+ if (UP_PATH_REGEXP.test(path5)) {
23078
+ debug('malicious path "%s"', path5);
23063
23079
  this.error(403);
23064
23080
  return res;
23065
23081
  }
23066
- parts = normalize(path3).split(sep);
23067
- path3 = resolve(path3);
23082
+ parts = normalize(path5).split(sep);
23083
+ path5 = resolve(path5);
23068
23084
  }
23069
23085
  if (containsDotFile(parts)) {
23070
- debug('%s dotfile "%s"', this._dotfiles, path3);
23086
+ debug('%s dotfile "%s"', this._dotfiles, path5);
23071
23087
  switch (this._dotfiles) {
23072
23088
  case "allow":
23073
23089
  break;
@@ -23081,13 +23097,13 @@ var require_send = __commonJS({
23081
23097
  }
23082
23098
  }
23083
23099
  if (this._index.length && this.hasTrailingSlash()) {
23084
- this.sendIndex(path3);
23100
+ this.sendIndex(path5);
23085
23101
  return res;
23086
23102
  }
23087
- this.sendFile(path3);
23103
+ this.sendFile(path5);
23088
23104
  return res;
23089
23105
  };
23090
- SendStream.prototype.send = function send2(path3, stat) {
23106
+ SendStream.prototype.send = function send2(path5, stat) {
23091
23107
  var len = stat.size;
23092
23108
  var options = this.options;
23093
23109
  var opts = {};
@@ -23099,9 +23115,9 @@ var require_send = __commonJS({
23099
23115
  this.headersAlreadySent();
23100
23116
  return;
23101
23117
  }
23102
- debug('pipe "%s"', path3);
23103
- this.setHeader(path3, stat);
23104
- this.type(path3);
23118
+ debug('pipe "%s"', path5);
23119
+ this.setHeader(path5, stat);
23120
+ this.type(path5);
23105
23121
  if (this.isConditionalGET()) {
23106
23122
  if (this.isPreconditionFailure()) {
23107
23123
  this.error(412);
@@ -23150,28 +23166,28 @@ var require_send = __commonJS({
23150
23166
  res.end();
23151
23167
  return;
23152
23168
  }
23153
- this.stream(path3, opts);
23169
+ this.stream(path5, opts);
23154
23170
  };
23155
- SendStream.prototype.sendFile = function sendFile(path3) {
23171
+ SendStream.prototype.sendFile = function sendFile(path5) {
23156
23172
  var i = 0;
23157
23173
  var self = this;
23158
- debug('stat "%s"', path3);
23159
- fs.stat(path3, function onstat(err, stat) {
23160
- var pathEndsWithSep = path3[path3.length - 1] === sep;
23161
- if (err && err.code === "ENOENT" && !extname(path3) && !pathEndsWithSep) {
23174
+ debug('stat "%s"', path5);
23175
+ fs.stat(path5, function onstat(err, stat) {
23176
+ var pathEndsWithSep = path5[path5.length - 1] === sep;
23177
+ if (err && err.code === "ENOENT" && !extname(path5) && !pathEndsWithSep) {
23162
23178
  return next(err);
23163
23179
  }
23164
23180
  if (err) return self.onStatError(err);
23165
- if (stat.isDirectory()) return self.redirect(path3);
23181
+ if (stat.isDirectory()) return self.redirect(path5);
23166
23182
  if (pathEndsWithSep) return self.error(404);
23167
- self.emit("file", path3, stat);
23168
- self.send(path3, stat);
23183
+ self.emit("file", path5, stat);
23184
+ self.send(path5, stat);
23169
23185
  });
23170
23186
  function next(err) {
23171
23187
  if (self._extensions.length <= i) {
23172
23188
  return err ? self.onStatError(err) : self.error(404);
23173
23189
  }
23174
- var p = path3 + "." + self._extensions[i++];
23190
+ var p = path5 + "." + self._extensions[i++];
23175
23191
  debug('stat "%s"', p);
23176
23192
  fs.stat(p, function(err2, stat) {
23177
23193
  if (err2) return next(err2);
@@ -23181,7 +23197,7 @@ var require_send = __commonJS({
23181
23197
  });
23182
23198
  }
23183
23199
  };
23184
- SendStream.prototype.sendIndex = function sendIndex(path3) {
23200
+ SendStream.prototype.sendIndex = function sendIndex(path5) {
23185
23201
  var i = -1;
23186
23202
  var self = this;
23187
23203
  function next(err) {
@@ -23189,7 +23205,7 @@ var require_send = __commonJS({
23189
23205
  if (err) return self.onStatError(err);
23190
23206
  return self.error(404);
23191
23207
  }
23192
- var p = join(path3, self._index[i]);
23208
+ var p = join(path5, self._index[i]);
23193
23209
  debug('stat "%s"', p);
23194
23210
  fs.stat(p, function(err2, stat) {
23195
23211
  if (err2) return next(err2);
@@ -23200,10 +23216,10 @@ var require_send = __commonJS({
23200
23216
  }
23201
23217
  next();
23202
23218
  };
23203
- SendStream.prototype.stream = function stream(path3, options) {
23219
+ SendStream.prototype.stream = function stream(path5, options) {
23204
23220
  var self = this;
23205
23221
  var res = this.res;
23206
- var stream2 = fs.createReadStream(path3, options);
23222
+ var stream2 = fs.createReadStream(path5, options);
23207
23223
  this.emit("stream", stream2);
23208
23224
  stream2.pipe(res);
23209
23225
  function cleanup() {
@@ -23218,17 +23234,17 @@ var require_send = __commonJS({
23218
23234
  self.emit("end");
23219
23235
  });
23220
23236
  };
23221
- SendStream.prototype.type = function type(path3) {
23237
+ SendStream.prototype.type = function type(path5) {
23222
23238
  var res = this.res;
23223
23239
  if (res.getHeader("Content-Type")) return;
23224
- var ext = extname(path3);
23240
+ var ext = extname(path5);
23225
23241
  var type2 = mime.contentType(ext) || "application/octet-stream";
23226
23242
  debug("content-type %s", type2);
23227
23243
  res.setHeader("Content-Type", type2);
23228
23244
  };
23229
- SendStream.prototype.setHeader = function setHeader(path3, stat) {
23245
+ SendStream.prototype.setHeader = function setHeader(path5, stat) {
23230
23246
  var res = this.res;
23231
- this.emit("headers", res, path3, stat);
23247
+ this.emit("headers", res, path5, stat);
23232
23248
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
23233
23249
  debug("accept ranges");
23234
23250
  res.setHeader("Accept-Ranges", "bytes");
@@ -23286,9 +23302,9 @@ var require_send = __commonJS({
23286
23302
  }
23287
23303
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
23288
23304
  }
23289
- function decode3(path3) {
23305
+ function decode3(path5) {
23290
23306
  try {
23291
- return decodeURIComponent(path3);
23307
+ return decodeURIComponent(path5);
23292
23308
  } catch (err) {
23293
23309
  return -1;
23294
23310
  }
@@ -23432,7 +23448,7 @@ var require_response = __commonJS({
23432
23448
  var http = __require("node:http");
23433
23449
  var onFinished = require_on_finished();
23434
23450
  var mime = require_mime_types();
23435
- var path2 = __require("node:path");
23451
+ var path4 = __require("node:path");
23436
23452
  var pathIsAbsolute = __require("node:path").isAbsolute;
23437
23453
  var statuses = require_statuses();
23438
23454
  var sign = require_cookie_signature().sign;
@@ -23441,8 +23457,8 @@ var require_response = __commonJS({
23441
23457
  var setCharset = require_utils3().setCharset;
23442
23458
  var cookie = require_cookie();
23443
23459
  var send = require_send();
23444
- var extname = path2.extname;
23445
- var resolve = path2.resolve;
23460
+ var extname = path4.extname;
23461
+ var resolve = path4.resolve;
23446
23462
  var vary = require_vary();
23447
23463
  var { Buffer: Buffer2 } = __require("node:buffer");
23448
23464
  var res = Object.create(http.ServerResponse.prototype);
@@ -23588,26 +23604,26 @@ var require_response = __commonJS({
23588
23604
  this.type("txt");
23589
23605
  return this.send(body);
23590
23606
  };
23591
- res.sendFile = function sendFile(path3, options, callback) {
23607
+ res.sendFile = function sendFile(path5, options, callback) {
23592
23608
  var done = callback;
23593
23609
  var req = this.req;
23594
23610
  var res2 = this;
23595
23611
  var next = req.next;
23596
23612
  var opts = options || {};
23597
- if (!path3) {
23613
+ if (!path5) {
23598
23614
  throw new TypeError("path argument is required to res.sendFile");
23599
23615
  }
23600
- if (typeof path3 !== "string") {
23616
+ if (typeof path5 !== "string") {
23601
23617
  throw new TypeError("path must be a string to res.sendFile");
23602
23618
  }
23603
23619
  if (typeof options === "function") {
23604
23620
  done = options;
23605
23621
  opts = {};
23606
23622
  }
23607
- if (!opts.root && !pathIsAbsolute(path3)) {
23623
+ if (!opts.root && !pathIsAbsolute(path5)) {
23608
23624
  throw new TypeError("path must be absolute or specify root to res.sendFile");
23609
23625
  }
23610
- var pathname = encodeURI(path3);
23626
+ var pathname = encodeURI(path5);
23611
23627
  opts.etag = this.app.enabled("etag");
23612
23628
  var file2 = send(req, pathname, opts);
23613
23629
  sendfile(res2, file2, opts, function(err) {
@@ -23618,7 +23634,7 @@ var require_response = __commonJS({
23618
23634
  }
23619
23635
  });
23620
23636
  };
23621
- res.download = function download(path3, filename, options, callback) {
23637
+ res.download = function download(path5, filename, options, callback) {
23622
23638
  var done = callback;
23623
23639
  var name = filename;
23624
23640
  var opts = options || null;
@@ -23635,7 +23651,7 @@ var require_response = __commonJS({
23635
23651
  opts = filename;
23636
23652
  }
23637
23653
  var headers = {
23638
- "Content-Disposition": contentDisposition(name || path3)
23654
+ "Content-Disposition": contentDisposition(name || path5)
23639
23655
  };
23640
23656
  if (opts && opts.headers) {
23641
23657
  var keys = Object.keys(opts.headers);
@@ -23648,7 +23664,7 @@ var require_response = __commonJS({
23648
23664
  }
23649
23665
  opts = Object.create(opts);
23650
23666
  opts.headers = headers;
23651
- var fullPath = !opts.root ? resolve(path3) : path3;
23667
+ var fullPath = !opts.root ? resolve(path5) : path5;
23652
23668
  return this.sendFile(fullPath, opts, done);
23653
23669
  };
23654
23670
  res.contentType = res.type = function contentType3(type) {
@@ -23931,11 +23947,11 @@ var require_serve_static = __commonJS({
23931
23947
  }
23932
23948
  var forwardError = !fallthrough;
23933
23949
  var originalUrl = parseUrl.original(req);
23934
- var path2 = parseUrl(req).pathname;
23935
- if (path2 === "/" && originalUrl.pathname.substr(-1) !== "/") {
23936
- path2 = "";
23950
+ var path4 = parseUrl(req).pathname;
23951
+ if (path4 === "/" && originalUrl.pathname.substr(-1) !== "/") {
23952
+ path4 = "";
23937
23953
  }
23938
- var stream = send(req, path2, opts);
23954
+ var stream = send(req, path4, opts);
23939
23955
  stream.on("directory", onDirectory);
23940
23956
  if (setHeaders) {
23941
23957
  stream.on("headers", setHeaders);
@@ -24419,11 +24435,11 @@ var require_codegen = __commonJS({
24419
24435
  const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
24420
24436
  return `${varKind} ${this.name}${rhs};` + _n;
24421
24437
  }
24422
- optimizeNames(names, constants3) {
24438
+ optimizeNames(names, constants2) {
24423
24439
  if (!names[this.name.str])
24424
24440
  return;
24425
24441
  if (this.rhs)
24426
- this.rhs = optimizeExpr(this.rhs, names, constants3);
24442
+ this.rhs = optimizeExpr(this.rhs, names, constants2);
24427
24443
  return this;
24428
24444
  }
24429
24445
  get names() {
@@ -24440,10 +24456,10 @@ var require_codegen = __commonJS({
24440
24456
  render({ _n }) {
24441
24457
  return `${this.lhs} = ${this.rhs};` + _n;
24442
24458
  }
24443
- optimizeNames(names, constants3) {
24459
+ optimizeNames(names, constants2) {
24444
24460
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
24445
24461
  return;
24446
- this.rhs = optimizeExpr(this.rhs, names, constants3);
24462
+ this.rhs = optimizeExpr(this.rhs, names, constants2);
24447
24463
  return this;
24448
24464
  }
24449
24465
  get names() {
@@ -24504,8 +24520,8 @@ var require_codegen = __commonJS({
24504
24520
  optimizeNodes() {
24505
24521
  return `${this.code}` ? this : void 0;
24506
24522
  }
24507
- optimizeNames(names, constants3) {
24508
- this.code = optimizeExpr(this.code, names, constants3);
24523
+ optimizeNames(names, constants2) {
24524
+ this.code = optimizeExpr(this.code, names, constants2);
24509
24525
  return this;
24510
24526
  }
24511
24527
  get names() {
@@ -24534,12 +24550,12 @@ var require_codegen = __commonJS({
24534
24550
  }
24535
24551
  return nodes.length > 0 ? this : void 0;
24536
24552
  }
24537
- optimizeNames(names, constants3) {
24553
+ optimizeNames(names, constants2) {
24538
24554
  const { nodes } = this;
24539
24555
  let i = nodes.length;
24540
24556
  while (i--) {
24541
24557
  const n = nodes[i];
24542
- if (n.optimizeNames(names, constants3))
24558
+ if (n.optimizeNames(names, constants2))
24543
24559
  continue;
24544
24560
  subtractNames(names, n.names);
24545
24561
  nodes.splice(i, 1);
@@ -24592,12 +24608,12 @@ var require_codegen = __commonJS({
24592
24608
  return void 0;
24593
24609
  return this;
24594
24610
  }
24595
- optimizeNames(names, constants3) {
24611
+ optimizeNames(names, constants2) {
24596
24612
  var _a3;
24597
- this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants3);
24598
- if (!(super.optimizeNames(names, constants3) || this.else))
24613
+ this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants2);
24614
+ if (!(super.optimizeNames(names, constants2) || this.else))
24599
24615
  return;
24600
- this.condition = optimizeExpr(this.condition, names, constants3);
24616
+ this.condition = optimizeExpr(this.condition, names, constants2);
24601
24617
  return this;
24602
24618
  }
24603
24619
  get names() {
@@ -24620,10 +24636,10 @@ var require_codegen = __commonJS({
24620
24636
  render(opts) {
24621
24637
  return `for(${this.iteration})` + super.render(opts);
24622
24638
  }
24623
- optimizeNames(names, constants3) {
24624
- if (!super.optimizeNames(names, constants3))
24639
+ optimizeNames(names, constants2) {
24640
+ if (!super.optimizeNames(names, constants2))
24625
24641
  return;
24626
- this.iteration = optimizeExpr(this.iteration, names, constants3);
24642
+ this.iteration = optimizeExpr(this.iteration, names, constants2);
24627
24643
  return this;
24628
24644
  }
24629
24645
  get names() {
@@ -24659,10 +24675,10 @@ var require_codegen = __commonJS({
24659
24675
  render(opts) {
24660
24676
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
24661
24677
  }
24662
- optimizeNames(names, constants3) {
24663
- if (!super.optimizeNames(names, constants3))
24678
+ optimizeNames(names, constants2) {
24679
+ if (!super.optimizeNames(names, constants2))
24664
24680
  return;
24665
- this.iterable = optimizeExpr(this.iterable, names, constants3);
24681
+ this.iterable = optimizeExpr(this.iterable, names, constants2);
24666
24682
  return this;
24667
24683
  }
24668
24684
  get names() {
@@ -24704,11 +24720,11 @@ var require_codegen = __commonJS({
24704
24720
  (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
24705
24721
  return this;
24706
24722
  }
24707
- optimizeNames(names, constants3) {
24723
+ optimizeNames(names, constants2) {
24708
24724
  var _a3, _b;
24709
- super.optimizeNames(names, constants3);
24710
- (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants3);
24711
- (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants3);
24725
+ super.optimizeNames(names, constants2);
24726
+ (_a3 = this.catch) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants2);
24727
+ (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants2);
24712
24728
  return this;
24713
24729
  }
24714
24730
  get names() {
@@ -25009,7 +25025,7 @@ var require_codegen = __commonJS({
25009
25025
  function addExprNames(names, from) {
25010
25026
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
25011
25027
  }
25012
- function optimizeExpr(expr, names, constants3) {
25028
+ function optimizeExpr(expr, names, constants2) {
25013
25029
  if (expr instanceof code_1.Name)
25014
25030
  return replaceName(expr);
25015
25031
  if (!canOptimize(expr))
@@ -25024,14 +25040,14 @@ var require_codegen = __commonJS({
25024
25040
  return items;
25025
25041
  }, []));
25026
25042
  function replaceName(n) {
25027
- const c = constants3[n.str];
25043
+ const c = constants2[n.str];
25028
25044
  if (c === void 0 || names[n.str] !== 1)
25029
25045
  return n;
25030
25046
  delete names[n.str];
25031
25047
  return c;
25032
25048
  }
25033
25049
  function canOptimize(e) {
25034
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants3[c.str] !== void 0);
25050
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants2[c.str] !== void 0);
25035
25051
  }
25036
25052
  }
25037
25053
  function subtractNames(names, from) {
@@ -27271,8 +27287,8 @@ var require_utils4 = __commonJS({
27271
27287
  }
27272
27288
  return ind;
27273
27289
  }
27274
- function removeDotSegments(path2) {
27275
- let input2 = path2;
27290
+ function removeDotSegments(path4) {
27291
+ let input2 = path4;
27276
27292
  const output2 = [];
27277
27293
  let nextSlash = -1;
27278
27294
  let len = 0;
@@ -27681,8 +27697,8 @@ var require_schemes = __commonJS({
27681
27697
  }
27682
27698
  if (wsComponent.resourceName) {
27683
27699
  const queryIndex = wsComponent.resourceName.indexOf("?");
27684
- const path2 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
27685
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
27700
+ const path4 = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
27701
+ wsComponent.path = path4 && path4 !== "/" ? path4 : void 0;
27686
27702
  wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
27687
27703
  wsComponent.resourceName = void 0;
27688
27704
  }
@@ -28157,13 +28173,14 @@ var require_fast_uri = __commonJS({
28157
28173
  if (!malformedIPLiteral) {
28158
28174
  malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
28159
28175
  }
28160
- if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
28161
- if (uri.indexOf("%") !== -1) {
28162
- if (parsed.host !== void 0 && !malformedIPLiteral) {
28163
- const host2 = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
28164
- parsed.host = reescapeHostDelimiters(host2, isIP);
28165
- }
28176
+ if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
28177
+ let host2 = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
28178
+ if (!isIP) {
28179
+ host2 = normalizePercentEncoding(host2.toLowerCase());
28166
28180
  }
28181
+ parsed.host = reescapeHostDelimiters(host2, isIP);
28182
+ }
28183
+ if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
28167
28184
  if (parsed.path) {
28168
28185
  parsed.path = normalizePathEncoding(parsed.path);
28169
28186
  }
@@ -31261,7 +31278,6 @@ function localhostHostValidation() {
31261
31278
  function createMcpExpressApp(options = {}) {
31262
31279
  const { host: host2 = "127.0.0.1", allowedHosts } = options;
31263
31280
  const app2 = (0, import_express.default)();
31264
- app2.use(import_express.default.json());
31265
31281
  if (allowedHosts) {
31266
31282
  app2.use(hostHeaderValidation(allowedHosts));
31267
31283
  } else {
@@ -31272,6 +31288,7 @@ function createMcpExpressApp(options = {}) {
31272
31288
  console.warn(`Warning: Server is binding to ${host2} without DNS rebinding protection. Consider using the allowedHosts option to restrict allowed hosts, or use authentication to protect your server.`);
31273
31289
  }
31274
31290
  }
31291
+ app2.use(import_express.default.json());
31275
31292
  return app2;
31276
31293
  }
31277
31294
 
@@ -32476,6 +32493,50 @@ function isJsonContentType(header) {
32476
32493
  return mediaTypeEssence(header) === "application/json";
32477
32494
  }
32478
32495
 
32496
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/server/requestBody.js
32497
+ var DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
32498
+ var MAX_BATCH_SIZE = 100;
32499
+ function requestBodyTooLargeMessage(maxBytes) {
32500
+ return `Payload Too Large: Request body must not exceed ${maxBytes} bytes`;
32501
+ }
32502
+ function resolveMaxRequestBodySize(value) {
32503
+ if (value === void 0) {
32504
+ return DEFAULT_MAX_REQUEST_BODY_SIZE;
32505
+ }
32506
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
32507
+ throw new RangeError(`maxRequestBodySize must be a positive number of bytes, got ${String(value)}`);
32508
+ }
32509
+ return value;
32510
+ }
32511
+ async function readRequestBody(request, maxBytes = DEFAULT_MAX_REQUEST_BODY_SIZE) {
32512
+ if (Number(request.headers.get("content-length")) > maxBytes) {
32513
+ return { tooLarge: true };
32514
+ }
32515
+ if (request.body === null) {
32516
+ return { tooLarge: false, text: "" };
32517
+ }
32518
+ const reader = request.body.getReader();
32519
+ const decoder = new TextDecoder();
32520
+ let received = 0;
32521
+ let text = "";
32522
+ try {
32523
+ for (; ; ) {
32524
+ const { done, value } = await reader.read();
32525
+ if (done) {
32526
+ break;
32527
+ }
32528
+ received += value.byteLength;
32529
+ if (received > maxBytes) {
32530
+ return { tooLarge: true };
32531
+ }
32532
+ text += decoder.decode(value, { stream: true });
32533
+ }
32534
+ } finally {
32535
+ reader.releaseLock();
32536
+ }
32537
+ return { tooLarge: false, text: text + decoder.decode() };
32538
+ }
32539
+
32479
32540
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
32480
32541
  var DEFAULT_SSE_KEEP_ALIVE_MS = 15e3;
32481
32542
  var MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
@@ -33304,10 +33365,10 @@ function mergeDefs(...defs) {
33304
33365
  function cloneDef(schema) {
33305
33366
  return mergeDefs(schema._zod.def);
33306
33367
  }
33307
- function getElementAtPath(obj, path2) {
33308
- if (!path2)
33368
+ function getElementAtPath(obj, path4) {
33369
+ if (!path4)
33309
33370
  return obj;
33310
- return path2.reduce((acc, key) => acc?.[key], obj);
33371
+ return path4.reduce((acc, key) => acc?.[key], obj);
33311
33372
  }
33312
33373
  function promiseAllObject(promisesObj) {
33313
33374
  const keys = Object.keys(promisesObj);
@@ -33647,11 +33708,11 @@ function explicitlyAborted(x, startIndex = 0) {
33647
33708
  }
33648
33709
  return false;
33649
33710
  }
33650
- function prefixIssues(path2, issues) {
33711
+ function prefixIssues(path4, issues) {
33651
33712
  return issues.map((iss) => {
33652
33713
  var _a3;
33653
33714
  (_a3 = iss).path ?? (_a3.path = []);
33654
- iss.path.unshift(path2);
33715
+ iss.path.unshift(path4);
33655
33716
  return iss;
33656
33717
  });
33657
33718
  }
@@ -34101,16 +34162,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
34101
34162
  }
34102
34163
  function formatError(error62, mapper = (issue2) => issue2.message) {
34103
34164
  const fieldErrors = { _errors: [] };
34104
- const processError = (error63, path2 = []) => {
34165
+ const processError = (error63, path4 = []) => {
34105
34166
  for (const issue2 of error63.issues) {
34106
34167
  if (issue2.code === "invalid_union" && issue2.errors.length) {
34107
- issue2.errors.map((issues) => processError({ issues }, [...path2, ...issue2.path]));
34168
+ issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
34108
34169
  } else if (issue2.code === "invalid_key") {
34109
- processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
34170
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
34110
34171
  } else if (issue2.code === "invalid_element") {
34111
- processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
34172
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
34112
34173
  } else {
34113
- const fullpath = [...path2, ...issue2.path];
34174
+ const fullpath = [...path4, ...issue2.path];
34114
34175
  if (fullpath.length === 0) {
34115
34176
  fieldErrors._errors.push(mapper(issue2));
34116
34177
  } else {
@@ -34149,17 +34210,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
34149
34210
  }
34150
34211
  function treeifyError(error62, mapper = (issue2) => issue2.message) {
34151
34212
  const result = { errors: [] };
34152
- const processError = (error63, path2 = []) => {
34213
+ const processError = (error63, path4 = []) => {
34153
34214
  var _a3;
34154
34215
  for (const issue2 of error63.issues) {
34155
34216
  if (issue2.code === "invalid_union" && issue2.errors.length) {
34156
- issue2.errors.map((issues) => processError({ issues }, [...path2, ...issue2.path]));
34217
+ issue2.errors.map((issues) => processError({ issues }, [...path4, ...issue2.path]));
34157
34218
  } else if (issue2.code === "invalid_key") {
34158
- processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
34219
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
34159
34220
  } else if (issue2.code === "invalid_element") {
34160
- processError({ issues: issue2.issues }, [...path2, ...issue2.path]);
34221
+ processError({ issues: issue2.issues }, [...path4, ...issue2.path]);
34161
34222
  } else {
34162
- const fullpath = [...path2, ...issue2.path];
34223
+ const fullpath = [...path4, ...issue2.path];
34163
34224
  if (fullpath.length === 0) {
34164
34225
  result.errors.push(mapper(issue2));
34165
34226
  continue;
@@ -34198,8 +34259,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
34198
34259
  }
34199
34260
  function toDotPath(_path) {
34200
34261
  const segs = [];
34201
- const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
34202
- for (const seg of path2) {
34262
+ const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
34263
+ for (const seg of path4) {
34203
34264
  if (typeof seg === "number")
34204
34265
  segs.push(`[${seg}]`);
34205
34266
  else if (typeof seg === "symbol")
@@ -51301,13 +51362,13 @@ function resolveRef(ref, ctx) {
51301
51362
  if (!ref.startsWith("#")) {
51302
51363
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
51303
51364
  }
51304
- const path2 = ref.slice(1).split("/").filter(Boolean);
51305
- if (path2.length === 0) {
51365
+ const path4 = ref.slice(1).split("/").filter(Boolean);
51366
+ if (path4.length === 0) {
51306
51367
  return ctx.rootSchema;
51307
51368
  }
51308
51369
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
51309
- if (path2[0] === defsKey) {
51310
- const key = path2[1] === void 0 ? void 0 : decodeJSONPointerSegment(path2[1]);
51370
+ if (path4[0] === defsKey) {
51371
+ const key = path4[1] === void 0 ? void 0 : decodeJSONPointerSegment(path4[1]);
51311
51372
  if (!key || !ctx.defs[key]) {
51312
51373
  throw new Error(`Reference not found: ${ref}`);
51313
51374
  }
@@ -53712,6 +53773,7 @@ var WebStandardStreamableHTTPServerTransport = class {
53712
53773
  this._enableDnsRebindingProtection = options.enableDnsRebindingProtection ?? false;
53713
53774
  this._retryInterval = options.retryInterval;
53714
53775
  this._keepAliveMs = options.keepAliveMs ?? DEFAULT_SSE_KEEP_ALIVE_MS;
53776
+ this._maxRequestBodySize = resolveMaxRequestBodySize(options.maxRequestBodySize);
53715
53777
  }
53716
53778
  /**
53717
53779
  * Arms a keep-alive interval for an SSE stream that periodically writes an SSE
@@ -54073,12 +54135,22 @@ data:
54073
54135
  rawMessage = options.parsedBody;
54074
54136
  } else {
54075
54137
  try {
54076
- rawMessage = await req.json();
54138
+ const body = await readRequestBody(req, this._maxRequestBodySize);
54139
+ if (body.tooLarge) {
54140
+ const message = requestBodyTooLargeMessage(this._maxRequestBodySize);
54141
+ this.onerror?.(new Error(message));
54142
+ return this.createJsonErrorResponse(413, -32e3, message);
54143
+ }
54144
+ rawMessage = JSON.parse(body.text);
54077
54145
  } catch {
54078
54146
  this.onerror?.(new Error("Parse error: Invalid JSON"));
54079
54147
  return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON");
54080
54148
  }
54081
54149
  }
54150
+ if (Array.isArray(rawMessage) && rawMessage.length > MAX_BATCH_SIZE) {
54151
+ this.onerror?.(new Error(`Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE} messages`));
54152
+ return this.createJsonErrorResponse(400, -32600, `Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE} messages`);
54153
+ }
54082
54154
  let messages;
54083
54155
  try {
54084
54156
  if (Array.isArray(rawMessage)) {
@@ -54523,9 +54595,6 @@ var StreamableHTTPServerTransport = class {
54523
54595
  }
54524
54596
  };
54525
54597
 
54526
- // src/server.ts
54527
- import { readdir, writeFile } from "node:fs/promises";
54528
-
54529
54598
  // node_modules/zod/v3/helpers/util.js
54530
54599
  var util;
54531
54600
  (function(util2) {
@@ -54900,8 +54969,8 @@ function getErrorMap2() {
54900
54969
 
54901
54970
  // node_modules/zod/v3/helpers/parseUtil.js
54902
54971
  var makeIssue = (params) => {
54903
- const { data, path: path2, errorMaps, issueData } = params;
54904
- const fullPath = [...path2, ...issueData.path || []];
54972
+ const { data, path: path4, errorMaps, issueData } = params;
54973
+ const fullPath = [...path4, ...issueData.path || []];
54905
54974
  const fullIssue = {
54906
54975
  ...issueData,
54907
54976
  path: fullPath
@@ -55016,11 +55085,11 @@ var errorUtil;
55016
55085
 
55017
55086
  // node_modules/zod/v3/types.js
55018
55087
  var ParseInputLazyPath = class {
55019
- constructor(parent, value, path2, key) {
55088
+ constructor(parent, value, path4, key) {
55020
55089
  this._cachedPath = [];
55021
55090
  this.parent = parent;
55022
55091
  this.data = value;
55023
- this._path = path2;
55092
+ this._path = path4;
55024
55093
  this._key = key;
55025
55094
  }
55026
55095
  get path() {
@@ -58571,11 +58640,11 @@ function normalizeObjectSchema(schema) {
58571
58640
  }
58572
58641
  return void 0;
58573
58642
  }
58574
- function getDotPath(path2) {
58575
- if (path2.length === 0) {
58643
+ function getDotPath(path4) {
58644
+ if (path4.length === 0) {
58576
58645
  return "object root";
58577
58646
  }
58578
- return path2.reduce((acc, seg, index) => {
58647
+ return path4.reduce((acc, seg, index) => {
58579
58648
  if (index === 0) {
58580
58649
  return String(seg);
58581
58650
  }
@@ -60019,6 +60088,9 @@ var Protocol = class {
60019
60088
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
60020
60089
  const handleTaskResult = async () => {
60021
60090
  const taskId = request.params.taskId;
60091
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
60092
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
60093
+ }
60022
60094
  if (this._taskMessageQueue) {
60023
60095
  let queuedMessage;
60024
60096
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -60049,12 +60121,12 @@ var Protocol = class {
60049
60121
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
60050
60122
  }
60051
60123
  if (!isTerminal(task.status)) {
60052
- await this._waitForTaskUpdate(taskId, extra.signal);
60124
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
60053
60125
  return await handleTaskResult();
60054
60126
  }
60055
60127
  if (isTerminal(task.status)) {
60056
60128
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
60057
- this._clearTaskQueue(taskId);
60129
+ this._clearTaskQueue(taskId, extra.sessionId);
60058
60130
  return {
60059
60131
  ...result,
60060
60132
  _meta: {
@@ -60091,7 +60163,7 @@ var Protocol = class {
60091
60163
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
60092
60164
  }
60093
60165
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
60094
- this._clearTaskQueue(request.params.taskId);
60166
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
60095
60167
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
60096
60168
  if (!cancelledTask) {
60097
60169
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -60219,6 +60291,19 @@ var Protocol = class {
60219
60291
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
60220
60292
  const capturedTransport = this._transport;
60221
60293
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
60294
+ const sessionId = capturedTransport?.sessionId;
60295
+ const store = this._taskStore;
60296
+ let relatedTaskFound = true;
60297
+ let relatedTaskLookup;
60298
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
60299
+ relatedTaskFound = false;
60300
+ relatedTaskLookup = (async () => {
60301
+ if (!await store.getTask(relatedTaskId, sessionId)) {
60302
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
60303
+ }
60304
+ relatedTaskFound = true;
60305
+ })();
60306
+ }
60222
60307
  if (handler === void 0) {
60223
60308
  const errorResponse = {
60224
60309
  jsonrpc: "2.0",
@@ -60228,7 +60313,10 @@ var Protocol = class {
60228
60313
  message: "Method not found"
60229
60314
  }
60230
60315
  };
60231
- if (relatedTaskId && this._taskMessageQueue) {
60316
+ if (relatedTaskId && relatedTaskLookup) {
60317
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
60318
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error62) => this._onerror(new Error(`Failed to send an error response: ${error62}`)));
60319
+ } else if (relatedTaskId && this._taskMessageQueue) {
60232
60320
  this._enqueueTaskMessage(relatedTaskId, {
60233
60321
  type: "error",
60234
60322
  message: errorResponse,
@@ -60279,7 +60367,10 @@ var Protocol = class {
60279
60367
  closeSSEStream: extra?.closeSSEStream,
60280
60368
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
60281
60369
  };
60282
- Promise.resolve().then(() => {
60370
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
60371
+ if (relatedTaskLookup && abortController.signal.aborted) {
60372
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
60373
+ }
60283
60374
  if (taskCreationParams) {
60284
60375
  this.assertTaskHandlerCapability(request.method);
60285
60376
  }
@@ -60314,7 +60405,7 @@ var Protocol = class {
60314
60405
  ...error62["data"] !== void 0 && { data: error62["data"] }
60315
60406
  }
60316
60407
  };
60317
- if (relatedTaskId && this._taskMessageQueue) {
60408
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
60318
60409
  await this._enqueueTaskMessage(relatedTaskId, {
60319
60410
  type: "error",
60320
60411
  message: errorResponse,
@@ -60794,7 +60885,7 @@ var Protocol = class {
60794
60885
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
60795
60886
  }
60796
60887
  const maxQueueSize = this._options?.maxTaskQueueSize;
60797
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
60888
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
60798
60889
  }
60799
60890
  /**
60800
60891
  * Clears the message queue for a task and rejects any pending request resolvers.
@@ -60823,12 +60914,13 @@ var Protocol = class {
60823
60914
  * Uses polling to check for updates at the task's configured poll interval.
60824
60915
  * @param taskId The task ID to wait for
60825
60916
  * @param signal Abort signal to cancel the wait
60917
+ * @param sessionId Session of the request that waits, passed to the task store
60826
60918
  * @returns Promise that resolves when an update occurs or rejects if aborted
60827
60919
  */
60828
- async _waitForTaskUpdate(taskId, signal) {
60920
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
60829
60921
  let interval = this._options?.defaultTaskPollInterval ?? 1e3;
60830
60922
  try {
60831
- const task = await this._taskStore?.getTask(taskId);
60923
+ const task = await this._taskStore?.getTask(taskId, sessionId);
60832
60924
  if (task?.pollInterval) {
60833
60925
  interval = task.pollInterval;
60834
60926
  }
@@ -61707,6 +61799,42 @@ var ExperimentalMcpServerTasks = class {
61707
61799
  };
61708
61800
 
61709
61801
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
61802
+ function toolInputElementCount(value, max) {
61803
+ let count = 0;
61804
+ const stack = [value];
61805
+ while (stack.length > 0) {
61806
+ const node2 = stack.pop();
61807
+ if (node2 === null || typeof node2 !== "object")
61808
+ continue;
61809
+ if (Array.isArray(node2)) {
61810
+ for (const child of node2) {
61811
+ if (++count > max)
61812
+ return count;
61813
+ if (child !== null && typeof child === "object")
61814
+ stack.push(child);
61815
+ }
61816
+ } else {
61817
+ for (const key in node2) {
61818
+ if (!Object.prototype.hasOwnProperty.call(node2, key))
61819
+ continue;
61820
+ if (++count > max)
61821
+ return count;
61822
+ const child = node2[key];
61823
+ if (child !== null && typeof child === "object")
61824
+ stack.push(child);
61825
+ }
61826
+ }
61827
+ }
61828
+ return count;
61829
+ }
61830
+ function resolveMaxToolInputElements(value) {
61831
+ if (value === void 0 || value === Infinity)
61832
+ return void 0;
61833
+ if (typeof value !== "number" || Number.isNaN(value) || value < 1) {
61834
+ throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
61835
+ }
61836
+ return value;
61837
+ }
61710
61838
  var McpServer = class {
61711
61839
  constructor(serverInfo, options) {
61712
61840
  this._registeredResources = {};
@@ -61718,6 +61846,7 @@ var McpServer = class {
61718
61846
  this._resourceHandlersInitialized = false;
61719
61847
  this._promptHandlersInitialized = false;
61720
61848
  this.server = new Server(serverInfo, options);
61849
+ this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
61721
61850
  }
61722
61851
  /**
61723
61852
  * Access experimental features.
@@ -61848,12 +61977,15 @@ var McpServer = class {
61848
61977
  * Validates tool input arguments against the tool's input schema.
61849
61978
  */
61850
61979
  async validateToolInput(tool, args, toolName) {
61980
+ if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) {
61981
+ throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
61982
+ }
61851
61983
  if (!tool.inputSchema) {
61852
61984
  return void 0;
61853
61985
  }
61854
61986
  const inputObj = normalizeObjectSchema(tool.inputSchema);
61855
61987
  const schemaToParse = inputObj ?? tool.inputSchema;
61856
- const parseResult = await safeParseAsync3(schemaToParse, args);
61988
+ const parseResult = await safeParseAsync3(schemaToParse, args ?? {});
61857
61989
  if (!parseResult.success) {
61858
61990
  const error62 = "error" in parseResult ? parseResult.error : "Unknown error";
61859
61991
  const errorMessage = getParseErrorMessage(error62);
@@ -62091,7 +62223,7 @@ var McpServer = class {
62091
62223
  }
62092
62224
  if (prompt.argsSchema) {
62093
62225
  const argsObj = normalizeObjectSchema(prompt.argsSchema);
62094
- const parseResult = await safeParseAsync3(argsObj, request.params.arguments);
62226
+ const parseResult = await safeParseAsync3(argsObj, request.params.arguments ?? {});
62095
62227
  if (!parseResult.success) {
62096
62228
  const error62 = "error" in parseResult ? parseResult.error : "Unknown error";
62097
62229
  const errorMessage = getParseErrorMessage(error62);
@@ -62498,14 +62630,28 @@ var EMPTY_COMPLETION_RESULT = {
62498
62630
  }
62499
62631
  };
62500
62632
 
62501
- // src/runner.ts
62502
- import { execFile } from "node:child_process";
62503
- import { promisify } from "node:util";
62633
+ // src/process-manager.ts
62634
+ import { randomUUID } from "node:crypto";
62635
+ import {
62636
+ closeSync,
62637
+ fsyncSync,
62638
+ mkdirSync,
62639
+ openSync,
62640
+ readFileSync,
62641
+ renameSync,
62642
+ rmSync,
62643
+ writeFileSync
62644
+ } from "node:fs";
62645
+ import path3 from "node:path";
62646
+ import { spawn as spawn2 } from "node:child_process";
62647
+
62648
+ // src/rooted-filesystem.ts
62649
+ import { spawn } from "node:child_process";
62650
+ import { realpathSync, statSync } from "node:fs";
62651
+ import path2 from "node:path";
62652
+ import { fileURLToPath } from "node:url";
62504
62653
 
62505
62654
  // src/security.ts
62506
- import { constants as constants2 } from "node:fs";
62507
- import { access, lstat, realpath } from "node:fs/promises";
62508
- import os from "node:os";
62509
62655
  import path from "node:path";
62510
62656
  var DEFAULT_ENVIRONMENT_KEYS = [
62511
62657
  "LANG",
@@ -62538,34 +62684,7 @@ function configuredRoots(raw = process.env.MACHINE_TERMINAL_ROOTS) {
62538
62684
  }
62539
62685
  function isWithinRoot(candidate, root) {
62540
62686
  const relative = path.relative(root, candidate);
62541
- return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== "..";
62542
- }
62543
- async function resolveReadablePath(requestedPath, roots2, cwd = roots2[0] ?? os.homedir()) {
62544
- const resolvedRoots = await Promise.all(roots2.map((root) => realpath(root)));
62545
- const candidate = await realpath(path.resolve(cwd, requestedPath));
62546
- if (!resolvedRoots.some((root) => isWithinRoot(candidate, root))) {
62547
- throw new Error("Path is outside MACHINE_TERMINAL_ROOTS.");
62548
- }
62549
- await access(candidate, constants2.R_OK);
62550
- return candidate;
62551
- }
62552
- async function resolveWritablePath(requestedPath, roots2, cwd = roots2[0] ?? os.homedir()) {
62553
- const absolute = path.resolve(cwd, requestedPath);
62554
- const resolvedParent = await realpath(path.dirname(absolute));
62555
- const resolvedRoots = await Promise.all(roots2.map((root) => realpath(root)));
62556
- const candidate = path.join(resolvedParent, path.basename(absolute));
62557
- if (!resolvedRoots.some((root) => isWithinRoot(candidate, root))) {
62558
- throw new Error("Path is outside MACHINE_TERMINAL_ROOTS.");
62559
- }
62560
- try {
62561
- const stats = await lstat(candidate);
62562
- if (stats.isSymbolicLink()) {
62563
- throw new Error("Writing through symbolic links is not allowed.");
62564
- }
62565
- } catch (error62) {
62566
- if (error62.code !== "ENOENT") throw error62;
62567
- }
62568
- return candidate;
62687
+ return relative === "" || !path.isAbsolute(relative) && !relative.startsWith(`..${path.sep}`) && relative !== "..";
62569
62688
  }
62570
62689
  function safeEnvironment(source = process.env) {
62571
62690
  return Object.fromEntries(
@@ -62590,68 +62709,671 @@ function assertProgramAllowed(program) {
62590
62709
  }
62591
62710
  }
62592
62711
 
62593
- // src/runner.ts
62594
- var execFileAsync = promisify(execFile);
62595
- async function runProgram(options) {
62596
- assertProgramAllowed(options.program);
62597
- try {
62598
- const { stdout, stderr } = await execFileAsync(
62599
- options.program,
62600
- options.args,
62601
- {
62602
- cwd: options.cwd,
62603
- env: safeEnvironment(),
62604
- encoding: "utf8",
62605
- maxBuffer: options.maxOutputChars,
62606
- timeout: options.timeoutMs,
62607
- windowsHide: true
62712
+ // src/rooted-filesystem.ts
62713
+ var filesystemHelperPath = fileURLToPath(
62714
+ new URL(
62715
+ `../dist/native/${process.platform}-${process.arch}/fs-helper${process.platform === "win32" ? ".exe" : ""}`,
62716
+ import.meta.url
62717
+ )
62718
+ );
62719
+ var RootedFilesystem = class {
62720
+ roots;
62721
+ #specs;
62722
+ #aliases;
62723
+ #child;
62724
+ #pending = /* @__PURE__ */ new Map();
62725
+ #nextID = 0;
62726
+ #buffer = "";
62727
+ #failure;
62728
+ #initialized = false;
62729
+ ready;
62730
+ constructor(roots2) {
62731
+ if (!roots2.length || roots2.length > 128)
62732
+ throw new Error("ROOTED_FILESYSTEM_ROOT_LIMIT");
62733
+ this.#aliases = roots2.map((root) => path2.resolve(root));
62734
+ this.#specs = roots2.map((root) => {
62735
+ const name = realpathSync(root);
62736
+ const info = statSync(name, { bigint: true });
62737
+ if (!info.isDirectory())
62738
+ throw new Error("ROOTED_FILESYSTEM_EXPECTED_DIRECTORY");
62739
+ return { path: name, dev: info.dev.toString(), ino: info.ino.toString() };
62740
+ });
62741
+ this.roots = this.#specs.map((root) => root.path);
62742
+ this.#child = spawn(filesystemHelperPath, [], {
62743
+ stdio: ["pipe", "pipe", "pipe"],
62744
+ windowsHide: true,
62745
+ env: safeEnvironment()
62746
+ });
62747
+ this.#child.stderr.resume();
62748
+ this.#child.on(
62749
+ "error",
62750
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_HELPER_UNAVAILABLE"))
62751
+ );
62752
+ this.#child.on(
62753
+ "close",
62754
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_HELPER_CLOSED"))
62755
+ );
62756
+ this.#child.stdin.on(
62757
+ "error",
62758
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_HELPER_CLOSED"))
62759
+ );
62760
+ this.#child.stdout.on(
62761
+ "error",
62762
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_HELPER_CLOSED"))
62763
+ );
62764
+ this.#child.stderr.on(
62765
+ "error",
62766
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_HELPER_CLOSED"))
62767
+ );
62768
+ this.#child.stdout.setEncoding("utf8");
62769
+ this.#child.stdout.on("data", (data) => {
62770
+ this.#buffer += data;
62771
+ if (Buffer.byteLength(this.#buffer) > 4 * 1024 * 1024) {
62772
+ this.#fail(new Error("ROOTED_FILESYSTEM_REPLY_LIMIT"));
62773
+ return;
62774
+ }
62775
+ let newline;
62776
+ while ((newline = this.#buffer.indexOf("\n")) !== -1) {
62777
+ const line = this.#buffer.slice(0, newline);
62778
+ this.#buffer = this.#buffer.slice(newline + 1);
62779
+ try {
62780
+ const reply = JSON.parse(line);
62781
+ const waiting = this.#pending.get(reply.id);
62782
+ if (!waiting) continue;
62783
+ this.#pending.delete(reply.id);
62784
+ clearTimeout(waiting.timer);
62785
+ if (reply.error) waiting.reject(new Error(reply.error));
62786
+ else waiting.resolve(reply);
62787
+ } catch {
62788
+ this.#fail(new Error("ROOTED_FILESYSTEM_INVALID_REPLY"));
62789
+ return;
62790
+ }
62608
62791
  }
62792
+ this.#referenceWork();
62793
+ });
62794
+ this.ready = this.#request("init", { roots: this.#specs }).then(() => {
62795
+ this.#initialized = true;
62796
+ });
62797
+ void this.ready.catch(() => void 0);
62798
+ }
62799
+ #referenceWork() {
62800
+ const method = this.#pending.size ? "ref" : "unref";
62801
+ this.#child[method]();
62802
+ for (const stream of [
62803
+ this.#child.stdin,
62804
+ this.#child.stdout,
62805
+ this.#child.stderr
62806
+ ])
62807
+ stream[method]();
62808
+ }
62809
+ #fail(error62) {
62810
+ this.#failure ??= error62;
62811
+ for (const waiting of this.#pending.values()) {
62812
+ clearTimeout(waiting.timer);
62813
+ waiting.reject(this.#failure);
62814
+ }
62815
+ this.#pending.clear();
62816
+ this.#child.kill();
62817
+ this.#referenceWork();
62818
+ }
62819
+ #request(operation, values) {
62820
+ if (this.#failure) return Promise.reject(this.#failure);
62821
+ if (this.#pending.size >= 16)
62822
+ return Promise.reject(new Error("ROOTED_FILESYSTEM_PENDING_LIMIT"));
62823
+ const id = ++this.#nextID;
62824
+ const message = JSON.stringify({ id, operation, ...values }) + "\n";
62825
+ if (Buffer.byteLength(message) >= 4 * 1024 * 1024)
62826
+ return Promise.reject(new Error("ROOTED_FILESYSTEM_INPUT_LIMIT"));
62827
+ return new Promise((resolve, reject) => {
62828
+ const timer = setTimeout(
62829
+ () => this.#fail(new Error("ROOTED_FILESYSTEM_TIMEOUT")),
62830
+ 1e4
62831
+ );
62832
+ this.#pending.set(id, { resolve, reject, timer });
62833
+ this.#referenceWork();
62834
+ this.#child.stdin.write(message);
62835
+ });
62836
+ }
62837
+ resolve(requestedPath) {
62838
+ const candidate = path2.resolve(this.#aliases[0], requestedPath);
62839
+ const index = this.roots.findIndex(
62840
+ (root, i) => isWithinRoot(candidate, root) || isWithinRoot(candidate, this.#aliases[i])
62609
62841
  );
62610
- return { exitCode: 0, signal: null, stdout, stderr, timedOut: false };
62611
- } catch (error62) {
62612
- const failure2 = error62;
62842
+ if (index === -1)
62843
+ throw new Error("Path is outside MACHINE_TERMINAL_ROOTS.");
62844
+ const base = isWithinRoot(candidate, this.roots[index]) ? this.roots[index] : this.#aliases[index];
62845
+ const relative = path2.relative(base, candidate) || ".";
62846
+ if (relative.length > 4096) throw new Error("ROOTED_FILESYSTEM_PATH_LIMIT");
62613
62847
  return {
62614
- exitCode: typeof failure2.code === "number" ? failure2.code : null,
62615
- signal: failure2.signal ?? null,
62616
- stdout: failure2.stdout ?? "",
62617
- stderr: failure2.stderr ?? failure2.message,
62618
- timedOut: failure2.killed === true && failure2.signal === "SIGTERM"
62848
+ root: index,
62849
+ path: relative,
62850
+ displayPath: path2.join(this.roots[index], relative)
62619
62851
  };
62620
62852
  }
62621
- }
62622
-
62623
- // src/file-reader.ts
62624
- import { open as open2 } from "node:fs/promises";
62625
- async function readBoundedTextFile(filename, maxCharacters) {
62626
- const handle = await open2(filename, "r");
62627
- try {
62628
- const stats = await handle.stat();
62629
- const buffer = Buffer.allocUnsafe(maxCharacters * 4 + 4);
62630
- const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
62631
- const hasUnreadBytes = bytesRead < stats.size;
62632
- const decoded = new TextDecoder().decode(buffer.subarray(0, bytesRead), {
62633
- stream: hasUnreadBytes
62634
- });
62853
+ async read(target, maxCharacters) {
62854
+ await this.ready;
62855
+ const reply = await this.#request("read", { ...target, maxCharacters });
62856
+ const decoded = new TextDecoder().decode(
62857
+ Buffer.from(reply.bytes ?? "", "base64"),
62858
+ { stream: reply.hasUnread }
62859
+ );
62635
62860
  return {
62636
62861
  contents: decoded.slice(0, maxCharacters),
62637
- truncated: hasUnreadBytes || decoded.length > maxCharacters
62862
+ truncated: reply.hasUnread || decoded.length > maxCharacters
62638
62863
  };
62639
- } finally {
62640
- await handle.close();
62641
62864
  }
62865
+ async write(target, contents, overwrite) {
62866
+ await this.ready;
62867
+ return (await this.#request("write", { ...target, contents, overwrite })).bytesWritten;
62868
+ }
62869
+ async list(target) {
62870
+ await this.ready;
62871
+ const reply = await this.#request("list", { ...target });
62872
+ return { entries: reply.entries ?? [], truncated: reply.truncated };
62873
+ }
62874
+ async execution(requestedPath, program, args) {
62875
+ await this.ready;
62876
+ const target = this.resolve(requestedPath);
62877
+ return {
62878
+ roots: [this.#specs[target.root]],
62879
+ path: target.path,
62880
+ program,
62881
+ args
62882
+ };
62883
+ }
62884
+ async close() {
62885
+ if (this.#child.exitCode !== null || this.#child.signalCode !== null)
62886
+ return;
62887
+ const exited = new Promise(
62888
+ (resolve) => this.#child.once("close", () => resolve())
62889
+ );
62890
+ this.#fail(new Error("ROOTED_FILESYSTEM_CLOSED"));
62891
+ await exited;
62892
+ }
62893
+ get available() {
62894
+ return this.#initialized && !this.#failure;
62895
+ }
62896
+ };
62897
+
62898
+ // src/process-manager.ts
62899
+ var MAX_EVENT_CHARACTERS = 4096;
62900
+ var MAX_RETAINED_EVENTS = 128;
62901
+ var MAX_RETAINED_EVENT_CHARACTERS = 64e3;
62902
+ var LOCAL_SESSION_RETENTION_MS = 60 * 6e4;
62903
+ var MAX_TASK_TOMBSTONES = 2e4;
62904
+ var TASK_RECEIPT_RETENTION_MS = 30 * 24 * 60 * 6e4;
62905
+ var TERMINATION_GRACE_MS = 1500;
62906
+ function appendBounded(current, value, limit) {
62907
+ if (current.length >= limit) return current;
62908
+ return `${current}${value.toString("utf8")}`.slice(0, limit);
62642
62909
  }
62910
+ function snapshot(session) {
62911
+ return {
62912
+ sessionId: session.sessionId,
62913
+ ...session.taskId ? { taskId: session.taskId } : {},
62914
+ program: session.program,
62915
+ args: session.args,
62916
+ cwd: session.cwd,
62917
+ pid: session.child.pid ?? null,
62918
+ running: session.running,
62919
+ exitCode: session.exitCode,
62920
+ signal: session.signal,
62921
+ stdout: session.stdout,
62922
+ stderr: session.stderr,
62923
+ timedOut: session.timedOut
62924
+ };
62925
+ }
62926
+ var ProcessManager = class {
62927
+ constructor(limits = {
62928
+ maxRunning: 32,
62929
+ maxRetained: 512
62930
+ }, receiptFile = process.env.MACHINE_TERMINAL_TASK_RECEIPTS_FILE) {
62931
+ this.limits = limits;
62932
+ this.receiptFile = receiptFile;
62933
+ if (!Number.isInteger(limits.maxRunning) || limits.maxRunning < 1 || !Number.isInteger(limits.maxRetained) || limits.maxRetained < limits.maxRunning) {
62934
+ throw new Error("INVALID_PROCESS_LIMITS: Invalid local process limits.");
62935
+ }
62936
+ this.#loadReceipts();
62937
+ }
62938
+ limits;
62939
+ receiptFile;
62940
+ #sessions = /* @__PURE__ */ new Map();
62941
+ #taskSessions = /* @__PURE__ */ new Map();
62942
+ #taskReceipts = /* @__PURE__ */ new Map();
62943
+ #loadReceipts() {
62944
+ if (!this.receiptFile) return;
62945
+ let raw;
62946
+ try {
62947
+ raw = readFileSync(this.receiptFile, "utf8");
62948
+ } catch (error62) {
62949
+ if (error62.code === "ENOENT") return;
62950
+ throw error62;
62951
+ }
62952
+ const parsed = JSON.parse(raw);
62953
+ if (parsed.version !== 1 || !Array.isArray(parsed.receipts)) {
62954
+ throw new Error(
62955
+ "INVALID_TASK_RECEIPTS: Refusing to drop existing replay receipts."
62956
+ );
62957
+ }
62958
+ for (const receipt of parsed.receipts) {
62959
+ if (typeof receipt.taskId !== "string" || !Number.isSafeInteger(receipt.createdAt)) {
62960
+ throw new Error("INVALID_TASK_RECEIPTS: Corrupt task-receipt record.");
62961
+ }
62962
+ this.#taskReceipts.set(receipt.taskId, receipt.createdAt);
62963
+ }
62964
+ this.#pruneReceipts();
62965
+ }
62966
+ #persistReceipts() {
62967
+ if (!this.receiptFile) return;
62968
+ mkdirSync(path3.dirname(this.receiptFile), { recursive: true, mode: 448 });
62969
+ const temporary = this.receiptFile + "." + process.pid + "." + randomUUID() + ".tmp";
62970
+ try {
62971
+ writeFileSync(
62972
+ temporary,
62973
+ JSON.stringify({
62974
+ version: 1,
62975
+ receipts: [...this.#taskReceipts].map(([taskId, createdAt]) => ({
62976
+ taskId,
62977
+ createdAt
62978
+ }))
62979
+ }),
62980
+ { mode: 384, flag: "wx", flush: true }
62981
+ );
62982
+ renameSync(temporary, this.receiptFile);
62983
+ if (process.platform !== "win32") {
62984
+ const directory = openSync(path3.dirname(this.receiptFile), "r");
62985
+ try {
62986
+ fsyncSync(directory);
62987
+ } finally {
62988
+ closeSync(directory);
62989
+ }
62990
+ }
62991
+ } finally {
62992
+ rmSync(temporary, { force: true });
62993
+ }
62994
+ }
62995
+ #pruneReceipts() {
62996
+ const cutoff = Date.now() - TASK_RECEIPT_RETENTION_MS;
62997
+ let dirty = false;
62998
+ for (const [taskId, createdAt] of this.#taskReceipts) {
62999
+ if (createdAt < cutoff && !this.#taskSessions.has(taskId)) {
63000
+ this.#taskReceipts.delete(taskId);
63001
+ dirty = true;
63002
+ }
63003
+ }
63004
+ if (dirty) this.#persistReceipts();
63005
+ }
63006
+ #recordTaskReceipt(taskId) {
63007
+ this.#taskReceipts.set(taskId, Date.now());
63008
+ try {
63009
+ this.#persistReceipts();
63010
+ } catch (error62) {
63011
+ this.#taskReceipts.delete(taskId);
63012
+ throw error62;
63013
+ }
63014
+ }
63015
+ #signalProcessTree(session, signal) {
63016
+ const pid = session.child.pid;
63017
+ if (!pid || pid < 1) return;
63018
+ if (process.platform === "win32") {
63019
+ const killer = spawn2("taskkill.exe", ["/PID", String(pid), "/T", "/F"], {
63020
+ windowsHide: true,
63021
+ stdio: "ignore"
63022
+ });
63023
+ killer.on("error", () => session.child.kill("SIGKILL"));
63024
+ killer.on("close", (code) => {
63025
+ if (code !== 0 && session.running) session.child.kill("SIGKILL");
63026
+ });
63027
+ return;
63028
+ }
63029
+ try {
63030
+ process.kill(-pid, signal);
63031
+ return;
63032
+ } catch (error62) {
63033
+ if (error62.code === "ESRCH") return;
63034
+ }
63035
+ session.child.kill(signal);
63036
+ }
63037
+ #unixProcessGroupExists(session) {
63038
+ if (process.platform === "win32") return false;
63039
+ const pid = session.child.pid;
63040
+ if (!pid || pid < 1) return false;
63041
+ try {
63042
+ process.kill(-pid, 0);
63043
+ return true;
63044
+ } catch (error62) {
63045
+ return error62.code !== "ESRCH";
63046
+ }
63047
+ }
63048
+ #finishSession(session, exitCode, signal) {
63049
+ if (session.finishedRecorded) return;
63050
+ session.finishedRecorded = true;
63051
+ session.running = false;
63052
+ session.finishedAt = Date.now();
63053
+ session.exitCode = exitCode;
63054
+ session.signal = signal;
63055
+ if (session.timeout) clearTimeout(session.timeout);
63056
+ if (session.forceKillTimer) {
63057
+ clearTimeout(session.forceKillTimer);
63058
+ session.forceKillTimer = void 0;
63059
+ }
63060
+ this.#record(session, "finished", {
63061
+ exitCode,
63062
+ signal,
63063
+ timedOut: session.timedOut
63064
+ });
63065
+ }
63066
+ #requestTermination(session) {
63067
+ if (!session.running) return;
63068
+ session.terminationRequested = true;
63069
+ this.#signalProcessTree(session, "SIGTERM");
63070
+ if (!session.forceKillTimer) {
63071
+ session.forceKillTimer = setTimeout(() => {
63072
+ session.forceKillTimer = void 0;
63073
+ if (process.platform !== "win32" || session.running) {
63074
+ this.#signalProcessTree(session, "SIGKILL");
63075
+ }
63076
+ const pending = session.pendingTerminationClose;
63077
+ if (pending) {
63078
+ session.pendingTerminationClose = void 0;
63079
+ this.#finishSession(session, pending.exitCode, pending.signal);
63080
+ }
63081
+ }, TERMINATION_GRACE_MS);
63082
+ }
63083
+ }
63084
+ #pruneFinished() {
63085
+ const cutoff = Date.now() - LOCAL_SESSION_RETENTION_MS;
63086
+ for (const [sessionId, session] of this.#sessions) {
63087
+ if (session.finishedAt !== void 0 && session.finishedAt < cutoff && session.watchers.size === 0) {
63088
+ this.#sessions.delete(sessionId);
63089
+ if (session.taskId) this.#taskSessions.delete(session.taskId);
63090
+ }
63091
+ }
63092
+ }
63093
+ #record(session, kind, details = {}) {
63094
+ const event = {
63095
+ sessionId: session.sessionId,
63096
+ ...session.taskId ? { taskId: session.taskId } : {},
63097
+ sequence: ++session.nextSequence,
63098
+ kind,
63099
+ ...details
63100
+ };
63101
+ session.events.push(event);
63102
+ session.retainedEventCharacters += event.data?.length ?? 0;
63103
+ while (session.events.length > MAX_RETAINED_EVENTS || session.retainedEventCharacters > MAX_RETAINED_EVENT_CHARACTERS) {
63104
+ const removed = session.events.shift();
63105
+ session.retainedEventCharacters -= removed.data?.length ?? 0;
63106
+ }
63107
+ for (const wake of session.watchers) wake();
63108
+ }
63109
+ #output(session, stream, chunk) {
63110
+ const before = session[stream].length;
63111
+ const next = appendBounded(
63112
+ session[stream],
63113
+ chunk,
63114
+ session.maxOutputCharacters
63115
+ );
63116
+ session[stream] = next;
63117
+ const appended = next.slice(before);
63118
+ for (let i = 0; i < appended.length; i += MAX_EVENT_CHARACTERS) {
63119
+ this.#record(session, stream, {
63120
+ offset: before + i,
63121
+ data: appended.slice(i, i + MAX_EVENT_CHARACTERS)
63122
+ });
63123
+ }
63124
+ }
63125
+ async watch(sessionId, afterSequence, timeoutMs = 15e3, maxEvents = 32) {
63126
+ this.#pruneFinished();
63127
+ const session = this.#sessions.get(sessionId);
63128
+ if (!session)
63129
+ throw new Error("The requested process session was not found.");
63130
+ if (!Number.isSafeInteger(afterSequence) || afterSequence < 0) {
63131
+ throw new Error("afterSequence must be a non-negative integer.");
63132
+ }
63133
+ if (!Number.isInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 2e4) {
63134
+ throw new Error("timeoutMs must be between 100 and 20000.");
63135
+ }
63136
+ if (!Number.isInteger(maxEvents) || maxEvents < 1 || maxEvents > 32) {
63137
+ throw new Error("maxEvents must be between 1 and 32.");
63138
+ }
63139
+ const collect = () => {
63140
+ const first = session.events[0]?.sequence ?? session.nextSequence + 1;
63141
+ const missedEvents = afterSequence + 1 < first;
63142
+ const events = session.events.filter((event) => event.sequence > afterSequence).slice(0, maxEvents);
63143
+ return {
63144
+ sessionId,
63145
+ events,
63146
+ nextSequence: events.at(-1)?.sequence ?? Math.max(afterSequence, session.nextSequence),
63147
+ missedEvents,
63148
+ finished: !session.running
63149
+ };
63150
+ };
63151
+ const initial = collect();
63152
+ if (initial.events.length || initial.finished || initial.missedEvents) {
63153
+ return initial;
63154
+ }
63155
+ return new Promise((resolve) => {
63156
+ let timer;
63157
+ const finish = () => {
63158
+ clearTimeout(timer);
63159
+ session.watchers.delete(finish);
63160
+ resolve(collect());
63161
+ };
63162
+ session.watchers.add(finish);
63163
+ timer = setTimeout(finish, timeoutMs);
63164
+ if (session.nextSequence > afterSequence || !session.running) finish();
63165
+ });
63166
+ }
63167
+ start(options) {
63168
+ this.#pruneReceipts();
63169
+ if (options.taskId) {
63170
+ const existingSession = this.#taskSessions.get(options.taskId);
63171
+ if (existingSession) {
63172
+ const existing = this.#sessions.get(existingSession);
63173
+ if (!existing) throw new Error("PROCESS_TASK_SESSION_LOST");
63174
+ if (existing.program !== options.program || existing.cwd !== options.cwd || existing.args.join("\0") !== options.args.join("\0")) {
63175
+ throw new Error(
63176
+ "PROCESS_TASK_CONFLICT: Task ID already started with different arguments."
63177
+ );
63178
+ }
63179
+ const result2 = snapshot(existing);
63180
+ return {
63181
+ ...result2,
63182
+ nextStdoutOffset: result2.stdout.length,
63183
+ nextStderrOffset: result2.stderr.length
63184
+ };
63185
+ }
63186
+ if (this.#taskReceipts.has(options.taskId)) {
63187
+ throw new Error(
63188
+ "PROCESS_TASK_SESSION_LOST: Task already ran; will not execute again."
63189
+ );
63190
+ }
63191
+ }
63192
+ this.#pruneFinished();
63193
+ if (this.#sessions.size >= this.limits.maxRetained) {
63194
+ throw new Error("PROCESS_LIMIT_REACHED: Local process history is full.");
63195
+ }
63196
+ const running = [...this.#sessions.values()].filter(
63197
+ (session2) => session2.running
63198
+ ).length;
63199
+ if (running >= this.limits.maxRunning) {
63200
+ throw new Error(
63201
+ "PROCESS_LIMIT_REACHED: Too many concurrent local processes."
63202
+ );
63203
+ }
63204
+ if (options.taskId && this.#taskReceipts.size >= MAX_TASK_TOMBSTONES) {
63205
+ throw new Error(
63206
+ "PROCESS_LIMIT_REACHED: Local task receipt capacity reached."
63207
+ );
63208
+ }
63209
+ assertProgramAllowed(options.program);
63210
+ if (options.rootedExecution && (options.rootedExecution.program !== options.program || options.rootedExecution.args.join("\0") !== options.args.join("\0")))
63211
+ throw new Error("ROOTED_EXECUTION_MISMATCH");
63212
+ const rootedPayload = options.rootedExecution ? JSON.stringify(options.rootedExecution) : void 0;
63213
+ if (rootedPayload && Buffer.byteLength(rootedPayload) >= 4 * 1024 * 1024)
63214
+ throw new Error("ROOTED_EXECUTION_INPUT_LIMIT");
63215
+ if (options.taskId) this.#recordTaskReceipt(options.taskId);
63216
+ const child = spawn2(
63217
+ options.rootedExecution ? filesystemHelperPath : options.program,
63218
+ options.rootedExecution ? ["--exec"] : options.args,
63219
+ {
63220
+ cwd: options.rootedExecution ? void 0 : options.cwd,
63221
+ env: safeEnvironment(),
63222
+ stdio: ["pipe", "pipe", "pipe"],
63223
+ windowsHide: true,
63224
+ // A separate Unix process group lets us terminate descendants too.
63225
+ detached: process.platform !== "win32"
63226
+ }
63227
+ );
63228
+ child.stdin.on("error", () => void 0);
63229
+ child.stdin.end(rootedPayload);
63230
+ const session = {
63231
+ sessionId: randomUUID(),
63232
+ ...options.taskId ? { taskId: options.taskId } : {},
63233
+ program: options.program,
63234
+ args: [...options.args],
63235
+ cwd: options.cwd,
63236
+ child,
63237
+ maxOutputCharacters: options.maxOutputCharacters,
63238
+ stdout: "",
63239
+ stderr: "",
63240
+ running: true,
63241
+ exitCode: null,
63242
+ signal: null,
63243
+ timedOut: false,
63244
+ nextSequence: 0,
63245
+ events: [],
63246
+ retainedEventCharacters: 0,
63247
+ watchers: /* @__PURE__ */ new Set()
63248
+ };
63249
+ this.#sessions.set(session.sessionId, session);
63250
+ if (session.taskId)
63251
+ this.#taskSessions.set(session.taskId, session.sessionId);
63252
+ this.#record(session, "started");
63253
+ child.stdout.on("data", (chunk) => {
63254
+ this.#output(session, "stdout", chunk);
63255
+ });
63256
+ child.stderr.on("data", (chunk) => {
63257
+ this.#output(session, "stderr", chunk);
63258
+ });
63259
+ child.once("error", (error62) => {
63260
+ session.stderr = appendBounded(
63261
+ session.stderr,
63262
+ error62.message,
63263
+ session.maxOutputCharacters
63264
+ );
63265
+ session.running = false;
63266
+ session.exitCode = null;
63267
+ session.signal = null;
63268
+ if (session.timeout) clearTimeout(session.timeout);
63269
+ });
63270
+ child.once("close", (exitCode, signal) => {
63271
+ if (session.terminationRequested && session.forceKillTimer && this.#unixProcessGroupExists(session)) {
63272
+ session.pendingTerminationClose = { exitCode, signal };
63273
+ if (session.timeout) clearTimeout(session.timeout);
63274
+ return;
63275
+ }
63276
+ this.#finishSession(session, exitCode, signal);
63277
+ });
63278
+ session.timeout = setTimeout(() => {
63279
+ if (!session.running) return;
63280
+ session.timedOut = true;
63281
+ this.#requestTermination(session);
63282
+ }, options.timeoutMs);
63283
+ const result = snapshot(session);
63284
+ return {
63285
+ ...result,
63286
+ nextStdoutOffset: result.stdout.length,
63287
+ nextStderrOffset: result.stderr.length
63288
+ };
63289
+ }
63290
+ read(sessionId, stdoutOffset, stderrOffset, maxOutputCharacters) {
63291
+ this.#pruneFinished();
63292
+ const session = this.#sessions.get(sessionId);
63293
+ if (!session)
63294
+ throw new Error("The requested process session was not found.");
63295
+ const safeStdoutOffset = Math.max(
63296
+ 0,
63297
+ Math.min(stdoutOffset, session.stdout.length)
63298
+ );
63299
+ const safeStderrOffset = Math.max(
63300
+ 0,
63301
+ Math.min(stderrOffset, session.stderr.length)
63302
+ );
63303
+ const stdout = session.stdout.slice(
63304
+ safeStdoutOffset,
63305
+ safeStdoutOffset + maxOutputCharacters
63306
+ );
63307
+ const stderr = session.stderr.slice(
63308
+ safeStderrOffset,
63309
+ safeStderrOffset + maxOutputCharacters
63310
+ );
63311
+ return {
63312
+ ...snapshot(session),
63313
+ stdout,
63314
+ stderr,
63315
+ nextStdoutOffset: safeStdoutOffset + stdout.length,
63316
+ nextStderrOffset: safeStderrOffset + stderr.length
63317
+ };
63318
+ }
63319
+ terminate(sessionId) {
63320
+ this.#pruneFinished();
63321
+ const session = this.#sessions.get(sessionId);
63322
+ if (!session)
63323
+ throw new Error("The requested process session was not found.");
63324
+ this.#requestTermination(session);
63325
+ return snapshot(session);
63326
+ }
63327
+ list() {
63328
+ this.#pruneFinished();
63329
+ return [...this.#sessions.values()].map(snapshot);
63330
+ }
63331
+ close() {
63332
+ for (const session of this.#sessions.values()) {
63333
+ if (session.timeout) clearTimeout(session.timeout);
63334
+ this.#requestTermination(session);
63335
+ }
63336
+ for (const session of this.#sessions.values()) {
63337
+ for (const wake of session.watchers) wake();
63338
+ }
63339
+ this.#sessions.clear();
63340
+ this.#taskSessions.clear();
63341
+ }
63342
+ };
62643
63343
 
62644
63344
  // src/server.ts
62645
63345
  var roots = configuredRoots();
63346
+ var processManager = new ProcessManager();
63347
+ var sharedFilesystem;
63348
+ function defaultFilesystem() {
63349
+ return sharedFilesystem ??= new RootedFilesystem(roots);
63350
+ }
63351
+ async function initializeFilesystemBoundary() {
63352
+ await defaultFilesystem().ready;
63353
+ }
63354
+ function filesystemBoundaryAvailable() {
63355
+ return sharedFilesystem?.available === true;
63356
+ }
63357
+ async function closeFilesystemBoundary() {
63358
+ await sharedFilesystem?.close();
63359
+ }
62646
63360
  function textResult(value) {
62647
63361
  return {
62648
63362
  content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
62649
63363
  structuredContent: value
62650
63364
  };
62651
63365
  }
62652
- function createServer() {
63366
+ function createServer(options = {}) {
63367
+ const filesystem = options.filesystem ?? defaultFilesystem();
63368
+ const requireAuthorizedAgent = () => {
63369
+ if (!options.allowDestructive) {
63370
+ throw new Error(
63371
+ "LOCAL_APPROVAL_REQUIRED: Connect through the approved Terminal Commands agent."
63372
+ );
63373
+ }
63374
+ };
62653
63375
  const server = new McpServer(
62654
- { name: "terminal-commands", version: "0.1.0" },
63376
+ { name: "terminal-commands", version: "0.2.0" },
62655
63377
  {
62656
63378
  instructions: "This server controls the user's machine. Prefer dedicated file tools over commands. Every command and write can modify or expose local data and must receive user approval. Never request secrets or bypass configured roots and safety controls."
62657
63379
  }
@@ -62704,15 +63426,12 @@ function createServer() {
62704
63426
  }
62705
63427
  },
62706
63428
  async ({ path: requestedPath }) => {
62707
- const directory = await resolveReadablePath(requestedPath, roots);
62708
- const entries = await readdir(directory, { withFileTypes: true });
63429
+ const directory = filesystem.resolve(requestedPath);
63430
+ const { entries, truncated } = await filesystem.list(directory);
62709
63431
  return textResult({
62710
- path: directory,
62711
- entries: entries.slice(0, 1e3).map((entry) => ({
62712
- name: entry.name,
62713
- type: entry.isDirectory() ? "directory" : entry.isFile() ? "file" : "other"
62714
- })),
62715
- truncated: entries.length > 1e3
63432
+ path: directory.displayPath,
63433
+ entries,
63434
+ truncated
62716
63435
  });
62717
63436
  }
62718
63437
  );
@@ -62737,13 +63456,13 @@ function createServer() {
62737
63456
  }
62738
63457
  },
62739
63458
  async ({ path: requestedPath, maxCharacters }) => {
62740
- const filename = await resolveReadablePath(requestedPath, roots);
62741
- const { contents, truncated } = await readBoundedTextFile(
63459
+ const filename = filesystem.resolve(requestedPath);
63460
+ const { contents, truncated } = await filesystem.read(
62742
63461
  filename,
62743
63462
  maxCharacters
62744
63463
  );
62745
63464
  return textResult({
62746
- path: filename,
63465
+ path: filename.displayPath,
62747
63466
  contents,
62748
63467
  truncated
62749
63468
  });
@@ -62770,23 +63489,26 @@ function createServer() {
62770
63489
  }
62771
63490
  },
62772
63491
  async ({ path: requestedPath, contents, overwrite }) => {
62773
- const filename = await resolveWritablePath(requestedPath, roots);
62774
- await writeFile(filename, contents, {
62775
- encoding: "utf8",
62776
- flag: overwrite ? "w" : "wx"
62777
- });
63492
+ requireAuthorizedAgent();
63493
+ const filename = filesystem.resolve(requestedPath);
63494
+ const bytesWritten = await filesystem.write(
63495
+ filename,
63496
+ contents,
63497
+ overwrite
63498
+ );
62778
63499
  return textResult({
62779
- path: filename,
62780
- bytesWritten: Buffer.byteLength(contents)
63500
+ path: filename.displayPath,
63501
+ bytesWritten
62781
63502
  });
62782
63503
  }
62783
63504
  );
62784
63505
  server.registerTool(
62785
- "run_program",
63506
+ "start_process",
62786
63507
  {
62787
- title: "Run a local program",
62788
- description: "Run one executable without a shell. Shells and privilege-elevation programs are blocked unless explicitly enabled by local configuration.",
63508
+ title: "Start a process",
63509
+ description: "Start one approved executable without a shell on this machine and return a session ID for reading its output.",
62789
63510
  inputSchema: {
63511
+ taskId: external_exports.string().uuid().optional(),
62790
63512
  program: external_exports.string().min(1),
62791
63513
  args: external_exports.array(external_exports.string()).max(100).default([]),
62792
63514
  cwd: external_exports.string().min(1).optional(),
@@ -62794,14 +63516,20 @@ function createServer() {
62794
63516
  maxOutputCharacters: external_exports.number().int().min(1e3).max(2e5).default(5e4)
62795
63517
  },
62796
63518
  outputSchema: {
63519
+ sessionId: external_exports.string(),
63520
+ taskId: external_exports.string().uuid().optional(),
62797
63521
  program: external_exports.string(),
62798
63522
  args: external_exports.array(external_exports.string()),
62799
63523
  cwd: external_exports.string(),
63524
+ pid: external_exports.number().int().nullable(),
63525
+ running: external_exports.boolean(),
62800
63526
  exitCode: external_exports.number().int().nullable(),
62801
63527
  signal: external_exports.string().nullable(),
62802
63528
  stdout: external_exports.string(),
62803
63529
  stderr: external_exports.string(),
62804
- timedOut: external_exports.boolean()
63530
+ timedOut: external_exports.boolean(),
63531
+ nextStdoutOffset: external_exports.number().int().nonnegative(),
63532
+ nextStderrOffset: external_exports.number().int().nonnegative()
62805
63533
  },
62806
63534
  annotations: {
62807
63535
  readOnlyHint: false,
@@ -62809,24 +63537,196 @@ function createServer() {
62809
63537
  openWorldHint: true
62810
63538
  }
62811
63539
  },
62812
- async ({ program, args, cwd, timeoutMs, maxOutputCharacters }) => {
62813
- const workingDirectory = await resolveReadablePath(
63540
+ async ({ taskId, program, args, cwd, timeoutMs, maxOutputCharacters }) => {
63541
+ requireAuthorizedAgent();
63542
+ const workingDirectory = filesystem.resolve(cwd ?? roots[0]);
63543
+ const rootedExecution = await filesystem.execution(
62814
63544
  cwd ?? roots[0],
62815
- roots
62816
- );
62817
- const result = await runProgram({
62818
63545
  program,
62819
- args,
62820
- cwd: workingDirectory,
63546
+ args
63547
+ );
63548
+ return textResult(
63549
+ processManager.start({
63550
+ taskId,
63551
+ program,
63552
+ args,
63553
+ cwd: workingDirectory.displayPath,
63554
+ rootedExecution,
63555
+ timeoutMs,
63556
+ maxOutputCharacters
63557
+ })
63558
+ );
63559
+ }
63560
+ );
63561
+ server.registerTool(
63562
+ "read_process_output",
63563
+ {
63564
+ title: "Read process output",
63565
+ description: "Read new stdout and stderr from a previously started process session.",
63566
+ inputSchema: {
63567
+ sessionId: external_exports.string().uuid(),
63568
+ stdoutOffset: external_exports.number().int().min(0).default(0),
63569
+ stderrOffset: external_exports.number().int().min(0).default(0),
63570
+ maxOutputCharacters: external_exports.number().int().min(1e3).max(2e5).default(5e4)
63571
+ },
63572
+ outputSchema: {
63573
+ sessionId: external_exports.string(),
63574
+ taskId: external_exports.string().uuid().optional(),
63575
+ program: external_exports.string(),
63576
+ args: external_exports.array(external_exports.string()),
63577
+ cwd: external_exports.string(),
63578
+ pid: external_exports.number().int().nullable(),
63579
+ running: external_exports.boolean(),
63580
+ exitCode: external_exports.number().int().nullable(),
63581
+ signal: external_exports.string().nullable(),
63582
+ stdout: external_exports.string(),
63583
+ stderr: external_exports.string(),
63584
+ timedOut: external_exports.boolean(),
63585
+ nextStdoutOffset: external_exports.number().int().nonnegative(),
63586
+ nextStderrOffset: external_exports.number().int().nonnegative()
63587
+ },
63588
+ annotations: {
63589
+ readOnlyHint: true,
63590
+ destructiveHint: false,
63591
+ openWorldHint: false
63592
+ }
63593
+ },
63594
+ async ({ sessionId, stdoutOffset, stderrOffset, maxOutputCharacters }) => textResult(
63595
+ processManager.read(
63596
+ sessionId,
63597
+ stdoutOffset,
63598
+ stderrOffset,
63599
+ maxOutputCharacters
63600
+ )
63601
+ )
63602
+ );
63603
+ server.registerTool(
63604
+ "watch_process_events",
63605
+ {
63606
+ title: "Watch local process events",
63607
+ description: "Wait for sequenced, bounded process events after a cursor. Used internally by the companion to push progress over WebSocket.",
63608
+ inputSchema: {
63609
+ sessionId: external_exports.string().uuid(),
63610
+ afterSequence: external_exports.number().int().nonnegative().default(0),
63611
+ timeoutMs: external_exports.number().int().min(100).max(2e4).default(1e4),
63612
+ maxEvents: external_exports.number().int().min(1).max(32).default(32)
63613
+ },
63614
+ outputSchema: {
63615
+ sessionId: external_exports.string().uuid(),
63616
+ events: external_exports.array(
63617
+ external_exports.object({
63618
+ sessionId: external_exports.string().uuid(),
63619
+ taskId: external_exports.string().uuid().optional(),
63620
+ sequence: external_exports.number().int().positive(),
63621
+ kind: external_exports.enum(["started", "stdout", "stderr", "finished"]),
63622
+ offset: external_exports.number().int().nonnegative().optional(),
63623
+ data: external_exports.string().max(4096).optional(),
63624
+ exitCode: external_exports.number().int().nullable().optional(),
63625
+ signal: external_exports.string().nullable().optional(),
63626
+ timedOut: external_exports.boolean().optional()
63627
+ })
63628
+ ).max(32),
63629
+ nextSequence: external_exports.number().int().nonnegative(),
63630
+ missedEvents: external_exports.boolean(),
63631
+ finished: external_exports.boolean()
63632
+ },
63633
+ annotations: {
63634
+ readOnlyHint: true,
63635
+ destructiveHint: false,
63636
+ openWorldHint: false
63637
+ }
63638
+ },
63639
+ async ({ sessionId, afterSequence, timeoutMs, maxEvents }) => textResult(
63640
+ await processManager.watch(
63641
+ sessionId,
63642
+ afterSequence,
62821
63643
  timeoutMs,
62822
- maxOutputChars: maxOutputCharacters
62823
- });
62824
- return textResult({ program, args, cwd: workingDirectory, ...result });
63644
+ maxEvents
63645
+ )
63646
+ )
63647
+ );
63648
+ server.registerTool(
63649
+ "terminate_process",
63650
+ {
63651
+ title: "Terminate a process",
63652
+ description: "Stop a previously started process session on this machine.",
63653
+ inputSchema: { sessionId: external_exports.string().uuid() },
63654
+ outputSchema: {
63655
+ sessionId: external_exports.string(),
63656
+ taskId: external_exports.string().uuid().optional(),
63657
+ program: external_exports.string(),
63658
+ args: external_exports.array(external_exports.string()),
63659
+ cwd: external_exports.string(),
63660
+ pid: external_exports.number().int().nullable(),
63661
+ running: external_exports.boolean(),
63662
+ exitCode: external_exports.number().int().nullable(),
63663
+ signal: external_exports.string().nullable(),
63664
+ stdout: external_exports.string(),
63665
+ stderr: external_exports.string(),
63666
+ timedOut: external_exports.boolean()
63667
+ },
63668
+ annotations: {
63669
+ readOnlyHint: false,
63670
+ destructiveHint: true,
63671
+ openWorldHint: false
63672
+ }
63673
+ },
63674
+ async ({ sessionId }) => {
63675
+ requireAuthorizedAgent();
63676
+ return textResult(processManager.terminate(sessionId));
62825
63677
  }
62826
63678
  );
63679
+ server.registerTool(
63680
+ "list_processes",
63681
+ {
63682
+ title: "List process sessions",
63683
+ description: "List process sessions started through Terminal Commands.",
63684
+ inputSchema: {},
63685
+ outputSchema: {
63686
+ processes: external_exports.array(
63687
+ external_exports.object({
63688
+ sessionId: external_exports.string(),
63689
+ taskId: external_exports.string().uuid().optional(),
63690
+ program: external_exports.string(),
63691
+ args: external_exports.array(external_exports.string()),
63692
+ cwd: external_exports.string(),
63693
+ pid: external_exports.number().int().nullable(),
63694
+ running: external_exports.boolean(),
63695
+ exitCode: external_exports.number().int().nullable(),
63696
+ signal: external_exports.string().nullable(),
63697
+ stdout: external_exports.string(),
63698
+ stderr: external_exports.string(),
63699
+ timedOut: external_exports.boolean()
63700
+ })
63701
+ )
63702
+ },
63703
+ annotations: {
63704
+ readOnlyHint: true,
63705
+ destructiveHint: false,
63706
+ openWorldHint: false
63707
+ }
63708
+ },
63709
+ async () => textResult({ processes: processManager.list() })
63710
+ );
62827
63711
  return server;
62828
63712
  }
62829
63713
 
63714
+ // src/local-agent-auth.ts
63715
+ import { createHmac, timingSafeEqual } from "node:crypto";
63716
+ function isTrustedLocalAgent(presented, expected) {
63717
+ if (!presented || !expected || !/^[a-f0-9]{64}$/i.test(expected))
63718
+ return false;
63719
+ if (!/^[a-f0-9]{64}$/i.test(presented)) return false;
63720
+ const left = Buffer.from(presented, "hex");
63721
+ const right = Buffer.from(expected, "hex");
63722
+ return left.length === right.length && timingSafeEqual(left, right);
63723
+ }
63724
+ function localHealthProof(secret, challenge) {
63725
+ if (!secret || !/^[a-f0-9]{64}$/i.test(secret)) return null;
63726
+ if (!challenge || !/^[a-f0-9]{64}$/i.test(challenge)) return null;
63727
+ return createHmac("sha256", Buffer.from(secret, "hex")).update(challenge, "ascii").digest("hex");
63728
+ }
63729
+
62830
63730
  // src/index.ts
62831
63731
  var host = process.env.MACHINE_TERMINAL_HOST ?? "127.0.0.1";
62832
63732
  var port = Number.parseInt(process.env.MACHINE_TERMINAL_PORT ?? "3333", 10);
@@ -62840,15 +63740,29 @@ if (!localHosts.has(host) && process.env.MACHINE_TERMINAL_ALLOW_PUBLIC_BIND !==
62840
63740
  );
62841
63741
  }
62842
63742
  var app = createMcpExpressApp({ host });
62843
- app.get("/health", (_request, response) => {
62844
- response.json({
62845
- status: "ok",
63743
+ app.get("/health", (request, response) => {
63744
+ const proof = localHealthProof(
63745
+ process.env.MACHINE_TERMINAL_LOCAL_AGENT_TOKEN,
63746
+ request.header("x-terminal-commands-health-challenge")
63747
+ );
63748
+ const available = filesystemBoundaryAvailable();
63749
+ response.status(available ? 200 : 503).json({
63750
+ status: available ? "ok" : "filesystem_unavailable",
62846
63751
  server: "terminal-commands",
62847
- version: "0.1.0"
63752
+ version: "0.2.0",
63753
+ ...proof ? { agentProof: proof } : {}
62848
63754
  });
62849
63755
  });
62850
63756
  app.post("/mcp", async (request, response) => {
62851
- const server = createServer();
63757
+ const authorized = isTrustedLocalAgent(
63758
+ request.header("x-terminal-commands-agent-token"),
63759
+ process.env.MACHINE_TERMINAL_LOCAL_AGENT_TOKEN
63760
+ );
63761
+ if (!authorized) {
63762
+ response.status(401).json({ error: "local_agent_authentication_required" });
63763
+ return;
63764
+ }
63765
+ const server = createServer({ allowDestructive: true });
62852
63766
  const transport = new StreamableHTTPServerTransport({
62853
63767
  sessionIdGenerator: void 0
62854
63768
  });
@@ -62879,11 +63793,14 @@ for (const method of ["get", "delete"]) {
62879
63793
  });
62880
63794
  });
62881
63795
  }
63796
+ await initializeFilesystemBoundary();
62882
63797
  var listener = app.listen(port, host, () => {
62883
63798
  console.log(`Terminal Commands MCP listening at http://${host}:${port}/mcp`);
62884
63799
  });
62885
- function shutdown(signal) {
63800
+ async function shutdown(signal) {
62886
63801
  console.log(`Received ${signal}; shutting down.`);
63802
+ processManager.close();
63803
+ await closeFilesystemBoundary();
62887
63804
  listener.close((error62) => {
62888
63805
  if (error62) {
62889
63806
  console.error(error62);
@@ -62891,8 +63808,8 @@ function shutdown(signal) {
62891
63808
  }
62892
63809
  });
62893
63810
  }
62894
- process.on("SIGINT", () => shutdown("SIGINT"));
62895
- process.on("SIGTERM", () => shutdown("SIGTERM"));
63811
+ process.on("SIGINT", () => void shutdown("SIGINT"));
63812
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
62896
63813
  /*! Bundled license information:
62897
63814
 
62898
63815
  depd/index.js: