meshy-node 0.0.9 → 0.1.2

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/main.cjs CHANGED
@@ -1460,8 +1460,8 @@ var require_node = __commonJS({
1460
1460
  }
1461
1461
  break;
1462
1462
  case "FILE":
1463
- var fs17 = require("fs");
1464
- stream2 = new fs17.SyncWriteStream(fd2, { autoClose: false });
1463
+ var fs16 = require("fs");
1464
+ stream2 = new fs16.SyncWriteStream(fd2, { autoClose: false });
1465
1465
  stream2._type = "fs";
1466
1466
  break;
1467
1467
  case "PIPE":
@@ -14251,11 +14251,11 @@ var require_mime_types = __commonJS({
14251
14251
  }
14252
14252
  return exts[0];
14253
14253
  }
14254
- function lookup(path17) {
14255
- if (!path17 || typeof path17 !== "string") {
14254
+ function lookup(path16) {
14255
+ if (!path16 || typeof path16 !== "string") {
14256
14256
  return false;
14257
14257
  }
14258
- var extension2 = extname3("x." + path17).toLowerCase().substr(1);
14258
+ var extension2 = extname3("x." + path16).toLowerCase().substr(1);
14259
14259
  if (!extension2) {
14260
14260
  return false;
14261
14261
  }
@@ -17773,7 +17773,7 @@ var require_path_to_regexp = __commonJS({
17773
17773
  "use strict";
17774
17774
  module2.exports = pathToRegexp;
17775
17775
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
17776
- function pathToRegexp(path17, keys, options) {
17776
+ function pathToRegexp(path16, keys, options) {
17777
17777
  options = options || {};
17778
17778
  keys = keys || [];
17779
17779
  var strict = options.strict;
@@ -17787,8 +17787,8 @@ var require_path_to_regexp = __commonJS({
17787
17787
  var pos = 0;
17788
17788
  var backtrack = "";
17789
17789
  var m;
17790
- if (path17 instanceof RegExp) {
17791
- while (m = MATCHING_GROUP_REGEXP.exec(path17.source)) {
17790
+ if (path16 instanceof RegExp) {
17791
+ while (m = MATCHING_GROUP_REGEXP.exec(path16.source)) {
17792
17792
  if (m[0][0] === "\\") continue;
17793
17793
  keys.push({
17794
17794
  name: m[1] || name++,
@@ -17796,18 +17796,18 @@ var require_path_to_regexp = __commonJS({
17796
17796
  offset: m.index
17797
17797
  });
17798
17798
  }
17799
- return path17;
17799
+ return path16;
17800
17800
  }
17801
- if (Array.isArray(path17)) {
17802
- path17 = path17.map(function(value) {
17801
+ if (Array.isArray(path16)) {
17802
+ path16 = path16.map(function(value) {
17803
17803
  return pathToRegexp(value, keys, options).source;
17804
17804
  });
17805
- return new RegExp(path17.join("|"), flags);
17805
+ return new RegExp(path16.join("|"), flags);
17806
17806
  }
17807
- if (typeof path17 !== "string") {
17807
+ if (typeof path16 !== "string") {
17808
17808
  throw new TypeError("path must be a string, array of strings, or regular expression");
17809
17809
  }
17810
- path17 = path17.replace(
17810
+ path16 = path16.replace(
17811
17811
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
17812
17812
  function(match, slash, format, key, capture, star, optional, offset) {
17813
17813
  if (match[0] === "\\") {
@@ -17824,7 +17824,7 @@ var require_path_to_regexp = __commonJS({
17824
17824
  if (slash || format) {
17825
17825
  backtrack = "";
17826
17826
  } else {
17827
- backtrack += path17.slice(pos, offset);
17827
+ backtrack += path16.slice(pos, offset);
17828
17828
  }
17829
17829
  pos = offset + match.length;
17830
17830
  if (match === "*") {
@@ -17854,7 +17854,7 @@ var require_path_to_regexp = __commonJS({
17854
17854
  return result;
17855
17855
  }
17856
17856
  );
17857
- while (m = MATCHING_GROUP_REGEXP.exec(path17)) {
17857
+ while (m = MATCHING_GROUP_REGEXP.exec(path16)) {
17858
17858
  if (m[0][0] === "\\") continue;
17859
17859
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
17860
17860
  keys.splice(keysOffset + i, 0, {
@@ -17866,13 +17866,13 @@ var require_path_to_regexp = __commonJS({
17866
17866
  }
17867
17867
  i++;
17868
17868
  }
17869
- path17 += strict ? "" : path17[path17.length - 1] === "/" ? "?" : "/?";
17869
+ path16 += strict ? "" : path16[path16.length - 1] === "/" ? "?" : "/?";
17870
17870
  if (end) {
17871
- path17 += "$";
17872
- } else if (path17[path17.length - 1] !== "/") {
17873
- path17 += lookahead ? "(?=/|$)" : "(?:/|$)";
17871
+ path16 += "$";
17872
+ } else if (path16[path16.length - 1] !== "/") {
17873
+ path16 += lookahead ? "(?=/|$)" : "(?:/|$)";
17874
17874
  }
17875
- return new RegExp("^" + path17, flags);
17875
+ return new RegExp("^" + path16, flags);
17876
17876
  }
17877
17877
  }
17878
17878
  });
@@ -17885,19 +17885,19 @@ var require_layer = __commonJS({
17885
17885
  var debug = require_src()("express:router:layer");
17886
17886
  var hasOwnProperty = Object.prototype.hasOwnProperty;
17887
17887
  module2.exports = Layer;
17888
- function Layer(path17, options, fn) {
17888
+ function Layer(path16, options, fn) {
17889
17889
  if (!(this instanceof Layer)) {
17890
- return new Layer(path17, options, fn);
17890
+ return new Layer(path16, options, fn);
17891
17891
  }
17892
- debug("new %o", path17);
17892
+ debug("new %o", path16);
17893
17893
  var opts = options || {};
17894
17894
  this.handle = fn;
17895
17895
  this.name = fn.name || "<anonymous>";
17896
17896
  this.params = void 0;
17897
17897
  this.path = void 0;
17898
- this.regexp = pathRegexp(path17, this.keys = [], opts);
17899
- this.regexp.fast_star = path17 === "*";
17900
- this.regexp.fast_slash = path17 === "/" && opts.end === false;
17898
+ this.regexp = pathRegexp(path16, this.keys = [], opts);
17899
+ this.regexp.fast_star = path16 === "*";
17900
+ this.regexp.fast_slash = path16 === "/" && opts.end === false;
17901
17901
  }
17902
17902
  Layer.prototype.handle_error = function handle_error(error, req, res, next) {
17903
17903
  var fn = this.handle;
@@ -17921,20 +17921,20 @@ var require_layer = __commonJS({
17921
17921
  next(err);
17922
17922
  }
17923
17923
  };
17924
- Layer.prototype.match = function match(path17) {
17924
+ Layer.prototype.match = function match(path16) {
17925
17925
  var match2;
17926
- if (path17 != null) {
17926
+ if (path16 != null) {
17927
17927
  if (this.regexp.fast_slash) {
17928
17928
  this.params = {};
17929
17929
  this.path = "";
17930
17930
  return true;
17931
17931
  }
17932
17932
  if (this.regexp.fast_star) {
17933
- this.params = { "0": decode_param(path17) };
17934
- this.path = path17;
17933
+ this.params = { "0": decode_param(path16) };
17934
+ this.path = path16;
17935
17935
  return true;
17936
17936
  }
17937
- match2 = this.regexp.exec(path17);
17937
+ match2 = this.regexp.exec(path16);
17938
17938
  }
17939
17939
  if (!match2) {
17940
17940
  this.params = void 0;
@@ -17976,10 +17976,10 @@ var require_layer = __commonJS({
17976
17976
  var require_methods = __commonJS({
17977
17977
  "../../node_modules/.pnpm/methods@1.1.2/node_modules/methods/index.js"(exports2, module2) {
17978
17978
  "use strict";
17979
- var http2 = require("http");
17979
+ var http3 = require("http");
17980
17980
  module2.exports = getCurrentNodeMethods() || getBasicNodeMethods();
17981
17981
  function getCurrentNodeMethods() {
17982
- return http2.METHODS && http2.METHODS.map(function lowerCaseMethod(method) {
17982
+ return http3.METHODS && http3.METHODS.map(function lowerCaseMethod(method) {
17983
17983
  return method.toLowerCase();
17984
17984
  });
17985
17985
  }
@@ -18027,10 +18027,10 @@ var require_route = __commonJS({
18027
18027
  var slice = Array.prototype.slice;
18028
18028
  var toString = Object.prototype.toString;
18029
18029
  module2.exports = Route;
18030
- function Route(path17) {
18031
- this.path = path17;
18030
+ function Route(path16) {
18031
+ this.path = path16;
18032
18032
  this.stack = [];
18033
- debug("new %o", path17);
18033
+ debug("new %o", path16);
18034
18034
  this.methods = {};
18035
18035
  }
18036
18036
  Route.prototype._handles_method = function _handles_method(method) {
@@ -18243,8 +18243,8 @@ var require_router = __commonJS({
18243
18243
  if (++sync > 100) {
18244
18244
  return setImmediate(next, err);
18245
18245
  }
18246
- var path17 = getPathname(req);
18247
- if (path17 == null) {
18246
+ var path16 = getPathname(req);
18247
+ if (path16 == null) {
18248
18248
  return done(layerError);
18249
18249
  }
18250
18250
  var layer;
@@ -18252,7 +18252,7 @@ var require_router = __commonJS({
18252
18252
  var route;
18253
18253
  while (match !== true && idx < stack.length) {
18254
18254
  layer = stack[idx++];
18255
- match = matchLayer(layer, path17);
18255
+ match = matchLayer(layer, path16);
18256
18256
  route = layer.route;
18257
18257
  if (typeof match !== "boolean") {
18258
18258
  layerError = layerError || match;
@@ -18290,18 +18290,18 @@ var require_router = __commonJS({
18290
18290
  } else if (route) {
18291
18291
  layer.handle_request(req, res, next);
18292
18292
  } else {
18293
- trim_prefix(layer, layerError, layerPath, path17);
18293
+ trim_prefix(layer, layerError, layerPath, path16);
18294
18294
  }
18295
18295
  sync = 0;
18296
18296
  });
18297
18297
  }
18298
- function trim_prefix(layer, layerError, layerPath, path17) {
18298
+ function trim_prefix(layer, layerError, layerPath, path16) {
18299
18299
  if (layerPath.length !== 0) {
18300
- if (layerPath !== path17.slice(0, layerPath.length)) {
18300
+ if (layerPath !== path16.slice(0, layerPath.length)) {
18301
18301
  next(layerError);
18302
18302
  return;
18303
18303
  }
18304
- var c = path17[layerPath.length];
18304
+ var c = path16[layerPath.length];
18305
18305
  if (c && c !== "/" && c !== ".") return next(layerError);
18306
18306
  debug("trim prefix (%s) from url %s", layerPath, req.url);
18307
18307
  removed = layerPath;
@@ -18379,7 +18379,7 @@ var require_router = __commonJS({
18379
18379
  };
18380
18380
  proto.use = function use(fn) {
18381
18381
  var offset = 0;
18382
- var path17 = "/";
18382
+ var path16 = "/";
18383
18383
  if (typeof fn !== "function") {
18384
18384
  var arg = fn;
18385
18385
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -18387,7 +18387,7 @@ var require_router = __commonJS({
18387
18387
  }
18388
18388
  if (typeof arg !== "function") {
18389
18389
  offset = 1;
18390
- path17 = fn;
18390
+ path16 = fn;
18391
18391
  }
18392
18392
  }
18393
18393
  var callbacks = flatten(slice.call(arguments, offset));
@@ -18399,8 +18399,8 @@ var require_router = __commonJS({
18399
18399
  if (typeof fn !== "function") {
18400
18400
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
18401
18401
  }
18402
- debug("use %o %s", path17, fn.name || "<anonymous>");
18403
- var layer = new Layer(path17, {
18402
+ debug("use %o %s", path16, fn.name || "<anonymous>");
18403
+ var layer = new Layer(path16, {
18404
18404
  sensitive: this.caseSensitive,
18405
18405
  strict: false,
18406
18406
  end: false
@@ -18410,9 +18410,9 @@ var require_router = __commonJS({
18410
18410
  }
18411
18411
  return this;
18412
18412
  };
18413
- proto.route = function route(path17) {
18414
- var route2 = new Route(path17);
18415
- var layer = new Layer(path17, {
18413
+ proto.route = function route(path16) {
18414
+ var route2 = new Route(path16);
18415
+ var layer = new Layer(path16, {
18416
18416
  sensitive: this.caseSensitive,
18417
18417
  strict: this.strict,
18418
18418
  end: true
@@ -18422,8 +18422,8 @@ var require_router = __commonJS({
18422
18422
  return route2;
18423
18423
  };
18424
18424
  methods.concat("all").forEach(function(method) {
18425
- proto[method] = function(path17) {
18426
- var route = this.route(path17);
18425
+ proto[method] = function(path16) {
18426
+ var route = this.route(path16);
18427
18427
  route[method].apply(route, slice.call(arguments, 1));
18428
18428
  return this;
18429
18429
  };
@@ -18459,9 +18459,9 @@ var require_router = __commonJS({
18459
18459
  }
18460
18460
  return toString.call(obj).replace(objectRegExp, "$1");
18461
18461
  }
18462
- function matchLayer(layer, path17) {
18462
+ function matchLayer(layer, path16) {
18463
18463
  try {
18464
- return layer.match(path17);
18464
+ return layer.match(path16);
18465
18465
  } catch (err) {
18466
18466
  return err;
18467
18467
  }
@@ -18579,13 +18579,13 @@ var require_view = __commonJS({
18579
18579
  "../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports2, module2) {
18580
18580
  "use strict";
18581
18581
  var debug = require_src()("express:view");
18582
- var path17 = require("path");
18583
- var fs17 = require("fs");
18584
- var dirname3 = path17.dirname;
18585
- var basename4 = path17.basename;
18586
- var extname3 = path17.extname;
18587
- var join13 = path17.join;
18588
- var resolve10 = path17.resolve;
18582
+ var path16 = require("path");
18583
+ var fs16 = require("fs");
18584
+ var dirname3 = path16.dirname;
18585
+ var basename3 = path16.basename;
18586
+ var extname3 = path16.extname;
18587
+ var join13 = path16.join;
18588
+ var resolve10 = path16.resolve;
18589
18589
  module2.exports = View;
18590
18590
  function View(name, options) {
18591
18591
  var opts = options || {};
@@ -18614,17 +18614,17 @@ var require_view = __commonJS({
18614
18614
  this.path = this.lookup(fileName);
18615
18615
  }
18616
18616
  View.prototype.lookup = function lookup(name) {
18617
- var path18;
18617
+ var path17;
18618
18618
  var roots = [].concat(this.root);
18619
18619
  debug('lookup "%s"', name);
18620
- for (var i = 0; i < roots.length && !path18; i++) {
18620
+ for (var i = 0; i < roots.length && !path17; i++) {
18621
18621
  var root = roots[i];
18622
18622
  var loc = resolve10(root, name);
18623
18623
  var dir = dirname3(loc);
18624
- var file = basename4(loc);
18625
- path18 = this.resolve(dir, file);
18624
+ var file = basename3(loc);
18625
+ path17 = this.resolve(dir, file);
18626
18626
  }
18627
- return path18;
18627
+ return path17;
18628
18628
  };
18629
18629
  View.prototype.render = function render(options, callback) {
18630
18630
  debug('render "%s"', this.path);
@@ -18632,21 +18632,21 @@ var require_view = __commonJS({
18632
18632
  };
18633
18633
  View.prototype.resolve = function resolve11(dir, file) {
18634
18634
  var ext = this.ext;
18635
- var path18 = join13(dir, file);
18636
- var stat = tryStat(path18);
18635
+ var path17 = join13(dir, file);
18636
+ var stat = tryStat(path17);
18637
18637
  if (stat && stat.isFile()) {
18638
- return path18;
18638
+ return path17;
18639
18639
  }
18640
- path18 = join13(dir, basename4(file, ext), "index" + ext);
18641
- stat = tryStat(path18);
18640
+ path17 = join13(dir, basename3(file, ext), "index" + ext);
18641
+ stat = tryStat(path17);
18642
18642
  if (stat && stat.isFile()) {
18643
- return path18;
18643
+ return path17;
18644
18644
  }
18645
18645
  };
18646
- function tryStat(path18) {
18647
- debug('stat "%s"', path18);
18646
+ function tryStat(path17) {
18647
+ debug('stat "%s"', path17);
18648
18648
  try {
18649
- return fs17.statSync(path18);
18649
+ return fs16.statSync(path17);
18650
18650
  } catch (e) {
18651
18651
  return void 0;
18652
18652
  }
@@ -18719,7 +18719,7 @@ var require_content_disposition = __commonJS({
18719
18719
  "use strict";
18720
18720
  module2.exports = contentDisposition;
18721
18721
  module2.exports.parse = parse;
18722
- var basename4 = require("path").basename;
18722
+ var basename3 = require("path").basename;
18723
18723
  var Buffer2 = require_safe_buffer().Buffer;
18724
18724
  var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
18725
18725
  var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
@@ -18755,9 +18755,9 @@ var require_content_disposition = __commonJS({
18755
18755
  if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
18756
18756
  throw new TypeError("fallback must be ISO-8859-1 string");
18757
18757
  }
18758
- var name = basename4(filename);
18758
+ var name = basename3(filename);
18759
18759
  var isQuotedString = TEXT_REGEXP.test(name);
18760
- var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename4(fallback);
18760
+ var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename3(fallback);
18761
18761
  var hasFallback = typeof fallbackName === "string" && fallbackName !== name;
18762
18762
  if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
18763
18763
  params["filename*"] = name;
@@ -19002,8 +19002,8 @@ var require_types = __commonJS({
19002
19002
  var require_mime = __commonJS({
19003
19003
  "../../node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports2, module2) {
19004
19004
  "use strict";
19005
- var path17 = require("path");
19006
- var fs17 = require("fs");
19005
+ var path16 = require("path");
19006
+ var fs16 = require("fs");
19007
19007
  function Mime() {
19008
19008
  this.types = /* @__PURE__ */ Object.create(null);
19009
19009
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -19024,7 +19024,7 @@ var require_mime = __commonJS({
19024
19024
  };
19025
19025
  Mime.prototype.load = function(file) {
19026
19026
  this._loading = file;
19027
- var map = {}, content = fs17.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
19027
+ var map = {}, content = fs16.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
19028
19028
  lines.forEach(function(line) {
19029
19029
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
19030
19030
  map[fields.shift()] = fields;
@@ -19032,8 +19032,8 @@ var require_mime = __commonJS({
19032
19032
  this.define(map);
19033
19033
  this._loading = null;
19034
19034
  };
19035
- Mime.prototype.lookup = function(path18, fallback) {
19036
- var ext = path18.replace(/^.*[\.\/\\]/, "").toLowerCase();
19035
+ Mime.prototype.lookup = function(path17, fallback) {
19036
+ var ext = path17.replace(/^.*[\.\/\\]/, "").toLowerCase();
19037
19037
  return this.types[ext] || fallback || this.default_type;
19038
19038
  };
19039
19039
  Mime.prototype.extension = function(mimeType) {
@@ -19263,33 +19263,33 @@ var require_send = __commonJS({
19263
19263
  var escapeHtml = require_escape_html();
19264
19264
  var etag = require_etag();
19265
19265
  var fresh = require_fresh();
19266
- var fs17 = require("fs");
19266
+ var fs16 = require("fs");
19267
19267
  var mime = require_mime();
19268
19268
  var ms = require_ms2();
19269
19269
  var onFinished = require_on_finished();
19270
19270
  var parseRange = require_range_parser();
19271
- var path17 = require("path");
19271
+ var path16 = require("path");
19272
19272
  var statuses = require_statuses();
19273
19273
  var Stream = require("stream");
19274
19274
  var util2 = require("util");
19275
- var extname3 = path17.extname;
19276
- var join13 = path17.join;
19277
- var normalize = path17.normalize;
19278
- var resolve10 = path17.resolve;
19279
- var sep3 = path17.sep;
19275
+ var extname3 = path16.extname;
19276
+ var join13 = path16.join;
19277
+ var normalize = path16.normalize;
19278
+ var resolve10 = path16.resolve;
19279
+ var sep3 = path16.sep;
19280
19280
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
19281
19281
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
19282
19282
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
19283
19283
  module2.exports = send;
19284
19284
  module2.exports.mime = mime;
19285
- function send(req, path18, options) {
19286
- return new SendStream(req, path18, options);
19285
+ function send(req, path17, options) {
19286
+ return new SendStream(req, path17, options);
19287
19287
  }
19288
- function SendStream(req, path18, options) {
19288
+ function SendStream(req, path17, options) {
19289
19289
  Stream.call(this);
19290
19290
  var opts = options || {};
19291
19291
  this.options = opts;
19292
- this.path = path18;
19292
+ this.path = path17;
19293
19293
  this.req = req;
19294
19294
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
19295
19295
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -19335,8 +19335,8 @@ var require_send = __commonJS({
19335
19335
  this._index = index2;
19336
19336
  return this;
19337
19337
  }, "send.index: pass index as option");
19338
- SendStream.prototype.root = function root(path18) {
19339
- this._root = resolve10(String(path18));
19338
+ SendStream.prototype.root = function root(path17) {
19339
+ this._root = resolve10(String(path17));
19340
19340
  debug("root %s", this._root);
19341
19341
  return this;
19342
19342
  };
@@ -19449,10 +19449,10 @@ var require_send = __commonJS({
19449
19449
  var lastModified = this.res.getHeader("Last-Modified");
19450
19450
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
19451
19451
  };
19452
- SendStream.prototype.redirect = function redirect(path18) {
19452
+ SendStream.prototype.redirect = function redirect(path17) {
19453
19453
  var res = this.res;
19454
19454
  if (hasListeners(this, "directory")) {
19455
- this.emit("directory", res, path18);
19455
+ this.emit("directory", res, path17);
19456
19456
  return;
19457
19457
  }
19458
19458
  if (this.hasTrailingSlash()) {
@@ -19472,42 +19472,42 @@ var require_send = __commonJS({
19472
19472
  SendStream.prototype.pipe = function pipe(res) {
19473
19473
  var root = this._root;
19474
19474
  this.res = res;
19475
- var path18 = decode(this.path);
19476
- if (path18 === -1) {
19475
+ var path17 = decode(this.path);
19476
+ if (path17 === -1) {
19477
19477
  this.error(400);
19478
19478
  return res;
19479
19479
  }
19480
- if (~path18.indexOf("\0")) {
19480
+ if (~path17.indexOf("\0")) {
19481
19481
  this.error(400);
19482
19482
  return res;
19483
19483
  }
19484
19484
  var parts;
19485
19485
  if (root !== null) {
19486
- if (path18) {
19487
- path18 = normalize("." + sep3 + path18);
19486
+ if (path17) {
19487
+ path17 = normalize("." + sep3 + path17);
19488
19488
  }
19489
- if (UP_PATH_REGEXP.test(path18)) {
19490
- debug('malicious path "%s"', path18);
19489
+ if (UP_PATH_REGEXP.test(path17)) {
19490
+ debug('malicious path "%s"', path17);
19491
19491
  this.error(403);
19492
19492
  return res;
19493
19493
  }
19494
- parts = path18.split(sep3);
19495
- path18 = normalize(join13(root, path18));
19494
+ parts = path17.split(sep3);
19495
+ path17 = normalize(join13(root, path17));
19496
19496
  } else {
19497
- if (UP_PATH_REGEXP.test(path18)) {
19498
- debug('malicious path "%s"', path18);
19497
+ if (UP_PATH_REGEXP.test(path17)) {
19498
+ debug('malicious path "%s"', path17);
19499
19499
  this.error(403);
19500
19500
  return res;
19501
19501
  }
19502
- parts = normalize(path18).split(sep3);
19503
- path18 = resolve10(path18);
19502
+ parts = normalize(path17).split(sep3);
19503
+ path17 = resolve10(path17);
19504
19504
  }
19505
19505
  if (containsDotFile(parts)) {
19506
19506
  var access = this._dotfiles;
19507
19507
  if (access === void 0) {
19508
19508
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
19509
19509
  }
19510
- debug('%s dotfile "%s"', access, path18);
19510
+ debug('%s dotfile "%s"', access, path17);
19511
19511
  switch (access) {
19512
19512
  case "allow":
19513
19513
  break;
@@ -19521,13 +19521,13 @@ var require_send = __commonJS({
19521
19521
  }
19522
19522
  }
19523
19523
  if (this._index.length && this.hasTrailingSlash()) {
19524
- this.sendIndex(path18);
19524
+ this.sendIndex(path17);
19525
19525
  return res;
19526
19526
  }
19527
- this.sendFile(path18);
19527
+ this.sendFile(path17);
19528
19528
  return res;
19529
19529
  };
19530
- SendStream.prototype.send = function send2(path18, stat) {
19530
+ SendStream.prototype.send = function send2(path17, stat) {
19531
19531
  var len = stat.size;
19532
19532
  var options = this.options;
19533
19533
  var opts = {};
@@ -19539,9 +19539,9 @@ var require_send = __commonJS({
19539
19539
  this.headersAlreadySent();
19540
19540
  return;
19541
19541
  }
19542
- debug('pipe "%s"', path18);
19543
- this.setHeader(path18, stat);
19544
- this.type(path18);
19542
+ debug('pipe "%s"', path17);
19543
+ this.setHeader(path17, stat);
19544
+ this.type(path17);
19545
19545
  if (this.isConditionalGET()) {
19546
19546
  if (this.isPreconditionFailure()) {
19547
19547
  this.error(412);
@@ -19590,28 +19590,28 @@ var require_send = __commonJS({
19590
19590
  res.end();
19591
19591
  return;
19592
19592
  }
19593
- this.stream(path18, opts);
19593
+ this.stream(path17, opts);
19594
19594
  };
19595
- SendStream.prototype.sendFile = function sendFile(path18) {
19595
+ SendStream.prototype.sendFile = function sendFile(path17) {
19596
19596
  var i = 0;
19597
19597
  var self = this;
19598
- debug('stat "%s"', path18);
19599
- fs17.stat(path18, function onstat(err, stat) {
19600
- if (err && err.code === "ENOENT" && !extname3(path18) && path18[path18.length - 1] !== sep3) {
19598
+ debug('stat "%s"', path17);
19599
+ fs16.stat(path17, function onstat(err, stat) {
19600
+ if (err && err.code === "ENOENT" && !extname3(path17) && path17[path17.length - 1] !== sep3) {
19601
19601
  return next(err);
19602
19602
  }
19603
19603
  if (err) return self.onStatError(err);
19604
- if (stat.isDirectory()) return self.redirect(path18);
19605
- self.emit("file", path18, stat);
19606
- self.send(path18, stat);
19604
+ if (stat.isDirectory()) return self.redirect(path17);
19605
+ self.emit("file", path17, stat);
19606
+ self.send(path17, stat);
19607
19607
  });
19608
19608
  function next(err) {
19609
19609
  if (self._extensions.length <= i) {
19610
19610
  return err ? self.onStatError(err) : self.error(404);
19611
19611
  }
19612
- var p = path18 + "." + self._extensions[i++];
19612
+ var p = path17 + "." + self._extensions[i++];
19613
19613
  debug('stat "%s"', p);
19614
- fs17.stat(p, function(err2, stat) {
19614
+ fs16.stat(p, function(err2, stat) {
19615
19615
  if (err2) return next(err2);
19616
19616
  if (stat.isDirectory()) return next();
19617
19617
  self.emit("file", p, stat);
@@ -19619,7 +19619,7 @@ var require_send = __commonJS({
19619
19619
  });
19620
19620
  }
19621
19621
  };
19622
- SendStream.prototype.sendIndex = function sendIndex(path18) {
19622
+ SendStream.prototype.sendIndex = function sendIndex(path17) {
19623
19623
  var i = -1;
19624
19624
  var self = this;
19625
19625
  function next(err) {
@@ -19627,9 +19627,9 @@ var require_send = __commonJS({
19627
19627
  if (err) return self.onStatError(err);
19628
19628
  return self.error(404);
19629
19629
  }
19630
- var p = join13(path18, self._index[i]);
19630
+ var p = join13(path17, self._index[i]);
19631
19631
  debug('stat "%s"', p);
19632
- fs17.stat(p, function(err2, stat) {
19632
+ fs16.stat(p, function(err2, stat) {
19633
19633
  if (err2) return next(err2);
19634
19634
  if (stat.isDirectory()) return next();
19635
19635
  self.emit("file", p, stat);
@@ -19638,10 +19638,10 @@ var require_send = __commonJS({
19638
19638
  }
19639
19639
  next();
19640
19640
  };
19641
- SendStream.prototype.stream = function stream(path18, options) {
19641
+ SendStream.prototype.stream = function stream(path17, options) {
19642
19642
  var self = this;
19643
19643
  var res = this.res;
19644
- var stream2 = fs17.createReadStream(path18, options);
19644
+ var stream2 = fs16.createReadStream(path17, options);
19645
19645
  this.emit("stream", stream2);
19646
19646
  stream2.pipe(res);
19647
19647
  function cleanup() {
@@ -19656,10 +19656,10 @@ var require_send = __commonJS({
19656
19656
  self.emit("end");
19657
19657
  });
19658
19658
  };
19659
- SendStream.prototype.type = function type(path18) {
19659
+ SendStream.prototype.type = function type(path17) {
19660
19660
  var res = this.res;
19661
19661
  if (res.getHeader("Content-Type")) return;
19662
- var type2 = mime.lookup(path18);
19662
+ var type2 = mime.lookup(path17);
19663
19663
  if (!type2) {
19664
19664
  debug("no content-type");
19665
19665
  return;
@@ -19668,9 +19668,9 @@ var require_send = __commonJS({
19668
19668
  debug("content-type %s", type2);
19669
19669
  res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
19670
19670
  };
19671
- SendStream.prototype.setHeader = function setHeader(path18, stat) {
19671
+ SendStream.prototype.setHeader = function setHeader(path17, stat) {
19672
19672
  var res = this.res;
19673
- this.emit("headers", res, path18, stat);
19673
+ this.emit("headers", res, path17, stat);
19674
19674
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
19675
19675
  debug("accept ranges");
19676
19676
  res.setHeader("Accept-Ranges", "bytes");
@@ -19729,9 +19729,9 @@ var require_send = __commonJS({
19729
19729
  }
19730
19730
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
19731
19731
  }
19732
- function decode(path18) {
19732
+ function decode(path17) {
19733
19733
  try {
19734
- return decodeURIComponent(path18);
19734
+ return decodeURIComponent(path17);
19735
19735
  } catch (err) {
19736
19736
  return -1;
19737
19737
  }
@@ -20641,10 +20641,10 @@ var require_utils2 = __commonJS({
20641
20641
  var querystring = require("querystring");
20642
20642
  exports2.etag = createETagGenerator({ weak: false });
20643
20643
  exports2.wetag = createETagGenerator({ weak: true });
20644
- exports2.isAbsolute = function(path17) {
20645
- if ("/" === path17[0]) return true;
20646
- if (":" === path17[1] && ("\\" === path17[2] || "/" === path17[2])) return true;
20647
- if ("\\\\" === path17.substring(0, 2)) return true;
20644
+ exports2.isAbsolute = function(path16) {
20645
+ if ("/" === path16[0]) return true;
20646
+ if (":" === path16[1] && ("\\" === path16[2] || "/" === path16[2])) return true;
20647
+ if ("\\\\" === path16.substring(0, 2)) return true;
20648
20648
  };
20649
20649
  exports2.flatten = deprecate.function(
20650
20650
  flatten,
@@ -20767,13 +20767,13 @@ var require_application = __commonJS({
20767
20767
  "../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/application.js"(exports2, module2) {
20768
20768
  "use strict";
20769
20769
  var finalhandler = require_finalhandler();
20770
- var Router7 = require_router();
20770
+ var Router8 = require_router();
20771
20771
  var methods = require_methods();
20772
20772
  var middleware = require_init();
20773
20773
  var query = require_query();
20774
20774
  var debug = require_src()("express:application");
20775
20775
  var View = require_view();
20776
- var http2 = require("http");
20776
+ var http3 = require("http");
20777
20777
  var compileETag = require_utils2().compileETag;
20778
20778
  var compileQueryParser = require_utils2().compileQueryParser;
20779
20779
  var compileTrust = require_utils2().compileTrust;
@@ -20832,7 +20832,7 @@ var require_application = __commonJS({
20832
20832
  };
20833
20833
  app.lazyrouter = function lazyrouter() {
20834
20834
  if (!this._router) {
20835
- this._router = new Router7({
20835
+ this._router = new Router8({
20836
20836
  caseSensitive: this.enabled("case sensitive routing"),
20837
20837
  strict: this.enabled("strict routing")
20838
20838
  });
@@ -20855,7 +20855,7 @@ var require_application = __commonJS({
20855
20855
  };
20856
20856
  app.use = function use(fn) {
20857
20857
  var offset = 0;
20858
- var path17 = "/";
20858
+ var path16 = "/";
20859
20859
  if (typeof fn !== "function") {
20860
20860
  var arg = fn;
20861
20861
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -20863,7 +20863,7 @@ var require_application = __commonJS({
20863
20863
  }
20864
20864
  if (typeof arg !== "function") {
20865
20865
  offset = 1;
20866
- path17 = fn;
20866
+ path16 = fn;
20867
20867
  }
20868
20868
  }
20869
20869
  var fns = flatten(slice.call(arguments, offset));
@@ -20874,12 +20874,12 @@ var require_application = __commonJS({
20874
20874
  var router = this._router;
20875
20875
  fns.forEach(function(fn2) {
20876
20876
  if (!fn2 || !fn2.handle || !fn2.set) {
20877
- return router.use(path17, fn2);
20877
+ return router.use(path16, fn2);
20878
20878
  }
20879
- debug(".use app under %s", path17);
20880
- fn2.mountpath = path17;
20879
+ debug(".use app under %s", path16);
20880
+ fn2.mountpath = path16;
20881
20881
  fn2.parent = this;
20882
- router.use(path17, function mounted_app(req, res, next) {
20882
+ router.use(path16, function mounted_app(req, res, next) {
20883
20883
  var orig = req.app;
20884
20884
  fn2.handle(req, res, function(err) {
20885
20885
  setPrototypeOf(req, orig.request);
@@ -20891,9 +20891,9 @@ var require_application = __commonJS({
20891
20891
  }, this);
20892
20892
  return this;
20893
20893
  };
20894
- app.route = function route(path17) {
20894
+ app.route = function route(path16) {
20895
20895
  this.lazyrouter();
20896
- return this._router.route(path17);
20896
+ return this._router.route(path16);
20897
20897
  };
20898
20898
  app.engine = function engine(ext, fn) {
20899
20899
  if (typeof fn !== "function") {
@@ -20944,7 +20944,7 @@ var require_application = __commonJS({
20944
20944
  }
20945
20945
  return this;
20946
20946
  };
20947
- app.path = function path17() {
20947
+ app.path = function path16() {
20948
20948
  return this.parent ? this.parent.path() + this.mountpath : "";
20949
20949
  };
20950
20950
  app.enabled = function enabled(setting) {
@@ -20960,19 +20960,19 @@ var require_application = __commonJS({
20960
20960
  return this.set(setting, false);
20961
20961
  };
20962
20962
  methods.forEach(function(method) {
20963
- app[method] = function(path17) {
20963
+ app[method] = function(path16) {
20964
20964
  if (method === "get" && arguments.length === 1) {
20965
- return this.set(path17);
20965
+ return this.set(path16);
20966
20966
  }
20967
20967
  this.lazyrouter();
20968
- var route = this._router.route(path17);
20968
+ var route = this._router.route(path16);
20969
20969
  route[method].apply(route, slice.call(arguments, 1));
20970
20970
  return this;
20971
20971
  };
20972
20972
  });
20973
- app.all = function all(path17) {
20973
+ app.all = function all(path16) {
20974
20974
  this.lazyrouter();
20975
- var route = this._router.route(path17);
20975
+ var route = this._router.route(path16);
20976
20976
  var args = slice.call(arguments, 1);
20977
20977
  for (var i = 0; i < methods.length; i++) {
20978
20978
  route[methods[i]].apply(route, args);
@@ -21022,7 +21022,7 @@ var require_application = __commonJS({
21022
21022
  tryRender(view, renderOptions, done);
21023
21023
  };
21024
21024
  app.listen = function listen() {
21025
- var server = http2.createServer(this);
21025
+ var server = http3.createServer(this);
21026
21026
  return server.listen.apply(server, arguments);
21027
21027
  };
21028
21028
  function logerror(err) {
@@ -21624,12 +21624,12 @@ var require_request = __commonJS({
21624
21624
  var deprecate = require_depd()("express");
21625
21625
  var isIP = require("net").isIP;
21626
21626
  var typeis = require_type_is();
21627
- var http2 = require("http");
21627
+ var http3 = require("http");
21628
21628
  var fresh = require_fresh();
21629
21629
  var parseRange = require_range_parser();
21630
21630
  var parse = require_parseurl();
21631
21631
  var proxyaddr = require_proxy_addr();
21632
- var req = Object.create(http2.IncomingMessage.prototype);
21632
+ var req = Object.create(http3.IncomingMessage.prototype);
21633
21633
  module2.exports = req;
21634
21634
  req.get = req.header = function header(name) {
21635
21635
  if (!name) {
@@ -21731,7 +21731,7 @@ var require_request = __commonJS({
21731
21731
  var subdomains2 = !isIP(hostname2) ? hostname2.split(".").reverse() : [hostname2];
21732
21732
  return subdomains2.slice(offset);
21733
21733
  });
21734
- defineGetter(req, "path", function path17() {
21734
+ defineGetter(req, "path", function path16() {
21735
21735
  return parse(this).pathname;
21736
21736
  });
21737
21737
  defineGetter(req, "hostname", function hostname2() {
@@ -22051,10 +22051,10 @@ var require_response = __commonJS({
22051
22051
  var deprecate = require_depd()("express");
22052
22052
  var encodeUrl = require_encodeurl();
22053
22053
  var escapeHtml = require_escape_html();
22054
- var http2 = require("http");
22054
+ var http3 = require("http");
22055
22055
  var isAbsolute2 = require_utils2().isAbsolute;
22056
22056
  var onFinished = require_on_finished();
22057
- var path17 = require("path");
22057
+ var path16 = require("path");
22058
22058
  var statuses = require_statuses();
22059
22059
  var merge = require_utils_merge();
22060
22060
  var sign = require_cookie_signature().sign;
@@ -22063,11 +22063,11 @@ var require_response = __commonJS({
22063
22063
  var setCharset = require_utils2().setCharset;
22064
22064
  var cookie = require_cookie();
22065
22065
  var send = require_send();
22066
- var extname3 = path17.extname;
22066
+ var extname3 = path16.extname;
22067
22067
  var mime = send.mime;
22068
- var resolve10 = path17.resolve;
22068
+ var resolve10 = path16.resolve;
22069
22069
  var vary = require_vary();
22070
- var res = Object.create(http2.ServerResponse.prototype);
22070
+ var res = Object.create(http3.ServerResponse.prototype);
22071
22071
  module2.exports = res;
22072
22072
  var charsetRegExp = /;\s*charset\s*=/;
22073
22073
  res.status = function status(code) {
@@ -22242,26 +22242,26 @@ var require_response = __commonJS({
22242
22242
  this.type("txt");
22243
22243
  return this.send(body);
22244
22244
  };
22245
- res.sendFile = function sendFile(path18, options, callback) {
22245
+ res.sendFile = function sendFile(path17, options, callback) {
22246
22246
  var done = callback;
22247
22247
  var req = this.req;
22248
22248
  var res2 = this;
22249
22249
  var next = req.next;
22250
22250
  var opts = options || {};
22251
- if (!path18) {
22251
+ if (!path17) {
22252
22252
  throw new TypeError("path argument is required to res.sendFile");
22253
22253
  }
22254
- if (typeof path18 !== "string") {
22254
+ if (typeof path17 !== "string") {
22255
22255
  throw new TypeError("path must be a string to res.sendFile");
22256
22256
  }
22257
22257
  if (typeof options === "function") {
22258
22258
  done = options;
22259
22259
  opts = {};
22260
22260
  }
22261
- if (!opts.root && !isAbsolute2(path18)) {
22261
+ if (!opts.root && !isAbsolute2(path17)) {
22262
22262
  throw new TypeError("path must be absolute or specify root to res.sendFile");
22263
22263
  }
22264
- var pathname = encodeURI(path18);
22264
+ var pathname = encodeURI(path17);
22265
22265
  var file = send(req, pathname, opts);
22266
22266
  sendfile(res2, file, opts, function(err) {
22267
22267
  if (done) return done(err);
@@ -22271,7 +22271,7 @@ var require_response = __commonJS({
22271
22271
  }
22272
22272
  });
22273
22273
  };
22274
- res.sendfile = function(path18, options, callback) {
22274
+ res.sendfile = function(path17, options, callback) {
22275
22275
  var done = callback;
22276
22276
  var req = this.req;
22277
22277
  var res2 = this;
@@ -22281,7 +22281,7 @@ var require_response = __commonJS({
22281
22281
  done = options;
22282
22282
  opts = {};
22283
22283
  }
22284
- var file = send(req, path18, opts);
22284
+ var file = send(req, path17, opts);
22285
22285
  sendfile(res2, file, opts, function(err) {
22286
22286
  if (done) return done(err);
22287
22287
  if (err && err.code === "EISDIR") return next();
@@ -22294,7 +22294,7 @@ var require_response = __commonJS({
22294
22294
  res.sendfile,
22295
22295
  "res.sendfile: Use res.sendFile instead"
22296
22296
  );
22297
- res.download = function download(path18, filename, options, callback) {
22297
+ res.download = function download(path17, filename, options, callback) {
22298
22298
  var done = callback;
22299
22299
  var name = filename;
22300
22300
  var opts = options || null;
@@ -22311,7 +22311,7 @@ var require_response = __commonJS({
22311
22311
  opts = filename;
22312
22312
  }
22313
22313
  var headers = {
22314
- "Content-Disposition": contentDisposition(name || path18)
22314
+ "Content-Disposition": contentDisposition(name || path17)
22315
22315
  };
22316
22316
  if (opts && opts.headers) {
22317
22317
  var keys = Object.keys(opts.headers);
@@ -22324,7 +22324,7 @@ var require_response = __commonJS({
22324
22324
  }
22325
22325
  opts = Object.create(opts);
22326
22326
  opts.headers = headers;
22327
- var fullPath = !opts.root ? resolve10(path18) : path18;
22327
+ var fullPath = !opts.root ? resolve10(path17) : path17;
22328
22328
  return this.sendFile(fullPath, opts, done);
22329
22329
  };
22330
22330
  res.contentType = res.type = function contentType(type) {
@@ -22625,11 +22625,11 @@ var require_serve_static = __commonJS({
22625
22625
  }
22626
22626
  var forwardError = !fallthrough;
22627
22627
  var originalUrl = parseUrl.original(req);
22628
- var path17 = parseUrl(req).pathname;
22629
- if (path17 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22630
- path17 = "";
22628
+ var path16 = parseUrl(req).pathname;
22629
+ if (path16 === "/" && originalUrl.pathname.substr(-1) !== "/") {
22630
+ path16 = "";
22631
22631
  }
22632
- var stream = send(req, path17, opts);
22632
+ var stream = send(req, path16, opts);
22633
22633
  stream.on("directory", onDirectory);
22634
22634
  if (setHeaders) {
22635
22635
  stream.on("headers", setHeaders);
@@ -22697,7 +22697,7 @@ var require_express = __commonJS({
22697
22697
  var mixin = require_merge_descriptors();
22698
22698
  var proto = require_application();
22699
22699
  var Route = require_route();
22700
- var Router7 = require_router();
22700
+ var Router8 = require_router();
22701
22701
  var req = require_request();
22702
22702
  var res = require_response();
22703
22703
  exports2 = module2.exports = createApplication;
@@ -22720,7 +22720,7 @@ var require_express = __commonJS({
22720
22720
  exports2.request = req;
22721
22721
  exports2.response = res;
22722
22722
  exports2.Route = Route;
22723
- exports2.Router = Router7;
22723
+ exports2.Router = Router8;
22724
22724
  exports2.json = bodyParser.json;
22725
22725
  exports2.query = require_query();
22726
22726
  exports2.raw = bodyParser.raw;
@@ -22791,6 +22791,7 @@ __export(main_exports, {
22791
22791
  shouldSkipStartupRequirementsCheck: () => shouldSkipStartupRequirementsCheck
22792
22792
  });
22793
22793
  module.exports = __toCommonJS(main_exports);
22794
+ var http2 = __toESM(require("http"), 1);
22794
22795
  var nodePath = __toESM(require("path"), 1);
22795
22796
 
22796
22797
  // ../../packages/core/src/logger.ts
@@ -23149,6 +23150,13 @@ function persistNodeStartupTransport(storagePath, transport) {
23149
23150
  transport
23150
23151
  });
23151
23152
  }
23153
+ function persistNodeStartupJoin(storagePath, join13) {
23154
+ const startup = resolveNodeStartupMetadata(storagePath);
23155
+ persistNodeStartupMetadata(storagePath, {
23156
+ ...startup,
23157
+ join: join13
23158
+ });
23159
+ }
23152
23160
  function resolvePersistedDevTunnelId(storagePath, kind) {
23153
23161
  return readNodeMetadata(storagePath).devTunnelIds?.[kind]?.trim() || void 0;
23154
23162
  }
@@ -24013,19 +24021,19 @@ async function fetchWithTimeout(url, init, timeoutMs = DEFAULT_NODE_REQUEST_TIME
24013
24021
  cleanup();
24014
24022
  }
24015
24023
  }
24016
- async function fetchNodeWithFallback(node, path17, init, timeoutMs = DEFAULT_NODE_REQUEST_TIMEOUT_MS, trace) {
24024
+ async function fetchNodeWithFallback(node, path16, init, timeoutMs = DEFAULT_NODE_REQUEST_TIMEOUT_MS, trace) {
24017
24025
  let lastError;
24018
24026
  const endpoints = getNodeRequestEndpoints(node);
24019
24027
  for (const [index, endpoint] of endpoints.entries()) {
24020
24028
  const attempt = index + 1;
24021
- trace?.onAttempt?.({ attempt, endpoint, path: path17, timeoutMs, totalEndpoints: endpoints.length });
24029
+ trace?.onAttempt?.({ attempt, endpoint, path: path16, timeoutMs, totalEndpoints: endpoints.length });
24022
24030
  try {
24023
- const response = await fetchWithTimeout(`${endpoint}${path17}`, init, timeoutMs);
24024
- trace?.onResponse?.({ attempt, endpoint, path: path17, response, timeoutMs, totalEndpoints: endpoints.length });
24031
+ const response = await fetchWithTimeout(`${endpoint}${path16}`, init, timeoutMs);
24032
+ trace?.onResponse?.({ attempt, endpoint, path: path16, response, timeoutMs, totalEndpoints: endpoints.length });
24025
24033
  return { endpoint, response };
24026
24034
  } catch (error) {
24027
24035
  lastError = error;
24028
- trace?.onError?.({ attempt, endpoint, error, path: path17, timeoutMs, totalEndpoints: endpoints.length });
24036
+ trace?.onError?.({ attempt, endpoint, error, path: path16, timeoutMs, totalEndpoints: endpoints.length });
24029
24037
  }
24030
24038
  }
24031
24039
  throw lastError instanceof Error ? lastError : new Error("No reachable node endpoint");
@@ -25817,9 +25825,9 @@ var DataRouter = class {
25817
25825
  /**
25818
25826
  * Returns true if the request should be proxied to the leader.
25819
25827
  */
25820
- shouldProxy(method, path17) {
25828
+ shouldProxy(method, path16) {
25821
25829
  if (this.election.isLeader()) return false;
25822
- if (this.isExcludedPath(path17)) return false;
25830
+ if (this.isExcludedPath(path16)) return false;
25823
25831
  if (method.toUpperCase() === "GET") return false;
25824
25832
  return WRITE_METHODS.has(method.toUpperCase());
25825
25833
  }
@@ -25920,8 +25928,8 @@ var DataRouter = class {
25920
25928
  };
25921
25929
  }
25922
25930
  // ── Helpers ───────────────────────────────────────────────────────────
25923
- isExcludedPath(path17) {
25924
- return EXCLUDED_PATH_PREFIXES.some((prefix) => path17.startsWith(prefix)) || EXCLUDED_PATH_SUFFIXES.some((suffix) => path17.endsWith(suffix));
25931
+ isExcludedPath(path16) {
25932
+ return EXCLUDED_PATH_PREFIXES.some((prefix) => path16.startsWith(prefix)) || EXCLUDED_PATH_SUFFIXES.some((suffix) => path16.endsWith(suffix));
25925
25933
  }
25926
25934
  };
25927
25935
 
@@ -26935,22 +26943,34 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
26935
26943
  async joinCluster(seedUrl) {
26936
26944
  const log = this.logger.child("node/join-cluster");
26937
26945
  const tasks = this.taskEngine.listTasks().tasks;
26946
+ const self = this.nodeRegistry.getSelf();
26938
26947
  const joinBody = {
26939
- id: this.selfInfo.id,
26940
- endpoint: this.selfInfo.endpoint,
26941
- name: this.config.node.name,
26948
+ id: self.id,
26949
+ endpoint: self.endpoint,
26950
+ name: self.name,
26942
26951
  capabilities: [],
26952
+ transportType: self.transportType,
26953
+ workDir: self.workDir,
26954
+ workDirFolders: listWorkDirFolders(this.getWorkDir()),
26943
26955
  tasks
26944
26956
  };
26945
- if (this.selfInfo.devtunnelEndpoint) {
26946
- joinBody.devtunnelEndpoint = this.selfInfo.devtunnelEndpoint;
26957
+ if (self.devtunnelEndpoint) {
26958
+ joinBody.devtunnelEndpoint = self.devtunnelEndpoint;
26959
+ }
26960
+ if (self.dashboardOrigin) {
26961
+ joinBody.dashboardOrigin = self.dashboardOrigin;
26962
+ }
26963
+ if (self.previewOrigin) {
26964
+ joinBody.previewOrigin = self.previewOrigin;
26947
26965
  }
26948
26966
  log.info("sending cluster join request", {
26949
26967
  seedUrl,
26950
- nodeId: this.selfInfo.id,
26951
- endpoint: this.selfInfo.endpoint,
26968
+ nodeId: self.id,
26969
+ endpoint: self.endpoint,
26952
26970
  taskCount: tasks.length,
26953
- hasDevTunnel: !!this.selfInfo.devtunnelEndpoint
26971
+ hasDevTunnel: !!self.devtunnelEndpoint,
26972
+ hasDashboardOrigin: !!self.dashboardOrigin,
26973
+ hasPreviewOrigin: !!self.previewOrigin
26954
26974
  });
26955
26975
  let response;
26956
26976
  try {
@@ -26996,6 +27016,7 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
26996
27016
  nodeCount: data.nodes.length
26997
27017
  });
26998
27018
  this.applyClusterState(data.nodes, data.leaderId, data.term);
27019
+ persistNodeStartupJoin(this.config.storage.path, seedUrl);
26999
27020
  }
27000
27021
  async leaveCluster() {
27001
27022
  const log = this.logger.child("node/leave-cluster");
@@ -27048,6 +27069,7 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
27048
27069
  this.nodeRegistry.clearLeader();
27049
27070
  this.election.assumeLeadership();
27050
27071
  this.syncSelfInfoFromRegistry();
27072
+ persistNodeStartupJoin(this.config.storage.path, void 0);
27051
27073
  log.info("detached from leader and assumed solo leadership", {
27052
27074
  previousLeaderId: leader.id,
27053
27075
  nodeId: refreshedSelf.id,
@@ -27229,15 +27251,17 @@ ${joinErrors.map((e) => ` - ${e}`).join("\n")}`
27229
27251
  this.selfInfo.status = current.status;
27230
27252
  }
27231
27253
  applyClusterState(nodes, leaderId, term) {
27232
- const remoteSelf = nodes.find((node) => node.id === this.selfInfo.id);
27254
+ const currentSelf = this.nodeRegistry.getSelf();
27255
+ const remoteSelf = nodes.find((node) => node.id === currentSelf.id);
27233
27256
  const nextSelf = {
27234
- ...this.selfInfo,
27257
+ ...currentSelf,
27235
27258
  ...remoteSelf ?? {},
27236
27259
  transportType: this.config.transport.type,
27237
- workDir: this.selfInfo.workDir,
27260
+ workDir: currentSelf.workDir,
27238
27261
  workDirFolders: listWorkDirFolders(this.getWorkDir()),
27239
- ...this.selfInfo.devtunnelEndpoint ? { devtunnelEndpoint: this.selfInfo.devtunnelEndpoint } : {},
27240
- ...this.selfInfo.previewOrigin ? { previewOrigin: this.selfInfo.previewOrigin } : {}
27262
+ ...currentSelf.devtunnelEndpoint ? { devtunnelEndpoint: currentSelf.devtunnelEndpoint } : {},
27263
+ ...currentSelf.dashboardOrigin ? { dashboardOrigin: currentSelf.dashboardOrigin } : {},
27264
+ ...currentSelf.previewOrigin ? { previewOrigin: currentSelf.previewOrigin } : {}
27241
27265
  };
27242
27266
  this.selfInfo = nextSelf;
27243
27267
  this.nodeRegistry.setSelf(nextSelf);
@@ -27881,8 +27905,8 @@ function getErrorMap() {
27881
27905
 
27882
27906
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
27883
27907
  var makeIssue = (params) => {
27884
- const { data, path: path17, errorMaps, issueData } = params;
27885
- const fullPath = [...path17, ...issueData.path || []];
27908
+ const { data, path: path16, errorMaps, issueData } = params;
27909
+ const fullPath = [...path16, ...issueData.path || []];
27886
27910
  const fullIssue = {
27887
27911
  ...issueData,
27888
27912
  path: fullPath
@@ -27998,11 +28022,11 @@ var errorUtil;
27998
28022
 
27999
28023
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
28000
28024
  var ParseInputLazyPath = class {
28001
- constructor(parent, value, path17, key) {
28025
+ constructor(parent, value, path16, key) {
28002
28026
  this._cachedPath = [];
28003
28027
  this.parent = parent;
28004
28028
  this.data = value;
28005
- this._path = path17;
28029
+ this._path = path16;
28006
28030
  this._key = key;
28007
28031
  }
28008
28032
  get path() {
@@ -31500,7 +31524,12 @@ var JoinClusterBody = external_exports.object({
31500
31524
  endpoint: external_exports.string().url(),
31501
31525
  name: external_exports.string().min(1),
31502
31526
  capabilities: external_exports.array(external_exports.string()).default([]),
31527
+ transportType: external_exports.string().optional(),
31528
+ workDir: external_exports.string().optional(),
31529
+ workDirFolders: external_exports.array(external_exports.string()).optional(),
31503
31530
  devtunnelEndpoint: external_exports.string().url().optional(),
31531
+ dashboardOrigin: external_exports.string().url().optional(),
31532
+ previewOrigin: external_exports.string().url().optional(),
31504
31533
  tasks: external_exports.array(JoinTaskSchema).default([])
31505
31534
  });
31506
31535
  var JoinClusterResponse = external_exports.object({
@@ -31663,9 +31692,9 @@ var BatchTaskIdsBody = external_exports.object({
31663
31692
  });
31664
31693
 
31665
31694
  // ../../packages/api/src/server.ts
31666
- var path15 = __toESM(require("path"), 1);
31667
- var fs15 = __toESM(require("fs"), 1);
31668
- var import_express7 = __toESM(require_express2(), 1);
31695
+ var path14 = __toESM(require("path"), 1);
31696
+ var fs14 = __toESM(require("fs"), 1);
31697
+ var import_express8 = __toESM(require_express2(), 1);
31669
31698
 
31670
31699
  // ../../packages/api/src/middleware/auth.ts
31671
31700
  var SKIP_AUTH_PATHS = ["/api/system/health"];
@@ -31745,7 +31774,7 @@ function createAuthMiddleware(config) {
31745
31774
  return;
31746
31775
  }
31747
31776
  if (config.validateBearerToken) {
31748
- if (isTrustedDashboardRequest(req, config)) {
31777
+ if (config.allowTrustedHostBypass !== false && isTrustedDashboardRequest(req, config)) {
31749
31778
  log.debug("skipping bearer auth for trusted dashboard request", {
31750
31779
  path: req.path,
31751
31780
  method: req.method,
@@ -31933,7 +31962,9 @@ function createClusterRoutes() {
31933
31962
  name: body.name,
31934
31963
  endpoint: body.endpoint,
31935
31964
  taskCount: body.tasks?.length ?? 0,
31936
- hasDevTunnel: !!body.devtunnelEndpoint
31965
+ hasDevTunnel: !!body.devtunnelEndpoint,
31966
+ hasDashboardOrigin: !!body.dashboardOrigin,
31967
+ hasPreviewOrigin: !!body.previewOrigin
31937
31968
  });
31938
31969
  const existingNodes = nodeRegistry.getAllNodes();
31939
31970
  let removedCount = 0;
@@ -31952,7 +31983,12 @@ function createClusterRoutes() {
31952
31983
  capabilities: body.capabilities ?? [],
31953
31984
  joinedAt: Date.now(),
31954
31985
  lastHeartbeat: Date.now(),
31955
- ...body.devtunnelEndpoint && { devtunnelEndpoint: body.devtunnelEndpoint }
31986
+ ...body.transportType && { transportType: body.transportType },
31987
+ ...body.workDir && { workDir: body.workDir },
31988
+ ...body.workDirFolders && { workDirFolders: body.workDirFolders },
31989
+ ...body.devtunnelEndpoint && { devtunnelEndpoint: body.devtunnelEndpoint },
31990
+ ...body.dashboardOrigin && { dashboardOrigin: body.dashboardOrigin },
31991
+ ...body.previewOrigin && { previewOrigin: body.previewOrigin }
31956
31992
  };
31957
31993
  nodeRegistry.addNode(node);
31958
31994
  taskEngine.importTasks(body.tasks ?? []);
@@ -32080,174 +32116,72 @@ function assertCanChangeNodeDevTunnel(taskEngine, nodeId) {
32080
32116
  );
32081
32117
  }
32082
32118
 
32083
- // ../../packages/api/src/worker-control.ts
32084
- var fs12 = __toESM(require("fs"), 1);
32085
- var path13 = __toESM(require("path"), 1);
32086
-
32087
- // ../../packages/api/src/preview/preview-server.ts
32088
- var crypto2 = __toESM(require("crypto"), 1);
32089
- var fs10 = __toESM(require("fs"), 1);
32090
- var path11 = __toESM(require("path"), 1);
32091
- var http = __toESM(require("http"), 1);
32092
- function resolvePreviewPath(rootPath, relativePath) {
32093
- const sanitizedPath = relativePath.replace(/\\/g, "/");
32094
- const resolvedPath = path11.resolve(rootPath, sanitizedPath);
32095
- const normalizedRoot = path11.resolve(rootPath);
32096
- if (!resolvedPath.startsWith(normalizedRoot + path11.sep) && resolvedPath !== normalizedRoot) {
32097
- throw new Error("Invalid preview path");
32098
- }
32099
- return {
32100
- absolutePath: resolvedPath,
32101
- normalizedPath: path11.relative(normalizedRoot, resolvedPath).split(path11.sep).join("/")
32102
- };
32103
- }
32104
- function resolvePreviewEntryPath(rootPath, entryPath) {
32105
- const { absolutePath, normalizedPath } = resolvePreviewPath(rootPath, entryPath ?? "index.html");
32106
- if (!fs10.existsSync(absolutePath) || !fs10.statSync(absolutePath).isFile()) {
32107
- throw new Error("Preview entry not found");
32108
- }
32109
- return normalizedPath;
32110
- }
32111
- function buildPreviewUrl(origin, session) {
32112
- const encodedEntryPath = session.entryPath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
32113
- return `${origin.replace(/\/+$/, "")}/preview/${session.token}/${encodedEntryPath}`;
32114
- }
32115
- var DEFAULT_TTL_MS = 15 * 60 * 1e3;
32116
- var PreviewSessionManager = class {
32117
- sessions = /* @__PURE__ */ new Map();
32118
- create(options) {
32119
- const token = crypto2.randomBytes(32).toString("hex");
32120
- const entryPath = resolvePreviewEntryPath(options.rootPath, options.entryPath);
32121
- const session = {
32122
- token,
32123
- taskId: options.taskId,
32124
- rootPath: options.rootPath,
32125
- entryPath,
32126
- expiresAt: Date.now() + (options.ttlMs ?? DEFAULT_TTL_MS)
32127
- };
32128
- this.sessions.set(token, session);
32129
- return session;
32130
- }
32131
- get(token) {
32132
- const session = this.sessions.get(token);
32133
- if (!session) return null;
32134
- if (Date.now() > session.expiresAt) {
32135
- this.sessions.delete(token);
32136
- return null;
32119
+ // ../../packages/api/src/task-cancellation.ts
32120
+ var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
32121
+ function cancelTaskOnCurrentNode(deps, taskId, options = {}) {
32122
+ const task = deps.taskEngine.getTask(taskId);
32123
+ if (!task) {
32124
+ if (options.missingOk) {
32125
+ return {
32126
+ task: null,
32127
+ cancelled: false,
32128
+ engineCancelRequested: false,
32129
+ missing: true,
32130
+ terminal: false
32131
+ };
32137
32132
  }
32138
- return session;
32133
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
32139
32134
  }
32140
- cleanup() {
32141
- const now = Date.now();
32142
- for (const [token, session] of this.sessions) {
32143
- if (now > session.expiresAt) {
32144
- this.sessions.delete(token);
32145
- }
32135
+ if (TERMINAL_STATUSES2.has(task.status)) {
32136
+ if (options.terminalOk) {
32137
+ return {
32138
+ task,
32139
+ cancelled: false,
32140
+ engineCancelRequested: false,
32141
+ missing: false,
32142
+ terminal: true
32143
+ };
32146
32144
  }
32145
+ throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled (status: ${task.status})`, 400);
32147
32146
  }
32148
- };
32149
- var MIME_MAP = {
32150
- ".html": "text/html",
32151
- ".htm": "text/html",
32152
- ".css": "text/css",
32153
- ".js": "text/javascript",
32154
- ".mjs": "text/javascript",
32155
- ".json": "application/json",
32156
- ".png": "image/png",
32157
- ".jpg": "image/jpeg",
32158
- ".jpeg": "image/jpeg",
32159
- ".gif": "image/gif",
32160
- ".svg": "image/svg+xml",
32161
- ".webp": "image/webp",
32162
- ".ico": "image/x-icon",
32163
- ".woff": "font/woff",
32164
- ".woff2": "font/woff2",
32165
- ".ttf": "font/ttf",
32166
- ".eot": "application/vnd.ms-fontobject",
32167
- ".pdf": "application/pdf"
32168
- };
32169
- function getMime(filePath) {
32170
- return MIME_MAP[path11.extname(filePath).toLowerCase()] ?? "application/octet-stream";
32171
- }
32172
- var PreviewServer = class {
32173
- server = null;
32174
- sessionManager;
32175
- constructor(sessionManager) {
32176
- this.sessionManager = sessionManager;
32177
- }
32178
- async start(port) {
32179
- return new Promise((resolve10, reject) => {
32180
- this.server = http.createServer((req, res) => this.handleRequest(req, res));
32181
- this.server.listen(port, () => {
32182
- const addr = this.server.address();
32183
- const actualPort = typeof addr === "object" && addr ? addr.port : port;
32184
- resolve10(actualPort);
32147
+ let engineCancelRequested = false;
32148
+ if (task.status === "running") {
32149
+ const engine = deps.engineRegistry.get(task.agent);
32150
+ if (!engine || typeof engine.cancelTask !== "function") {
32151
+ deps.logger.warn("engine not registered while cancelling running task", {
32152
+ taskId,
32153
+ agent: task.agent
32185
32154
  });
32186
- this.server.on("error", reject);
32187
- });
32188
- }
32189
- async stop() {
32190
- return new Promise((resolve10) => {
32191
- if (!this.server) {
32192
- resolve10();
32193
- return;
32155
+ } else {
32156
+ engineCancelRequested = engine.cancelTask(taskId);
32157
+ if (!engineCancelRequested) {
32158
+ deps.logger.warn("running task had no active engine process to cancel", {
32159
+ taskId,
32160
+ agent: task.agent
32161
+ });
32194
32162
  }
32195
- this.server.close(() => resolve10());
32196
- });
32197
- }
32198
- getPort() {
32199
- if (!this.server) return null;
32200
- const addr = this.server.address();
32201
- return typeof addr === "object" && addr ? addr.port : null;
32202
- }
32203
- handleRequest(req, res) {
32204
- if (req.method !== "GET") {
32205
- res.writeHead(405, { "Content-Type": "text/plain" });
32206
- res.end("Method not allowed");
32207
- return;
32208
32163
  }
32209
- const url = new URL(req.url ?? "/", `http://localhost`);
32210
- const match = url.pathname.match(/^\/preview\/([a-f0-9]+)(?:\/(.*))?$/i);
32211
- const token = match?.[1];
32212
- if (!token) {
32213
- res.writeHead(404, { "Content-Type": "text/plain" });
32214
- res.end("Preview not found");
32215
- return;
32216
- }
32217
- const session = this.sessionManager.get(token);
32218
- if (!session) {
32219
- res.writeHead(403, { "Content-Type": "text/plain" });
32220
- res.end("Invalid or expired preview token");
32221
- return;
32222
- }
32223
- const requestedPath = decodeURIComponent(match?.[2] ?? session.entryPath);
32224
- let resolved;
32225
- try {
32226
- resolved = resolvePreviewPath(session.rootPath, requestedPath).absolutePath;
32227
- } catch {
32228
- res.writeHead(400, { "Content-Type": "text/plain" });
32229
- res.end("Invalid path");
32230
- return;
32231
- }
32232
- if (!fs10.existsSync(resolved) || !fs10.statSync(resolved).isFile()) {
32233
- res.writeHead(404, { "Content-Type": "text/plain" });
32234
- res.end("File not found");
32235
- return;
32236
- }
32237
- const mime = getMime(resolved);
32238
- const content = fs10.readFileSync(resolved);
32239
- res.writeHead(200, {
32240
- "Content-Type": mime,
32241
- "Content-Length": content.length,
32242
- "Cache-Control": "no-cache"
32243
- });
32244
- res.end(content);
32245
32164
  }
32246
- };
32165
+ const cancelled = deps.taskEngine.cancelTask(taskId);
32166
+ if (!cancelled) {
32167
+ throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled`, 400);
32168
+ }
32169
+ return {
32170
+ task,
32171
+ cancelled: true,
32172
+ engineCancelRequested,
32173
+ missing: false,
32174
+ terminal: false
32175
+ };
32176
+ }
32177
+
32178
+ // ../../packages/api/src/task-output-service.ts
32179
+ var fs12 = __toESM(require("fs"), 1);
32180
+ var path13 = __toESM(require("path"), 1);
32247
32181
 
32248
32182
  // ../../packages/api/src/output/helpers.ts
32249
- var fs11 = __toESM(require("fs"), 1);
32250
- var path12 = __toESM(require("path"), 1);
32183
+ var fs10 = __toESM(require("fs"), 1);
32184
+ var path11 = __toESM(require("path"), 1);
32251
32185
  var MAX_INLINE_SIZE = 512 * 1024;
32252
32186
  var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
32253
32187
  ".txt",
@@ -32324,7 +32258,7 @@ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
32324
32258
  ".ico",
32325
32259
  ".avif"
32326
32260
  ]);
32327
- var MIME_MAP2 = {
32261
+ var MIME_MAP = {
32328
32262
  ".png": "image/png",
32329
32263
  ".jpg": "image/jpeg",
32330
32264
  ".jpeg": "image/jpeg",
@@ -32357,18 +32291,18 @@ var MIME_MAP2 = {
32357
32291
  ".sh": "text/x-shellscript"
32358
32292
  };
32359
32293
  function mimeForExt(ext) {
32360
- return MIME_MAP2[ext] ?? "application/octet-stream";
32294
+ return MIME_MAP[ext] ?? "application/octet-stream";
32361
32295
  }
32362
32296
  function resolveOutputPath(root, relativePath) {
32363
- const resolved = path12.resolve(root, relativePath);
32364
- const normalizedRoot = path12.resolve(root);
32365
- if (!resolved.startsWith(normalizedRoot + path12.sep) && resolved !== normalizedRoot) {
32297
+ const resolved = path11.resolve(root, relativePath);
32298
+ const normalizedRoot = path11.resolve(root);
32299
+ if (!resolved.startsWith(normalizedRoot + path11.sep) && resolved !== normalizedRoot) {
32366
32300
  throw new Error("Path traversal detected");
32367
32301
  }
32368
32302
  return resolved;
32369
32303
  }
32370
32304
  function classifyFile(filePath) {
32371
- const ext = path12.extname(filePath).toLowerCase();
32305
+ const ext = path11.extname(filePath).toLowerCase();
32372
32306
  if (ext === ".json" || ext === ".jsonl" || ext === ".ndjson") {
32373
32307
  return { kind: "json", mimeType: "application/json" };
32374
32308
  }
@@ -32395,14 +32329,14 @@ function classifyFile(filePath) {
32395
32329
  }
32396
32330
  function listDirectory(root, relativePath) {
32397
32331
  const absPath = resolveOutputPath(root, relativePath);
32398
- if (!fs11.existsSync(absPath) || !fs11.statSync(absPath).isDirectory()) {
32332
+ if (!fs10.existsSync(absPath) || !fs10.statSync(absPath).isDirectory()) {
32399
32333
  return [];
32400
32334
  }
32401
- const entries = fs11.readdirSync(absPath, { withFileTypes: true });
32335
+ const entries = fs10.readdirSync(absPath, { withFileTypes: true });
32402
32336
  const result = [];
32403
32337
  for (const entry of entries) {
32404
32338
  if (entry.name.startsWith(".")) continue;
32405
- const entryRelPath = path12.join(relativePath || ".", entry.name).split(path12.sep).join("/");
32339
+ const entryRelPath = path11.join(relativePath || ".", entry.name).split(path11.sep).join("/");
32406
32340
  if (entry.isDirectory()) {
32407
32341
  result.push({
32408
32342
  path: entryRelPath,
@@ -32410,8 +32344,8 @@ function listDirectory(root, relativePath) {
32410
32344
  type: "directory"
32411
32345
  });
32412
32346
  } else if (entry.isFile()) {
32413
- const fullPath = path12.join(absPath, entry.name);
32414
- const stat = fs11.statSync(fullPath);
32347
+ const fullPath = path11.join(absPath, entry.name);
32348
+ const stat = fs10.statSync(fullPath);
32415
32349
  const { kind, mimeType } = classifyFile(entry.name);
32416
32350
  result.push({
32417
32351
  path: entryRelPath,
@@ -32431,11 +32365,11 @@ function listDirectory(root, relativePath) {
32431
32365
  }
32432
32366
  function detectHtmlEntries(root) {
32433
32367
  const entries = [];
32434
- if (fs11.existsSync(path12.join(root, "index.html"))) {
32368
+ if (fs10.existsSync(path11.join(root, "index.html"))) {
32435
32369
  entries.push({ path: "index.html", label: "index.html" });
32436
32370
  }
32437
32371
  try {
32438
- const topLevel = fs11.readdirSync(root, { withFileTypes: true });
32372
+ const topLevel = fs10.readdirSync(root, { withFileTypes: true });
32439
32373
  const htmlFiles = topLevel.filter(
32440
32374
  (e) => e.isFile() && e.name.endsWith(".html") && !e.name.startsWith(".")
32441
32375
  );
@@ -32446,8 +32380,8 @@ function detectHtmlEntries(root) {
32446
32380
  }
32447
32381
  const subdirs = topLevel.filter((e) => e.isDirectory() && !e.name.startsWith("."));
32448
32382
  for (const dir of subdirs) {
32449
- const subIndex = path12.join(root, dir.name, "index.html");
32450
- if (fs11.existsSync(subIndex)) {
32383
+ const subIndex = path11.join(root, dir.name, "index.html");
32384
+ if (fs10.existsSync(subIndex)) {
32451
32385
  entries.push({
32452
32386
  path: `${dir.name}/index.html`,
32453
32387
  label: `${dir.name}/index.html`
@@ -32459,11 +32393,11 @@ function detectHtmlEntries(root) {
32459
32393
  return entries;
32460
32394
  }
32461
32395
  function getOutputSummary(root) {
32462
- const rootName = path12.basename(root);
32396
+ const rootName = path11.basename(root);
32463
32397
  const htmlEntries = detectHtmlEntries(root);
32464
32398
  let fileCount;
32465
32399
  try {
32466
- const entries = fs11.readdirSync(root, { withFileTypes: true });
32400
+ const entries = fs10.readdirSync(root, { withFileTypes: true });
32467
32401
  fileCount = entries.filter((e) => !e.name.startsWith(".")).length;
32468
32402
  } catch {
32469
32403
  fileCount = void 0;
@@ -32479,14 +32413,14 @@ function getOutputSummary(root) {
32479
32413
  }
32480
32414
  function readFileContent(root, relativePath) {
32481
32415
  const absPath = resolveOutputPath(root, relativePath);
32482
- if (!fs11.existsSync(absPath) || !fs11.statSync(absPath).isFile()) {
32416
+ if (!fs10.existsSync(absPath) || !fs10.statSync(absPath).isFile()) {
32483
32417
  throw new Error("File not found");
32484
32418
  }
32485
- const stat = fs11.statSync(absPath);
32419
+ const stat = fs10.statSync(absPath);
32486
32420
  const { kind, mimeType } = classifyFile(absPath);
32487
32421
  if (kind === "image" || kind === "pdf" || kind === "binary") {
32488
32422
  const truncated2 = stat.size > MAX_INLINE_SIZE;
32489
- const buffer = truncated2 ? Buffer.alloc(0) : fs11.readFileSync(absPath);
32423
+ const buffer = truncated2 ? Buffer.alloc(0) : fs10.readFileSync(absPath);
32490
32424
  return {
32491
32425
  path: relativePath,
32492
32426
  kind,
@@ -32497,7 +32431,7 @@ function readFileContent(root, relativePath) {
32497
32431
  };
32498
32432
  }
32499
32433
  const truncated = stat.size > MAX_INLINE_SIZE;
32500
- const content = truncated ? fs11.readFileSync(absPath, "utf-8").slice(0, MAX_INLINE_SIZE) : fs11.readFileSync(absPath, "utf-8");
32434
+ const content = truncated ? fs10.readFileSync(absPath, "utf-8").slice(0, MAX_INLINE_SIZE) : fs10.readFileSync(absPath, "utf-8");
32501
32435
  return {
32502
32436
  path: relativePath,
32503
32437
  kind,
@@ -32557,62 +32491,264 @@ function getGitDiff(dirPath) {
32557
32491
  };
32558
32492
  }
32559
32493
 
32560
- // ../../packages/api/src/task-cancellation.ts
32561
- var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
32562
- function cancelTaskOnCurrentNode(deps, taskId, options = {}) {
32563
- const task = deps.taskEngine.getTask(taskId);
32564
- if (!task) {
32565
- if (options.missingOk) {
32566
- return {
32567
- task: null,
32568
- cancelled: false,
32569
- engineCancelRequested: false,
32570
- missing: true,
32571
- terminal: false
32572
- };
32494
+ // ../../packages/api/src/preview/preview-server.ts
32495
+ var crypto2 = __toESM(require("crypto"), 1);
32496
+ var fs11 = __toESM(require("fs"), 1);
32497
+ var path12 = __toESM(require("path"), 1);
32498
+ var http = __toESM(require("http"), 1);
32499
+ function resolvePreviewPath(rootPath, relativePath) {
32500
+ const sanitizedPath = relativePath.replace(/\\/g, "/");
32501
+ const resolvedPath = path12.resolve(rootPath, sanitizedPath);
32502
+ const normalizedRoot = path12.resolve(rootPath);
32503
+ if (!resolvedPath.startsWith(normalizedRoot + path12.sep) && resolvedPath !== normalizedRoot) {
32504
+ throw new Error("Invalid preview path");
32505
+ }
32506
+ return {
32507
+ absolutePath: resolvedPath,
32508
+ normalizedPath: path12.relative(normalizedRoot, resolvedPath).split(path12.sep).join("/")
32509
+ };
32510
+ }
32511
+ function resolvePreviewEntryPath(rootPath, entryPath) {
32512
+ const { absolutePath, normalizedPath } = resolvePreviewPath(rootPath, entryPath ?? "index.html");
32513
+ if (!fs11.existsSync(absolutePath) || !fs11.statSync(absolutePath).isFile()) {
32514
+ throw new Error("Preview entry not found");
32515
+ }
32516
+ return normalizedPath;
32517
+ }
32518
+ function buildPreviewUrl(origin, session) {
32519
+ const encodedEntryPath = session.entryPath.split("/").filter(Boolean).map((segment) => encodeURIComponent(segment)).join("/");
32520
+ return `${origin.replace(/\/+$/, "")}/preview/${session.token}/${encodedEntryPath}`;
32521
+ }
32522
+ var DEFAULT_TTL_MS = 15 * 60 * 1e3;
32523
+ var PreviewSessionManager = class {
32524
+ sessions = /* @__PURE__ */ new Map();
32525
+ create(options) {
32526
+ const token = crypto2.randomBytes(32).toString("hex");
32527
+ const entryPath = resolvePreviewEntryPath(options.rootPath, options.entryPath);
32528
+ const session = {
32529
+ token,
32530
+ taskId: options.taskId,
32531
+ rootPath: options.rootPath,
32532
+ entryPath,
32533
+ expiresAt: Date.now() + (options.ttlMs ?? DEFAULT_TTL_MS)
32534
+ };
32535
+ this.sessions.set(token, session);
32536
+ return session;
32537
+ }
32538
+ get(token) {
32539
+ const session = this.sessions.get(token);
32540
+ if (!session) return null;
32541
+ if (Date.now() > session.expiresAt) {
32542
+ this.sessions.delete(token);
32543
+ return null;
32573
32544
  }
32545
+ return session;
32546
+ }
32547
+ cleanup() {
32548
+ const now = Date.now();
32549
+ for (const [token, session] of this.sessions) {
32550
+ if (now > session.expiresAt) {
32551
+ this.sessions.delete(token);
32552
+ }
32553
+ }
32554
+ }
32555
+ };
32556
+ var MIME_MAP2 = {
32557
+ ".html": "text/html",
32558
+ ".htm": "text/html",
32559
+ ".css": "text/css",
32560
+ ".js": "text/javascript",
32561
+ ".mjs": "text/javascript",
32562
+ ".json": "application/json",
32563
+ ".png": "image/png",
32564
+ ".jpg": "image/jpeg",
32565
+ ".jpeg": "image/jpeg",
32566
+ ".gif": "image/gif",
32567
+ ".svg": "image/svg+xml",
32568
+ ".webp": "image/webp",
32569
+ ".ico": "image/x-icon",
32570
+ ".woff": "font/woff",
32571
+ ".woff2": "font/woff2",
32572
+ ".ttf": "font/ttf",
32573
+ ".eot": "application/vnd.ms-fontobject",
32574
+ ".pdf": "application/pdf"
32575
+ };
32576
+ function getMime(filePath) {
32577
+ return MIME_MAP2[path12.extname(filePath).toLowerCase()] ?? "application/octet-stream";
32578
+ }
32579
+ function handlePreviewRequest(sessionManager, req, res) {
32580
+ const url = new URL(req.url ?? "/", "http://localhost");
32581
+ if (!url.pathname.startsWith("/preview/")) {
32582
+ return false;
32583
+ }
32584
+ if (req.method !== "GET") {
32585
+ res.writeHead(405, { "Content-Type": "text/plain" });
32586
+ res.end("Method not allowed");
32587
+ return true;
32588
+ }
32589
+ const match = url.pathname.match(/^\/preview\/([a-f0-9]+)(?:\/(.*))?$/i);
32590
+ const token = match?.[1];
32591
+ if (!token) {
32592
+ res.writeHead(404, { "Content-Type": "text/plain" });
32593
+ res.end("Preview not found");
32594
+ return true;
32595
+ }
32596
+ const session = sessionManager.get(token);
32597
+ if (!session) {
32598
+ res.writeHead(403, { "Content-Type": "text/plain" });
32599
+ res.end("Invalid or expired preview token");
32600
+ return true;
32601
+ }
32602
+ const requestedPath = decodeURIComponent(match?.[2] ?? session.entryPath);
32603
+ let resolved;
32604
+ try {
32605
+ resolved = resolvePreviewPath(session.rootPath, requestedPath).absolutePath;
32606
+ } catch {
32607
+ res.writeHead(400, { "Content-Type": "text/plain" });
32608
+ res.end("Invalid path");
32609
+ return true;
32610
+ }
32611
+ if (!fs11.existsSync(resolved) || !fs11.statSync(resolved).isFile()) {
32612
+ res.writeHead(404, { "Content-Type": "text/plain" });
32613
+ res.end("File not found");
32614
+ return true;
32615
+ }
32616
+ const mime = getMime(resolved);
32617
+ const content = fs11.readFileSync(resolved);
32618
+ res.writeHead(200, {
32619
+ "Content-Type": mime,
32620
+ "Content-Length": content.length,
32621
+ "Cache-Control": "no-cache"
32622
+ });
32623
+ res.end(content);
32624
+ return true;
32625
+ }
32626
+
32627
+ // ../../packages/api/src/task-output-service.ts
32628
+ var TASK_OUTPUT_ROUTE_PREFIX = "/api/tasks";
32629
+ function getTask(taskEngine, taskId) {
32630
+ const task = taskEngine.getTask(taskId);
32631
+ if (!task) {
32574
32632
  throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
32575
32633
  }
32576
- if (TERMINAL_STATUSES2.has(task.status)) {
32577
- if (options.terminalOk) {
32578
- return {
32579
- task,
32580
- cancelled: false,
32581
- engineCancelRequested: false,
32582
- missing: false,
32583
- terminal: true
32584
- };
32634
+ return task;
32635
+ }
32636
+ function getTaskOutputRoot(taskEngine, taskId) {
32637
+ const task = getTask(taskEngine, taskId);
32638
+ if (!task.effectiveProjectPath) {
32639
+ throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
32640
+ }
32641
+ return task.effectiveProjectPath;
32642
+ }
32643
+ function buildTaskOutputDownloadUrl(taskId, filePath) {
32644
+ return `${TASK_OUTPUT_ROUTE_PREFIX}/${taskId}/output/download?path=${encodeURIComponent(filePath)}`;
32645
+ }
32646
+ function getLocalTaskOutputSummary(taskEngine, taskId) {
32647
+ const task = getTask(taskEngine, taskId);
32648
+ if (!task.effectiveProjectPath) {
32649
+ return {
32650
+ taskId: task.id,
32651
+ requestedProject: task.project,
32652
+ effectiveProjectPath: null,
32653
+ assignedTo: task.assignedTo,
32654
+ available: false,
32655
+ summary: null
32656
+ };
32657
+ }
32658
+ return {
32659
+ taskId: task.id,
32660
+ requestedProject: task.project,
32661
+ effectiveProjectPath: task.effectiveProjectPath,
32662
+ assignedTo: task.assignedTo,
32663
+ available: true,
32664
+ summary: getOutputSummary(task.effectiveProjectPath)
32665
+ };
32666
+ }
32667
+ function getLocalTaskOutputTree(taskEngine, taskId, currentPath) {
32668
+ const rootPath = getTaskOutputRoot(taskEngine, taskId);
32669
+ try {
32670
+ return {
32671
+ rootPath,
32672
+ currentPath,
32673
+ entries: listDirectory(rootPath, currentPath)
32674
+ };
32675
+ } catch (err) {
32676
+ if (err instanceof Error && err.message === "Path traversal detected") {
32677
+ throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
32585
32678
  }
32586
- throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled (status: ${task.status})`, 400);
32679
+ throw err;
32587
32680
  }
32588
- let engineCancelRequested = false;
32589
- if (task.status === "running") {
32590
- const engine = deps.engineRegistry.get(task.agent);
32591
- if (!engine || typeof engine.cancelTask !== "function") {
32592
- deps.logger.warn("engine not registered while cancelling running task", {
32593
- taskId,
32594
- agent: task.agent
32595
- });
32596
- } else {
32597
- engineCancelRequested = engine.cancelTask(taskId);
32598
- if (!engineCancelRequested) {
32599
- deps.logger.warn("running task had no active engine process to cancel", {
32600
- taskId,
32601
- agent: task.agent
32602
- });
32681
+ }
32682
+ function getLocalTaskOutputContent(taskEngine, taskId, filePath) {
32683
+ const rootPath = getTaskOutputRoot(taskEngine, taskId);
32684
+ try {
32685
+ return {
32686
+ ...readFileContent(rootPath, filePath),
32687
+ downloadUrl: buildTaskOutputDownloadUrl(taskId, filePath)
32688
+ };
32689
+ } catch (err) {
32690
+ if (err instanceof Error && err.message === "Path traversal detected") {
32691
+ throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
32692
+ }
32693
+ if (err instanceof Error && err.message === "File not found") {
32694
+ throw new MeshyError("TASK_NOT_FOUND", `File not found: ${filePath}`, 404);
32695
+ }
32696
+ throw err;
32697
+ }
32698
+ }
32699
+ function getLocalTaskOutputDownload(taskEngine, taskId, filePath) {
32700
+ const rootPath = getTaskOutputRoot(taskEngine, taskId);
32701
+ try {
32702
+ const absolutePath = resolveOutputPath(rootPath, filePath);
32703
+ if (!fs12.existsSync(absolutePath) || !fs12.statSync(absolutePath).isFile()) {
32704
+ throw new MeshyError("TASK_NOT_FOUND", `File not found: ${filePath}`, 404);
32705
+ }
32706
+ const { mimeType } = classifyFile(absolutePath);
32707
+ const fileName = path13.basename(absolutePath).replace(/"/g, "");
32708
+ return {
32709
+ content: fs12.readFileSync(absolutePath),
32710
+ headers: {
32711
+ "Content-Type": mimeType,
32712
+ "Content-Disposition": `inline; filename="${fileName}"`,
32713
+ "Cache-Control": "no-cache"
32603
32714
  }
32715
+ };
32716
+ } catch (err) {
32717
+ if (err instanceof MeshyError) {
32718
+ throw err;
32719
+ }
32720
+ if (err instanceof Error && err.message === "Path traversal detected") {
32721
+ throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
32604
32722
  }
32723
+ throw err;
32605
32724
  }
32606
- const cancelled = deps.taskEngine.cancelTask(taskId);
32607
- if (!cancelled) {
32608
- throw new MeshyError("VALIDATION_ERROR", `Task ${taskId} cannot be cancelled`, 400);
32725
+ }
32726
+ function getLocalTaskOutputDiff(taskEngine, taskId) {
32727
+ const rootPath = getTaskOutputRoot(taskEngine, taskId);
32728
+ return getGitDiff(rootPath);
32729
+ }
32730
+ async function createPreviewSessionPayload(deps, taskId, entryPath) {
32731
+ const previewManager = deps.previewSessionManager;
32732
+ if (!previewManager) {
32733
+ throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
32734
+ }
32735
+ if (!deps.previewPort) {
32736
+ throw new MeshyError("VALIDATION_ERROR", "Preview server not running", 400);
32737
+ }
32738
+ const rootPath = getTaskOutputRoot(deps.taskEngine, taskId);
32739
+ const session = previewManager.create({
32740
+ taskId,
32741
+ rootPath,
32742
+ entryPath
32743
+ });
32744
+ const origin = deps.ensurePreviewOrigin ? await deps.ensurePreviewOrigin() ?? deps.previewOrigin : deps.previewOrigin;
32745
+ if (!origin) {
32746
+ throw new MeshyError("VALIDATION_ERROR", "Preview origin not available", 502);
32609
32747
  }
32610
32748
  return {
32611
- task,
32612
- cancelled: true,
32613
- engineCancelRequested,
32614
- missing: false,
32615
- terminal: false
32749
+ previewUrl: buildPreviewUrl(origin, session),
32750
+ expiresAt: session.expiresAt,
32751
+ entryPath: session.entryPath
32616
32752
  };
32617
32753
  }
32618
32754
 
@@ -32654,44 +32790,6 @@ function errorResponse(requestId, err) {
32654
32790
  }
32655
32791
  });
32656
32792
  }
32657
- function getTask(taskEngine, taskId) {
32658
- const task = taskEngine.getTask(taskId);
32659
- if (!task) {
32660
- throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
32661
- }
32662
- return task;
32663
- }
32664
- function getTaskOutputRoot(taskEngine, taskId) {
32665
- const task = getTask(taskEngine, taskId);
32666
- if (!task.effectiveProjectPath) {
32667
- throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
32668
- }
32669
- return task.effectiveProjectPath;
32670
- }
32671
- async function createPreviewSessionPayload(deps, taskId, entryPath) {
32672
- const previewManager = deps.previewSessionManager;
32673
- if (!previewManager) {
32674
- throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
32675
- }
32676
- if (!deps.previewPort) {
32677
- throw new MeshyError("VALIDATION_ERROR", "Preview server not running", 400);
32678
- }
32679
- const rootPath = getTaskOutputRoot(deps.taskEngine, taskId);
32680
- const session = previewManager.create({
32681
- taskId,
32682
- rootPath,
32683
- entryPath
32684
- });
32685
- const origin = deps.ensurePreviewOrigin ? await deps.ensurePreviewOrigin() ?? deps.previewOrigin : deps.previewOrigin;
32686
- if (!origin) {
32687
- throw new MeshyError("VALIDATION_ERROR", "Preview origin not available", 502);
32688
- }
32689
- return {
32690
- previewUrl: buildPreviewUrl(origin, session),
32691
- expiresAt: session.expiresAt,
32692
- entryPath: session.entryPath
32693
- };
32694
- }
32695
32793
  async function executeWorkerControlRequest(deps, request) {
32696
32794
  const log = deps.logger.child("worker-control");
32697
32795
  log.info("received worker control request", {
@@ -32751,89 +32849,40 @@ async function executeWorkerControlRequest(deps, request) {
32751
32849
  break;
32752
32850
  }
32753
32851
  case "task-output-summary": {
32754
- const task = getTask(deps.taskEngine, request.taskId ?? "");
32755
- if (!task.effectiveProjectPath) {
32756
- response = jsonResponse(request.requestId, 200, {
32757
- taskId: task.id,
32758
- requestedProject: task.project,
32759
- effectiveProjectPath: null,
32760
- assignedTo: task.assignedTo,
32761
- available: false,
32762
- summary: null
32763
- });
32764
- break;
32765
- }
32766
- response = jsonResponse(request.requestId, 200, {
32767
- taskId: task.id,
32768
- requestedProject: task.project,
32769
- effectiveProjectPath: task.effectiveProjectPath,
32770
- assignedTo: task.assignedTo,
32771
- available: true,
32772
- summary: getOutputSummary(task.effectiveProjectPath)
32773
- });
32852
+ response = jsonResponse(
32853
+ request.requestId,
32854
+ 200,
32855
+ getLocalTaskOutputSummary(deps.taskEngine, request.taskId ?? "")
32856
+ );
32774
32857
  break;
32775
32858
  }
32776
32859
  case "task-output-tree": {
32777
- const rootPath = getTaskOutputRoot(deps.taskEngine, request.taskId ?? "");
32778
- try {
32779
- response = jsonResponse(request.requestId, 200, {
32780
- rootPath,
32781
- currentPath: request.path ?? ".",
32782
- entries: listDirectory(rootPath, request.path ?? ".")
32783
- });
32784
- break;
32785
- } catch (err) {
32786
- if (err instanceof Error && err.message === "Path traversal detected") {
32787
- throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
32788
- }
32789
- throw err;
32790
- }
32860
+ response = jsonResponse(
32861
+ request.requestId,
32862
+ 200,
32863
+ getLocalTaskOutputTree(deps.taskEngine, request.taskId ?? "", request.path ?? ".")
32864
+ );
32865
+ break;
32791
32866
  }
32792
32867
  case "task-output-content": {
32793
- const rootPath = getTaskOutputRoot(deps.taskEngine, request.taskId ?? "");
32794
- try {
32795
- const filePath = request.path ?? "";
32796
- response = jsonResponse(request.requestId, 200, {
32797
- ...readFileContent(rootPath, filePath),
32798
- downloadUrl: `/api/tasks/${request.taskId}/output/download?path=${encodeURIComponent(filePath)}`
32799
- });
32800
- break;
32801
- } catch (err) {
32802
- if (err instanceof Error && err.message === "Path traversal detected") {
32803
- throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
32804
- }
32805
- if (err instanceof Error && err.message === "File not found") {
32806
- throw new MeshyError("TASK_NOT_FOUND", `File not found: ${request.path}`, 404);
32807
- }
32808
- throw err;
32809
- }
32868
+ response = jsonResponse(
32869
+ request.requestId,
32870
+ 200,
32871
+ getLocalTaskOutputContent(deps.taskEngine, request.taskId ?? "", request.path ?? "")
32872
+ );
32873
+ break;
32810
32874
  }
32811
32875
  case "task-output-download": {
32812
- const rootPath = getTaskOutputRoot(deps.taskEngine, request.taskId ?? "");
32813
- try {
32814
- const absolutePath = resolveOutputPath(rootPath, request.path ?? "");
32815
- if (!fs12.existsSync(absolutePath) || !fs12.statSync(absolutePath).isFile()) {
32816
- throw new MeshyError("TASK_NOT_FOUND", `File not found: ${request.path}`, 404);
32817
- }
32818
- const { mimeType } = classifyFile(absolutePath);
32819
- const fileName = path13.basename(absolutePath).replace(/"/g, "");
32820
- response = binaryResponse(request.requestId, 200, fs12.readFileSync(absolutePath), {
32821
- "Content-Type": mimeType,
32822
- "Content-Disposition": `inline; filename="${fileName}"`,
32823
- "Cache-Control": "no-cache"
32824
- });
32825
- break;
32826
- } catch (err) {
32827
- if (err instanceof MeshyError) throw err;
32828
- if (err instanceof Error && err.message === "Path traversal detected") {
32829
- throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
32830
- }
32831
- throw err;
32832
- }
32876
+ const download = getLocalTaskOutputDownload(deps.taskEngine, request.taskId ?? "", request.path ?? "");
32877
+ response = binaryResponse(request.requestId, 200, download.content, download.headers);
32878
+ break;
32833
32879
  }
32834
32880
  case "task-output-diff": {
32835
- const rootPath = getTaskOutputRoot(deps.taskEngine, request.taskId ?? "");
32836
- response = jsonResponse(request.requestId, 200, getGitDiff(rootPath));
32881
+ response = jsonResponse(
32882
+ request.requestId,
32883
+ 200,
32884
+ getLocalTaskOutputDiff(deps.taskEngine, request.taskId ?? "")
32885
+ );
32837
32886
  break;
32838
32887
  }
32839
32888
  case "task-preview-session": {
@@ -33066,9 +33115,7 @@ function createNodeRoutes() {
33066
33115
  }
33067
33116
 
33068
33117
  // ../../packages/api/src/routes/tasks.ts
33069
- var fs14 = __toESM(require("fs"), 1);
33070
- var path14 = __toESM(require("path"), 1);
33071
- var import_express3 = __toESM(require_express2(), 1);
33118
+ var import_express4 = __toESM(require_express2(), 1);
33072
33119
 
33073
33120
  // ../../packages/api/src/task-route-utils.ts
33074
33121
  var fs13 = __toESM(require("fs"), 1);
@@ -33177,11 +33224,190 @@ function startLocalTaskFollowUp(deps, task, content, assignedTo, metadata) {
33177
33224
  }
33178
33225
  }
33179
33226
 
33227
+ // ../../packages/api/src/routes/task-output.ts
33228
+ var import_express3 = __toESM(require_express2(), 1);
33229
+ function asyncHandler3(fn) {
33230
+ return (req, res, next) => fn(req, res, next).catch(next);
33231
+ }
33232
+ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, init, fallbackRequest) {
33233
+ const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
33234
+ const log = rootLogger.child("tasks/output");
33235
+ const task = taskEngine.getTask(taskId);
33236
+ if (!task) {
33237
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
33238
+ }
33239
+ const selfId = nodeRegistry.getSelf()?.id;
33240
+ const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
33241
+ if (!needsProxy) {
33242
+ return false;
33243
+ }
33244
+ const assignedNodeId = task.assignedTo;
33245
+ if (!assignedNodeId) {
33246
+ return false;
33247
+ }
33248
+ const node = nodeRegistry.getNode(assignedNodeId);
33249
+ if (!node) {
33250
+ throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${assignedNodeId} not found`, 404);
33251
+ }
33252
+ if (!node.previewOrigin) {
33253
+ if (fallbackRequest && heartbeat?.requestWorkerControl) {
33254
+ log.warn("task output server origin missing, falling back to keepalive control", {
33255
+ taskId,
33256
+ assignedTo: assignedNodeId,
33257
+ kind: fallbackRequest.kind
33258
+ });
33259
+ const controlResponse = await heartbeat.requestWorkerControl(assignedNodeId, fallbackRequest);
33260
+ sendWorkerControlResponse(res, controlResponse);
33261
+ return true;
33262
+ }
33263
+ throw new MeshyError("NODE_OFFLINE", "Task output API is not available on the assigned worker", 502);
33264
+ }
33265
+ const qs = new URL(req.originalUrl ?? req.url, "http://localhost").search;
33266
+ const proxyPath = `/api/tasks/${taskId}/output${subPath}${qs}`;
33267
+ try {
33268
+ const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
33269
+ { endpoint: node.previewOrigin },
33270
+ proxyPath,
33271
+ init
33272
+ );
33273
+ log.debug("proxying task output request to worker output server", {
33274
+ taskId,
33275
+ assignedTo: assignedNodeId,
33276
+ proxyPath,
33277
+ outputOrigin: endpoint
33278
+ });
33279
+ await sendProxyResponse(res, proxyRes);
33280
+ return true;
33281
+ } catch (err) {
33282
+ if (fallbackRequest && heartbeat?.requestWorkerControl) {
33283
+ log.warn("output server proxy failed, falling back to keepalive control", {
33284
+ taskId,
33285
+ assignedTo: assignedNodeId,
33286
+ kind: fallbackRequest.kind,
33287
+ error: err instanceof Error ? err.message : String(err)
33288
+ });
33289
+ const controlResponse = await heartbeat.requestWorkerControl(assignedNodeId, fallbackRequest);
33290
+ sendWorkerControlResponse(res, controlResponse);
33291
+ return true;
33292
+ }
33293
+ log.warn("output server proxy error", {
33294
+ taskId,
33295
+ assignedTo: assignedNodeId,
33296
+ error: err instanceof Error ? err.message : String(err)
33297
+ });
33298
+ throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
33299
+ }
33300
+ }
33301
+ function createTaskOutputRoutes(options = {}) {
33302
+ const router = (0, import_express3.Router)();
33303
+ const allowRemoteProxy = options.allowRemoteProxy ?? true;
33304
+ router.get("/:id/output", asyncHandler3(async (req, res) => {
33305
+ const taskId = req.params.id;
33306
+ if (allowRemoteProxy) {
33307
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "", void 0, {
33308
+ kind: "task-output-summary",
33309
+ taskId
33310
+ });
33311
+ if (handled) {
33312
+ return;
33313
+ }
33314
+ }
33315
+ const { taskEngine } = req.app.locals.deps;
33316
+ res.json(getLocalTaskOutputSummary(taskEngine, taskId));
33317
+ }));
33318
+ router.get("/:id/output/tree", asyncHandler3(async (req, res) => {
33319
+ const taskId = req.params.id;
33320
+ const query = TaskOutputTreeQuery.parse(req.query);
33321
+ if (allowRemoteProxy) {
33322
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/tree", void 0, {
33323
+ kind: "task-output-tree",
33324
+ taskId,
33325
+ path: query.path
33326
+ });
33327
+ if (handled) {
33328
+ return;
33329
+ }
33330
+ }
33331
+ const { taskEngine } = req.app.locals.deps;
33332
+ res.json(getLocalTaskOutputTree(taskEngine, taskId, query.path));
33333
+ }));
33334
+ router.get("/:id/output/content", asyncHandler3(async (req, res) => {
33335
+ const taskId = req.params.id;
33336
+ const query = TaskOutputContentQuery.parse(req.query);
33337
+ if (allowRemoteProxy) {
33338
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/content", void 0, {
33339
+ kind: "task-output-content",
33340
+ taskId,
33341
+ path: query.path
33342
+ });
33343
+ if (handled) {
33344
+ return;
33345
+ }
33346
+ }
33347
+ const { taskEngine } = req.app.locals.deps;
33348
+ res.json(getLocalTaskOutputContent(taskEngine, taskId, query.path));
33349
+ }));
33350
+ router.get("/:id/output/download", asyncHandler3(async (req, res) => {
33351
+ const taskId = req.params.id;
33352
+ const query = TaskOutputDownloadQuery.parse(req.query);
33353
+ if (allowRemoteProxy) {
33354
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/download", void 0, {
33355
+ kind: "task-output-download",
33356
+ taskId,
33357
+ path: query.path
33358
+ });
33359
+ if (handled) {
33360
+ return;
33361
+ }
33362
+ }
33363
+ const { taskEngine } = req.app.locals.deps;
33364
+ const download = getLocalTaskOutputDownload(taskEngine, taskId, query.path);
33365
+ for (const [key, value] of Object.entries(download.headers)) {
33366
+ res.setHeader(key, value);
33367
+ }
33368
+ res.send(download.content);
33369
+ }));
33370
+ router.get("/:id/output/diff", asyncHandler3(async (req, res) => {
33371
+ const taskId = req.params.id;
33372
+ if (allowRemoteProxy) {
33373
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/diff", void 0, {
33374
+ kind: "task-output-diff",
33375
+ taskId
33376
+ });
33377
+ if (handled) {
33378
+ return;
33379
+ }
33380
+ }
33381
+ const { taskEngine } = req.app.locals.deps;
33382
+ res.json(getLocalTaskOutputDiff(taskEngine, taskId));
33383
+ }));
33384
+ router.post("/:id/output/preview-sessions", asyncHandler3(async (req, res) => {
33385
+ const taskId = req.params.id;
33386
+ const body = TaskPreviewSessionBody.parse(req.body ?? {});
33387
+ if (allowRemoteProxy) {
33388
+ const handled = await maybeHandleRemoteTaskOutputRequest(req, res, taskId, "/preview-sessions", {
33389
+ method: "POST",
33390
+ headers: { "Content-Type": "application/json" },
33391
+ body: JSON.stringify(body)
33392
+ }, {
33393
+ kind: "task-preview-session",
33394
+ taskId,
33395
+ path: body.path
33396
+ });
33397
+ if (handled) {
33398
+ return;
33399
+ }
33400
+ }
33401
+ res.json(await createPreviewSessionPayload(req.app.locals.deps, taskId, body.path));
33402
+ }));
33403
+ return router;
33404
+ }
33405
+
33180
33406
  // ../../packages/api/src/routes/tasks.ts
33181
33407
  var TERMINAL_STATUSES3 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
33182
33408
  var ARCHIVABLE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
33183
33409
  var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned", "running"]);
33184
- function asyncHandler3(fn) {
33410
+ function asyncHandler4(fn) {
33185
33411
  return (req, res, next) => fn(req, res, next).catch(next);
33186
33412
  }
33187
33413
  function withAssignedNodeMetadata(task, nodeRegistry) {
@@ -33196,8 +33422,8 @@ function withAssignedNodeMetadata(task, nodeRegistry) {
33196
33422
  };
33197
33423
  }
33198
33424
  function createTaskRoutes() {
33199
- const router = (0, import_express3.Router)();
33200
- router.post("/", asyncHandler3(async (req, res) => {
33425
+ const router = (0, import_express4.Router)();
33426
+ router.post("/", asyncHandler4(async (req, res) => {
33201
33427
  const { taskEngine, nodeRegistry } = req.app.locals.deps;
33202
33428
  const body = CreateTaskBody.parse(req.body);
33203
33429
  const task = taskEngine.createTask({
@@ -33216,7 +33442,7 @@ function createTaskRoutes() {
33216
33442
  }
33217
33443
  res.status(201).json(withAssignedNodeMetadata(task, nodeRegistry));
33218
33444
  }));
33219
- router.get("/", asyncHandler3(async (req, res) => {
33445
+ router.get("/", asyncHandler4(async (req, res) => {
33220
33446
  const { taskEngine, nodeRegistry } = req.app.locals.deps;
33221
33447
  const query = TaskListQuery.parse(req.query);
33222
33448
  const filter = {};
@@ -33231,7 +33457,7 @@ function createTaskRoutes() {
33231
33457
  total: result.total
33232
33458
  });
33233
33459
  }));
33234
- router.post("/batch/delete", asyncHandler3(async (req, res) => {
33460
+ router.post("/batch/delete", asyncHandler4(async (req, res) => {
33235
33461
  const { taskEngine } = req.app.locals.deps;
33236
33462
  const { ids } = BatchTaskIdsBody.parse(req.body);
33237
33463
  const results = ids.map((id) => {
@@ -33244,7 +33470,7 @@ function createTaskRoutes() {
33244
33470
  });
33245
33471
  res.json({ results });
33246
33472
  }));
33247
- router.post("/batch/archive", asyncHandler3(async (req, res) => {
33473
+ router.post("/batch/archive", asyncHandler4(async (req, res) => {
33248
33474
  const { taskEngine } = req.app.locals.deps;
33249
33475
  const { ids } = BatchTaskIdsBody.parse(req.body);
33250
33476
  const results = ids.map((id) => {
@@ -33262,7 +33488,7 @@ function createTaskRoutes() {
33262
33488
  });
33263
33489
  res.json({ results });
33264
33490
  }));
33265
- router.get("/:id", asyncHandler3(async (req, res) => {
33491
+ router.get("/:id", asyncHandler4(async (req, res) => {
33266
33492
  const { taskEngine, nodeRegistry } = req.app.locals.deps;
33267
33493
  const task = taskEngine.getTask(req.params.id);
33268
33494
  if (!task) {
@@ -33270,7 +33496,7 @@ function createTaskRoutes() {
33270
33496
  }
33271
33497
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
33272
33498
  }));
33273
- router.patch("/:id", asyncHandler3(async (req, res) => {
33499
+ router.patch("/:id", asyncHandler4(async (req, res) => {
33274
33500
  const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
33275
33501
  const log = rootLogger.child("tasks/patch");
33276
33502
  const updates = UpdateTaskBody.parse(req.body);
@@ -33309,7 +33535,7 @@ function createTaskRoutes() {
33309
33535
  }
33310
33536
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
33311
33537
  }));
33312
- router.delete("/:id", asyncHandler3(async (req, res) => {
33538
+ router.delete("/:id", asyncHandler4(async (req, res) => {
33313
33539
  const { taskEngine } = req.app.locals.deps;
33314
33540
  const result = taskEngine.deleteTask(req.params.id);
33315
33541
  if (!result) {
@@ -33317,7 +33543,7 @@ function createTaskRoutes() {
33317
33543
  }
33318
33544
  res.json({ ok: true });
33319
33545
  }));
33320
- router.post("/:id/cancel", asyncHandler3(async (req, res) => {
33546
+ router.post("/:id/cancel", asyncHandler4(async (req, res) => {
33321
33547
  const { taskEngine, nodeRegistry, engineRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
33322
33548
  const log = rootLogger.child("tasks/cancel");
33323
33549
  const task = taskEngine.getTask(req.params.id);
@@ -33354,18 +33580,18 @@ function createTaskRoutes() {
33354
33580
  }, task.id);
33355
33581
  res.json({ ok: true });
33356
33582
  }));
33357
- router.post("/:id/assign", asyncHandler3(async (req, res) => {
33583
+ router.post("/:id/assign", asyncHandler4(async (req, res) => {
33358
33584
  const { taskEngine, nodeRegistry } = req.app.locals.deps;
33359
33585
  const body = AssignTaskBody.parse(req.body);
33360
33586
  const task = taskEngine.assignTask(req.params.id, body.nodeId);
33361
33587
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
33362
33588
  }));
33363
- router.post("/:id/retry", asyncHandler3(async (req, res) => {
33589
+ router.post("/:id/retry", asyncHandler4(async (req, res) => {
33364
33590
  const { taskEngine, nodeRegistry } = req.app.locals.deps;
33365
33591
  const task = taskEngine.retryTask(req.params.id);
33366
33592
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
33367
33593
  }));
33368
- router.get("/:id/logs", asyncHandler3(async (req, res) => {
33594
+ router.get("/:id/logs", asyncHandler4(async (req, res) => {
33369
33595
  const { engineRegistry, taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
33370
33596
  const log = rootLogger.child("tasks/logs");
33371
33597
  const query = TaskLogsQuery.parse(req.query);
@@ -33432,7 +33658,7 @@ function createTaskRoutes() {
33432
33658
  });
33433
33659
  res.json(local);
33434
33660
  }));
33435
- router.post("/:id/message", asyncHandler3(async (req, res) => {
33661
+ router.post("/:id/message", asyncHandler4(async (req, res) => {
33436
33662
  const { taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
33437
33663
  const log = rootLogger.child("tasks/message");
33438
33664
  const body = SendMessageBody.parse(req.body);
@@ -33516,281 +33742,24 @@ function createTaskRoutes() {
33516
33742
  }, task, body.content, task.assignedTo);
33517
33743
  res.json({ ok: true });
33518
33744
  }));
33519
- async function resolveTaskOutputOrProxy(req, res, taskId, subPath, init, fallbackRequest) {
33520
- const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
33521
- const log = rootLogger.child("tasks/output");
33522
- const task = taskEngine.getTask(taskId);
33523
- if (!task) {
33524
- throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
33525
- }
33526
- const effectivePath = task.effectiveProjectPath;
33527
- if (!effectivePath) {
33528
- throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
33529
- }
33530
- const selfId = nodeRegistry.getSelf()?.id;
33531
- const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
33532
- if (needsProxy) {
33533
- const node = nodeRegistry.getNode(task.assignedTo);
33534
- if (!node) {
33535
- throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${task.assignedTo} not found`, 404);
33536
- }
33537
- const canPushToNode = heartbeat?.canPushToNode?.(task.assignedTo) ?? true;
33538
- if (!canPushToNode && fallbackRequest && heartbeat?.requestWorkerControl) {
33539
- log.debug("skipping direct output proxy because worker is keepalive-only", {
33540
- taskId,
33541
- assignedTo: task.assignedTo,
33542
- kind: fallbackRequest.kind
33543
- });
33544
- const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, fallbackRequest);
33545
- sendWorkerControlResponse(res, controlResponse);
33546
- return null;
33547
- }
33548
- const qs = new URL(req.url, "http://localhost").search;
33549
- const proxyPath = `/api/tasks/${taskId}/output${subPath}${qs}`;
33550
- try {
33551
- const { endpoint, response: proxyRes } = await fetchNodeWithFallback(node, proxyPath, init);
33552
- const proxyUrl = `${endpoint}${proxyPath}`;
33553
- log.debug("proxying output request to worker", { taskId, proxyUrl });
33554
- await sendProxyResponse(res, proxyRes);
33555
- return null;
33556
- } catch (err) {
33557
- if (fallbackRequest && heartbeat?.requestWorkerControl) {
33558
- log.warn("direct output proxy failed, falling back to keepalive control", {
33559
- taskId,
33560
- assignedTo: task.assignedTo,
33561
- kind: fallbackRequest.kind,
33562
- error: err instanceof Error ? err.message : String(err)
33563
- });
33564
- try {
33565
- const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, fallbackRequest);
33566
- sendWorkerControlResponse(res, controlResponse);
33567
- return null;
33568
- } catch (fallbackErr) {
33569
- log.warn("keepalive output fallback failed", {
33570
- taskId,
33571
- assignedTo: task.assignedTo,
33572
- kind: fallbackRequest.kind,
33573
- error: fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
33574
- });
33575
- }
33576
- }
33577
- log.warn("output proxy error", { error: err instanceof Error ? err.message : String(err) });
33578
- throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
33579
- }
33580
- }
33581
- return effectivePath;
33582
- }
33583
- router.get("/:id/output", asyncHandler3(async (req, res) => {
33584
- const { taskEngine } = req.app.locals.deps;
33585
- const taskId = req.params.id;
33586
- const task = taskEngine.getTask(taskId);
33587
- if (!task) {
33588
- throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
33589
- }
33590
- const effectivePath = task.effectiveProjectPath;
33591
- if (!effectivePath) {
33592
- res.json({
33593
- taskId,
33594
- requestedProject: task.project,
33595
- effectiveProjectPath: null,
33596
- assignedTo: task.assignedTo,
33597
- available: false,
33598
- summary: null
33599
- });
33600
- return;
33601
- }
33602
- const root = await resolveTaskOutputOrProxy(req, res, taskId, "", void 0, {
33603
- kind: "task-output-summary",
33604
- taskId
33605
- });
33606
- if (root === null) return;
33607
- const summary = getOutputSummary(root);
33608
- res.json({
33609
- taskId,
33610
- requestedProject: task.project,
33611
- effectiveProjectPath: effectivePath,
33612
- assignedTo: task.assignedTo,
33613
- available: true,
33614
- summary
33615
- });
33616
- }));
33617
- router.get("/:id/output/tree", asyncHandler3(async (req, res) => {
33618
- const taskId = req.params.id;
33619
- const query = TaskOutputTreeQuery.parse(req.query);
33620
- const root = await resolveTaskOutputOrProxy(req, res, taskId, "/tree", void 0, {
33621
- kind: "task-output-tree",
33622
- taskId,
33623
- path: query.path
33624
- });
33625
- if (root === null) return;
33626
- try {
33627
- const entries = listDirectory(root, query.path);
33628
- res.json({
33629
- rootPath: root,
33630
- currentPath: query.path,
33631
- entries
33632
- });
33633
- } catch (err) {
33634
- if (err instanceof Error && err.message === "Path traversal detected") {
33635
- throw new MeshyError("VALIDATION_ERROR", "Invalid directory path", 400);
33636
- }
33637
- throw err;
33638
- }
33639
- }));
33640
- router.get("/:id/output/content", asyncHandler3(async (req, res) => {
33641
- const taskId = req.params.id;
33642
- const query = TaskOutputContentQuery.parse(req.query);
33643
- const root = await resolveTaskOutputOrProxy(req, res, taskId, "/content", void 0, {
33644
- kind: "task-output-content",
33645
- taskId,
33646
- path: query.path
33647
- });
33648
- if (root === null) return;
33649
- try {
33650
- const content = readFileContent(root, query.path);
33651
- res.json({
33652
- ...content,
33653
- downloadUrl: `/api/tasks/${taskId}/output/download?path=${encodeURIComponent(query.path)}`
33654
- });
33655
- } catch (err) {
33656
- if (err instanceof Error && err.message === "Path traversal detected") {
33657
- throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
33658
- }
33659
- if (err instanceof Error && err.message === "File not found") {
33660
- throw new MeshyError("TASK_NOT_FOUND", `File not found: ${query.path}`, 404);
33661
- }
33662
- throw err;
33663
- }
33664
- }));
33665
- router.get("/:id/output/download", asyncHandler3(async (req, res) => {
33666
- const taskId = req.params.id;
33667
- const query = TaskOutputDownloadQuery.parse(req.query);
33668
- const root = await resolveTaskOutputOrProxy(req, res, taskId, "/download", void 0, {
33669
- kind: "task-output-download",
33670
- taskId,
33671
- path: query.path
33672
- });
33673
- if (root === null) return;
33674
- try {
33675
- const absolutePath = resolveOutputPath(root, query.path);
33676
- if (!fs14.existsSync(absolutePath) || !fs14.statSync(absolutePath).isFile()) {
33677
- throw new MeshyError("TASK_NOT_FOUND", `File not found: ${query.path}`, 404);
33678
- }
33679
- const { mimeType } = classifyFile(absolutePath);
33680
- const fileName = path14.basename(absolutePath).replace(/"/g, "");
33681
- const content = fs14.readFileSync(absolutePath);
33682
- res.setHeader("Content-Type", mimeType);
33683
- res.setHeader("Content-Disposition", `inline; filename="${fileName}"`);
33684
- res.setHeader("Cache-Control", "no-cache");
33685
- res.send(content);
33686
- } catch (err) {
33687
- if (err instanceof MeshyError) throw err;
33688
- if (err instanceof Error && err.message === "Path traversal detected") {
33689
- throw new MeshyError("VALIDATION_ERROR", "Invalid file path", 400);
33690
- }
33691
- throw err;
33692
- }
33693
- }));
33694
- router.get("/:id/output/diff", asyncHandler3(async (req, res) => {
33695
- const taskId = req.params.id;
33696
- const root = await resolveTaskOutputOrProxy(req, res, taskId, "/diff", void 0, {
33697
- kind: "task-output-diff",
33698
- taskId
33699
- });
33700
- if (root === null) return;
33701
- const diff = getGitDiff(root);
33702
- res.json(diff);
33703
- }));
33704
- router.post("/:id/output/preview-sessions", asyncHandler3(async (req, res) => {
33705
- const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
33706
- const log = rootLogger.child("tasks/preview");
33707
- const taskId = req.params.id;
33708
- const body = TaskPreviewSessionBody.parse(req.body ?? {});
33709
- const task = taskEngine.getTask(taskId);
33710
- if (!task) {
33711
- throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
33712
- }
33713
- const effectivePath = task.effectiveProjectPath;
33714
- if (!effectivePath) {
33715
- throw new MeshyError("VALIDATION_ERROR", "Task output not available", 400);
33716
- }
33717
- const selfId = nodeRegistry.getSelf()?.id;
33718
- const needsProxy = !!(task.assignedTo && task.assignedTo !== selfId);
33719
- if (needsProxy) {
33720
- const node = nodeRegistry.getNode(task.assignedTo);
33721
- if (!node) {
33722
- throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${task.assignedTo} not found`, 404);
33723
- }
33724
- const canPushToNode = heartbeat?.canPushToNode?.(task.assignedTo) ?? true;
33725
- if (!canPushToNode && heartbeat?.requestWorkerControl) {
33726
- log.debug("skipping direct preview proxy because worker is keepalive-only", {
33727
- taskId,
33728
- assignedTo: task.assignedTo
33729
- });
33730
- const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, {
33731
- kind: "task-preview-session",
33732
- taskId,
33733
- path: body.path
33734
- });
33735
- sendWorkerControlResponse(res, controlResponse);
33736
- return;
33737
- }
33738
- try {
33739
- const { endpoint, response: proxyRes } = await fetchNodeWithFallback(node, "/api/worker/preview-session", {
33740
- method: "POST",
33741
- headers: { "Content-Type": "application/json" },
33742
- body: JSON.stringify({ taskId, path: body.path })
33743
- });
33744
- const workerEndpoint = endpoint;
33745
- log.debug("proxying preview session request to worker", { taskId, workerEndpoint });
33746
- await sendProxyResponse(res, proxyRes);
33747
- return;
33748
- } catch (err) {
33749
- if (heartbeat?.requestWorkerControl) {
33750
- log.warn("direct preview proxy failed, falling back to keepalive control", {
33751
- taskId,
33752
- assignedTo: task.assignedTo,
33753
- error: err instanceof Error ? err.message : String(err)
33754
- });
33755
- try {
33756
- const controlResponse = await heartbeat.requestWorkerControl(task.assignedTo, {
33757
- kind: "task-preview-session",
33758
- taskId,
33759
- path: body.path
33760
- });
33761
- sendWorkerControlResponse(res, controlResponse);
33762
- return;
33763
- } catch (fallbackErr) {
33764
- log.warn("keepalive preview fallback failed", {
33765
- taskId,
33766
- assignedTo: task.assignedTo,
33767
- error: fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)
33768
- });
33769
- }
33770
- }
33771
- log.warn("preview session proxy error", { error: err instanceof Error ? err.message : String(err) });
33772
- throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for preview session", 502);
33773
- }
33774
- }
33775
- res.json(await createPreviewSessionPayload(req.app.locals.deps, taskId, body.path));
33776
- }));
33745
+ router.use(createTaskOutputRoutes());
33777
33746
  return router;
33778
33747
  }
33779
33748
 
33780
33749
  // ../../packages/api/src/routes/worker.ts
33781
- var import_express4 = __toESM(require_express2(), 1);
33750
+ var import_express5 = __toESM(require_express2(), 1);
33782
33751
  var WorkerMessageBody = external_exports.object({
33783
33752
  taskId: external_exports.string().min(1)
33784
33753
  }).and(SendMessageBody);
33785
33754
  var WorkerTaskBody = external_exports.object({
33786
33755
  taskId: external_exports.string().min(1)
33787
33756
  });
33788
- function asyncHandler4(fn) {
33757
+ function asyncHandler5(fn) {
33789
33758
  return (req, res, next) => fn(req, res, next).catch(next);
33790
33759
  }
33791
33760
  function createWorkerRoutes() {
33792
- const router = (0, import_express4.Router)();
33793
- router.post("/execute", asyncHandler4(async (req, res) => {
33761
+ const router = (0, import_express5.Router)();
33762
+ router.post("/execute", asyncHandler5(async (req, res) => {
33794
33763
  const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: rootLogger, workDir } = req.app.locals.deps;
33795
33764
  const log = rootLogger.child("worker/execute");
33796
33765
  const task = req.body;
@@ -33863,7 +33832,7 @@ function createWorkerRoutes() {
33863
33832
  }
33864
33833
  }
33865
33834
  }));
33866
- router.post("/message", asyncHandler4(async (req, res) => {
33835
+ router.post("/message", asyncHandler5(async (req, res) => {
33867
33836
  const { engineRegistry, taskEngine, nodeRegistry, eventBus, logger: rootLogger } = req.app.locals.deps;
33868
33837
  const log = rootLogger.child("worker/message");
33869
33838
  const body = WorkerMessageBody.parse(req.body);
@@ -33906,7 +33875,7 @@ function createWorkerRoutes() {
33906
33875
  }
33907
33876
  res.json({ ok: true });
33908
33877
  }));
33909
- router.post("/cancel", asyncHandler4(async (req, res) => {
33878
+ router.post("/cancel", asyncHandler5(async (req, res) => {
33910
33879
  const { taskEngine, engineRegistry, logger: rootLogger } = req.app.locals.deps;
33911
33880
  const log = rootLogger.child("worker/cancel");
33912
33881
  const body = WorkerTaskBody.parse(req.body);
@@ -33926,7 +33895,7 @@ function createWorkerRoutes() {
33926
33895
  terminal: result.terminal
33927
33896
  });
33928
33897
  }));
33929
- router.post("/output", asyncHandler4(async (req, res) => {
33898
+ router.post("/output", asyncHandler5(async (req, res) => {
33930
33899
  const { eventBus, engineRegistry, taskEngine, logger: rootLogger } = req.app.locals.deps;
33931
33900
  const log = rootLogger.child("worker/output");
33932
33901
  const { taskId, event } = req.body;
@@ -33941,7 +33910,7 @@ function createWorkerRoutes() {
33941
33910
  }
33942
33911
  res.json({ ok: true });
33943
33912
  }));
33944
- router.post("/heartbeat", asyncHandler4(async (req, res) => {
33913
+ router.post("/heartbeat", asyncHandler5(async (req, res) => {
33945
33914
  const { heartbeat, logger: rootLogger } = req.app.locals.deps;
33946
33915
  const log = rootLogger.child("worker/heartbeat");
33947
33916
  const body = req.body;
@@ -33958,7 +33927,7 @@ function createWorkerRoutes() {
33958
33927
  });
33959
33928
  res.json(response);
33960
33929
  }));
33961
- router.post("/keepalive", asyncHandler4(async (req, res) => {
33930
+ router.post("/keepalive", asyncHandler5(async (req, res) => {
33962
33931
  const { heartbeat, logger: rootLogger } = req.app.locals.deps;
33963
33932
  const log = rootLogger.child("worker/keepalive");
33964
33933
  const body = req.body;
@@ -33978,17 +33947,17 @@ function createWorkerRoutes() {
33978
33947
  });
33979
33948
  res.json(response);
33980
33949
  }));
33981
- router.post("/vote", asyncHandler4(async (req, res) => {
33950
+ router.post("/vote", asyncHandler5(async (req, res) => {
33982
33951
  const { election } = req.app.locals.deps;
33983
33952
  const response = election.handleVoteRequest(req.body);
33984
33953
  res.json(response);
33985
33954
  }));
33986
- router.post("/announce", asyncHandler4(async (req, res) => {
33955
+ router.post("/announce", asyncHandler5(async (req, res) => {
33987
33956
  const { election } = req.app.locals.deps;
33988
33957
  election.handleLeaderAnnounce(req.body);
33989
33958
  res.json({ ok: true });
33990
33959
  }));
33991
- router.post("/preview-session", asyncHandler4(async (req, res) => {
33960
+ router.post("/preview-session", asyncHandler5(async (req, res) => {
33992
33961
  const { logger: rootLogger } = req.app.locals.deps;
33993
33962
  const log = rootLogger.child("worker/preview-session");
33994
33963
  const body = TaskPreviewSessionBody.extend({
@@ -33998,7 +33967,7 @@ function createWorkerRoutes() {
33998
33967
  log.info("created preview session", { taskId: body.taskId, entryPath: payload.entryPath });
33999
33968
  res.json(payload);
34000
33969
  }));
34001
- router.post("/control-response", asyncHandler4(async (req, res) => {
33970
+ router.post("/control-response", asyncHandler5(async (req, res) => {
34002
33971
  const { heartbeat, logger: rootLogger } = req.app.locals.deps;
34003
33972
  const log = rootLogger.child("worker/control-response");
34004
33973
  const body = req.body;
@@ -34018,13 +33987,13 @@ function createWorkerRoutes() {
34018
33987
  }
34019
33988
 
34020
33989
  // ../../packages/api/src/routes/system.ts
34021
- var import_express5 = __toESM(require_express2(), 1);
34022
- function asyncHandler5(fn) {
33990
+ var import_express6 = __toESM(require_express2(), 1);
33991
+ function asyncHandler6(fn) {
34023
33992
  return (req, res, next) => fn(req, res, next).catch(next);
34024
33993
  }
34025
33994
  function createSystemRoutes() {
34026
- const router = (0, import_express5.Router)();
34027
- router.get("/health", asyncHandler5(async (req, res) => {
33995
+ const router = (0, import_express6.Router)();
33996
+ router.get("/health", asyncHandler6(async (req, res) => {
34028
33997
  const { logger: rootLogger } = req.app.locals.deps;
34029
33998
  rootLogger.child("system/health").info("received system health API call", {
34030
33999
  method: req.method,
@@ -34033,7 +34002,7 @@ function createSystemRoutes() {
34033
34002
  });
34034
34003
  res.json({ status: "ok", timestamp: Date.now() });
34035
34004
  }));
34036
- router.get("/info", asyncHandler5(async (req, res) => {
34005
+ router.get("/info", asyncHandler6(async (req, res) => {
34037
34006
  const { nodeRegistry, getTransportType, config, dashboardOrigin } = req.app.locals.deps;
34038
34007
  const self = nodeRegistry.getSelf();
34039
34008
  res.json({
@@ -34049,7 +34018,7 @@ function createSystemRoutes() {
34049
34018
  }
34050
34019
  });
34051
34020
  }));
34052
- router.post("/transport", asyncHandler5(async (req, res) => {
34021
+ router.post("/transport", asyncHandler6(async (req, res) => {
34053
34022
  const { switchTransport } = req.app.locals.deps;
34054
34023
  if (!switchTransport) {
34055
34024
  res.status(501).json({ error: "Transport switching not available" });
@@ -34063,7 +34032,7 @@ function createSystemRoutes() {
34063
34032
  const newEndpoint = await switchTransport(type);
34064
34033
  res.json({ ok: true, transportType: type, endpoint: newEndpoint });
34065
34034
  }));
34066
- router.post("/devtunnel", asyncHandler5(async (req, res) => {
34035
+ router.post("/devtunnel", asyncHandler6(async (req, res) => {
34067
34036
  const { enableDevTunnel, disableDevTunnel, nodeRegistry, taskEngine } = req.app.locals.deps;
34068
34037
  if (!enableDevTunnel || !disableDevTunnel) {
34069
34038
  res.status(501).json({ error: "DevTunnel control not available" });
@@ -34092,7 +34061,7 @@ function createSystemRoutes() {
34092
34061
  });
34093
34062
  }
34094
34063
  }));
34095
- router.get("/metrics", asyncHandler5(async (req, res) => {
34064
+ router.get("/metrics", asyncHandler6(async (req, res) => {
34096
34065
  const { taskEngine } = req.app.locals.deps;
34097
34066
  const metrics = taskEngine.getMetrics();
34098
34067
  res.json(metrics);
@@ -34101,7 +34070,7 @@ function createSystemRoutes() {
34101
34070
  }
34102
34071
 
34103
34072
  // ../../packages/api/src/routes/events.ts
34104
- var import_express6 = __toESM(require_express2(), 1);
34073
+ var import_express7 = __toESM(require_express2(), 1);
34105
34074
  var HEARTBEAT_INTERVAL_MS = 15e3;
34106
34075
  var CATEGORY_MAP = {
34107
34076
  tasks: "task.",
@@ -34136,7 +34105,7 @@ function shouldIncludeEvent(eventName, categories) {
34136
34105
  });
34137
34106
  }
34138
34107
  function createEventRoutes() {
34139
- const router = (0, import_express6.Router)();
34108
+ const router = (0, import_express7.Router)();
34140
34109
  router.get("/", (req, res) => {
34141
34110
  const { eventBus } = req.app.locals.deps;
34142
34111
  const categories = parseFilter(req.query.filter);
@@ -34187,8 +34156,8 @@ var JSON_BODY_LIMIT_LARGE = "25mb";
34187
34156
  function resolveRuntimeBaseDir() {
34188
34157
  const entryPath = process.argv[1];
34189
34158
  if (typeof entryPath === "string" && entryPath.length > 0) {
34190
- const resolved = fs15.realpathSync(path15.resolve(entryPath));
34191
- return path15.dirname(resolved);
34159
+ const resolved = fs14.realpathSync(path14.resolve(entryPath));
34160
+ return path14.dirname(resolved);
34192
34161
  }
34193
34162
  return process.cwd();
34194
34163
  }
@@ -34196,25 +34165,25 @@ function resolveStaticDir(baseDir) {
34196
34165
  const envStaticDir = process.env.MESHY_STATIC_DIR;
34197
34166
  const candidateDirs = [
34198
34167
  envStaticDir,
34199
- path15.resolve(baseDir, "dashboard"),
34200
- path15.resolve(baseDir, "../dashboard"),
34201
- path15.resolve(baseDir, "../../dashboard/dist"),
34202
- path15.resolve(baseDir, "../../../packages/dashboard/dist"),
34203
- path15.resolve(baseDir, "../public"),
34204
- path15.resolve(baseDir, "../../packages/api/public"),
34205
- path15.resolve(baseDir, "../../../packages/api/public"),
34206
- path15.resolve(process.cwd(), "packages/dashboard/dist"),
34207
- path15.resolve(process.cwd(), "packages/api/public")
34168
+ path14.resolve(baseDir, "dashboard"),
34169
+ path14.resolve(baseDir, "../dashboard"),
34170
+ path14.resolve(baseDir, "../../dashboard/dist"),
34171
+ path14.resolve(baseDir, "../../../packages/dashboard/dist"),
34172
+ path14.resolve(baseDir, "../public"),
34173
+ path14.resolve(baseDir, "../../packages/api/public"),
34174
+ path14.resolve(baseDir, "../../../packages/api/public"),
34175
+ path14.resolve(process.cwd(), "packages/dashboard/dist"),
34176
+ path14.resolve(process.cwd(), "packages/api/public")
34208
34177
  ].filter((value) => typeof value === "string" && value.length > 0);
34209
34178
  for (const candidate of candidateDirs) {
34210
- if (fs15.existsSync(candidate)) {
34179
+ if (fs14.existsSync(candidate)) {
34211
34180
  return candidate;
34212
34181
  }
34213
34182
  }
34214
34183
  return null;
34215
34184
  }
34216
34185
  function createServer2(deps) {
34217
- const app = (0, import_express7.default)();
34186
+ const app = (0, import_express8.default)();
34218
34187
  app.locals.deps = deps;
34219
34188
  if (typeof deps.heartbeat.setControlRequestHandler === "function") {
34220
34189
  deps.heartbeat.setControlRequestHandler((request) => executeWorkerControlRequest(deps, request));
@@ -34238,7 +34207,7 @@ function createServer2(deps) {
34238
34207
  const runtimeBaseDir = resolveRuntimeBaseDir();
34239
34208
  const staticDir = resolveStaticDir(runtimeBaseDir);
34240
34209
  if (staticDir) {
34241
- const staticMiddleware = import_express7.default.static(staticDir);
34210
+ const staticMiddleware = import_express8.default.static(staticDir);
34242
34211
  app.use((req, res, next) => {
34243
34212
  if (isApiRequest(req)) {
34244
34213
  next();
@@ -34251,10 +34220,10 @@ function createServer2(deps) {
34251
34220
  staticMiddleware(req, res, next);
34252
34221
  });
34253
34222
  }
34254
- app.use(import_express7.default.json({ limit: JSON_BODY_LIMIT }));
34223
+ app.use(import_express8.default.json({ limit: JSON_BODY_LIMIT }));
34255
34224
  app.use(createAuthMiddleware(authConfig));
34256
34225
  app.use(createRoutingMiddleware(deps.dataRouter));
34257
- const largeBodyParser = import_express7.default.json({ limit: JSON_BODY_LIMIT_LARGE });
34226
+ const largeBodyParser = import_express8.default.json({ limit: JSON_BODY_LIMIT_LARGE });
34258
34227
  app.use("/api/cluster", createClusterRoutes());
34259
34228
  app.use("/api/nodes", createNodeRoutes());
34260
34229
  app.use("/api/tasks", largeBodyParser, createTaskRoutes());
@@ -34262,8 +34231,8 @@ function createServer2(deps) {
34262
34231
  app.use("/api/system", createSystemRoutes());
34263
34232
  app.use("/api/events", createEventRoutes());
34264
34233
  if (staticDir) {
34265
- const indexPath = path15.join(staticDir, "index.html");
34266
- if (fs15.existsSync(indexPath)) {
34234
+ const indexPath = path14.join(staticDir, "index.html");
34235
+ if (fs14.existsSync(indexPath)) {
34267
34236
  app.get("*", (req, res, next) => {
34268
34237
  if (isApiRequest(req)) {
34269
34238
  next();
@@ -34281,6 +34250,34 @@ function createServer2(deps) {
34281
34250
  return app;
34282
34251
  }
34283
34252
 
34253
+ // ../../packages/api/src/output-server.ts
34254
+ var import_express9 = __toESM(require_express2(), 1);
34255
+ var JSON_BODY_LIMIT_LARGE2 = "25mb";
34256
+ function createOutputServer(deps) {
34257
+ if (!deps.previewSessionManager) {
34258
+ throw new Error("Preview session manager is required for the output server");
34259
+ }
34260
+ const app = (0, import_express9.default)();
34261
+ app.locals.deps = deps;
34262
+ app.use((req, res, next) => {
34263
+ if (handlePreviewRequest(deps.previewSessionManager, req, res)) {
34264
+ return;
34265
+ }
34266
+ next();
34267
+ });
34268
+ const authConfig = {
34269
+ apiKey: deps.config.apiKey,
34270
+ validateBearerToken: deps.config.validateBearerToken,
34271
+ allowTrustedHostBypass: false
34272
+ };
34273
+ const largeBodyParser = import_express9.default.json({ limit: JSON_BODY_LIMIT_LARGE2 });
34274
+ app.use("/api/tasks", largeBodyParser, createAuthMiddleware(authConfig), createTaskOutputRoutes({
34275
+ allowRemoteProxy: false
34276
+ }));
34277
+ app.use(createErrorMiddleware());
34278
+ return app;
34279
+ }
34280
+
34284
34281
  // ../../packages/transport/src/direct.ts
34285
34282
  var import_node_os = require("os");
34286
34283
  var import_node_http = require("http");
@@ -34591,8 +34588,8 @@ function createTransport(config) {
34591
34588
  }
34592
34589
 
34593
34590
  // src/startup.ts
34594
- var fs16 = __toESM(require("fs"), 1);
34595
- var path16 = __toESM(require("path"), 1);
34591
+ var fs15 = __toESM(require("fs"), 1);
34592
+ var path15 = __toESM(require("path"), 1);
34596
34593
  var readline = __toESM(require("readline/promises"), 1);
34597
34594
  var import_node_child_process6 = require("child_process");
34598
34595
  function getDefaultNodeName() {
@@ -34656,19 +34653,19 @@ function createDefaultCommandRunner(platform) {
34656
34653
  };
34657
34654
  }
34658
34655
  function getNodeMetadataPath2(storagePath) {
34659
- return path16.join(storagePath, "metadata.json");
34656
+ return path15.join(storagePath, "metadata.json");
34660
34657
  }
34661
34658
  function readStartupMetadataFile(storagePath) {
34662
34659
  try {
34663
- const raw = JSON.parse(fs16.readFileSync(getNodeMetadataPath2(storagePath), "utf-8"));
34660
+ const raw = JSON.parse(fs15.readFileSync(getNodeMetadataPath2(storagePath), "utf-8"));
34664
34661
  return typeof raw === "object" && raw !== null ? raw : {};
34665
34662
  } catch {
34666
34663
  return {};
34667
34664
  }
34668
34665
  }
34669
34666
  function writeStartupMetadataFile(storagePath, metadata) {
34670
- fs16.mkdirSync(storagePath, { recursive: true });
34671
- fs16.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
34667
+ fs15.mkdirSync(storagePath, { recursive: true });
34668
+ fs15.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
34672
34669
  }
34673
34670
  function formatLocalDate(now) {
34674
34671
  const year = now.getFullYear();
@@ -34913,9 +34910,9 @@ function parseArgs(argv) {
34913
34910
  }
34914
34911
  return result;
34915
34912
  }
34916
- function loadConfigFile(path17) {
34913
+ function loadConfigFile(path16) {
34917
34914
  try {
34918
- const raw = fs16.readFileSync(path17, "utf-8");
34915
+ const raw = fs15.readFileSync(path16, "utf-8");
34919
34916
  return JSON.parse(raw);
34920
34917
  } catch {
34921
34918
  return {};
@@ -35164,14 +35161,35 @@ async function main() {
35164
35161
  });
35165
35162
  await meshyNode.start();
35166
35163
  const previewSessionManager = new PreviewSessionManager();
35167
- const previewServer = new PreviewServer(previewSessionManager);
35168
35164
  const previewPort = config.node.port + 1;
35169
- const actualPreviewPort = await previewServer.start(previewPort);
35165
+ let actualPreviewPort = previewPort;
35170
35166
  let dashboardTransport = null;
35171
35167
  let dashboardOrigin;
35172
35168
  let previewTransport = null;
35173
35169
  let previewOrigin;
35170
+ let outputServer = null;
35174
35171
  let deps;
35172
+ async function listen(app2, port) {
35173
+ return new Promise((resolve10, reject) => {
35174
+ const server2 = http2.createServer(app2);
35175
+ server2.listen(port, () => resolve10(server2));
35176
+ server2.on("error", reject);
35177
+ });
35178
+ }
35179
+ async function closeServer(server2) {
35180
+ if (!server2) {
35181
+ return;
35182
+ }
35183
+ await new Promise((resolve10, reject) => {
35184
+ server2.close((err) => {
35185
+ if (err) {
35186
+ reject(err);
35187
+ return;
35188
+ }
35189
+ resolve10();
35190
+ });
35191
+ });
35192
+ }
35175
35193
  function createDashboardTransportConfig() {
35176
35194
  return {
35177
35195
  type: "devtunnel",
@@ -35294,6 +35312,10 @@ async function main() {
35294
35312
  const nextOrigin = await nextTransport.getEndpoint();
35295
35313
  previewTransport = nextTransport;
35296
35314
  setAdvertisedPreviewOrigin(nextOrigin);
35315
+ meshyNode.getLogger().info("started output preview tunnel", {
35316
+ previewOrigin: nextOrigin,
35317
+ previewPort: actualPreviewPort
35318
+ });
35297
35319
  if (previousTransport) {
35298
35320
  await previousTransport.stop().catch(() => void 0);
35299
35321
  }
@@ -35372,6 +35394,11 @@ async function main() {
35372
35394
  deps.previewPort = actualPreviewPort;
35373
35395
  deps.dashboardOrigin = dashboardOrigin;
35374
35396
  deps.previewOrigin = previewOrigin;
35397
+ const outputApp = createOutputServer(deps);
35398
+ outputServer = await listen(outputApp, previewPort);
35399
+ const outputAddress = outputServer.address();
35400
+ actualPreviewPort = typeof outputAddress === "object" && outputAddress ? outputAddress.port : previewPort;
35401
+ deps.previewPort = actualPreviewPort;
35375
35402
  meshyNode.getLogger().info("configured node auth mode", {
35376
35403
  authEnabled: authMetadata.enabled,
35377
35404
  allowSameTenant: authMetadata.allowSameTenant,
@@ -35379,6 +35406,7 @@ async function main() {
35379
35406
  mainTransportType: meshyNode.getTransportType(),
35380
35407
  sidecarEnabled: meshyNode.isDevTunnelEnabled()
35381
35408
  });
35409
+ await restartPreviewTransport(createPreviewTransportConfig());
35382
35410
  await syncDashboardTransport("startup");
35383
35411
  const previewHealthTimer = setInterval(() => {
35384
35412
  void (async () => {
@@ -35391,6 +35419,7 @@ async function main() {
35391
35419
  meshyNode.getLogger().warn("preview transport became unhealthy and was cleared", {
35392
35420
  previewPort: actualPreviewPort
35393
35421
  });
35422
+ await restartPreviewTransport(createPreviewTransportConfig());
35394
35423
  })();
35395
35424
  }, config.cluster.heartbeatInterval);
35396
35425
  const dashboardHealthTimer = setInterval(() => {
@@ -35437,9 +35466,9 @@ async function main() {
35437
35466
  if (previewTransport) {
35438
35467
  await previewTransport.stop();
35439
35468
  }
35440
- await previewServer.stop();
35469
+ await closeServer(outputServer);
35441
35470
  await meshyNode.stop();
35442
- server.close();
35471
+ await closeServer(server);
35443
35472
  console.log("Goodbye!");
35444
35473
  process.exit(0);
35445
35474
  } catch (err) {