meshy-node 0.3.1 → 0.3.3

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
@@ -4301,7 +4301,7 @@ var require_has_flag = __commonJS({
4301
4301
  var require_supports_color = __commonJS({
4302
4302
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports2, module2) {
4303
4303
  "use strict";
4304
- var os6 = require("os");
4304
+ var os7 = require("os");
4305
4305
  var tty = require("tty");
4306
4306
  var hasFlag2 = require_has_flag();
4307
4307
  var { env } = process;
@@ -4349,7 +4349,7 @@ var require_supports_color = __commonJS({
4349
4349
  return min;
4350
4350
  }
4351
4351
  if (process.platform === "win32") {
4352
- const osRelease = os6.release().split(".");
4352
+ const osRelease = os7.release().split(".");
4353
4353
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
4354
4354
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
4355
4355
  }
@@ -6629,8 +6629,8 @@ var require_node2 = __commonJS({
6629
6629
  }
6630
6630
  break;
6631
6631
  case "FILE":
6632
- var fs20 = require("fs");
6633
- stream2 = new fs20.SyncWriteStream(fd2, { autoClose: false });
6632
+ var fs21 = require("fs");
6633
+ stream2 = new fs21.SyncWriteStream(fd2, { autoClose: false });
6634
6634
  stream2._type = "fs";
6635
6635
  break;
6636
6636
  case "PIPE":
@@ -19420,11 +19420,11 @@ var require_mime_types = __commonJS({
19420
19420
  }
19421
19421
  return exts[0];
19422
19422
  }
19423
- function lookup(path21) {
19424
- if (!path21 || typeof path21 !== "string") {
19423
+ function lookup(path22) {
19424
+ if (!path22 || typeof path22 !== "string") {
19425
19425
  return false;
19426
19426
  }
19427
- var extension2 = extname3("x." + path21).toLowerCase().substr(1);
19427
+ var extension2 = extname3("x." + path22).toLowerCase().substr(1);
19428
19428
  if (!extension2) {
19429
19429
  return false;
19430
19430
  }
@@ -22942,7 +22942,7 @@ var require_path_to_regexp = __commonJS({
22942
22942
  "use strict";
22943
22943
  module2.exports = pathToRegexp;
22944
22944
  var MATCHING_GROUP_REGEXP = /\\.|\((?:\?<(.*?)>)?(?!\?)/g;
22945
- function pathToRegexp(path21, keys, options) {
22945
+ function pathToRegexp(path22, keys, options) {
22946
22946
  options = options || {};
22947
22947
  keys = keys || [];
22948
22948
  var strict = options.strict;
@@ -22956,8 +22956,8 @@ var require_path_to_regexp = __commonJS({
22956
22956
  var pos = 0;
22957
22957
  var backtrack = "";
22958
22958
  var m;
22959
- if (path21 instanceof RegExp) {
22960
- while (m = MATCHING_GROUP_REGEXP.exec(path21.source)) {
22959
+ if (path22 instanceof RegExp) {
22960
+ while (m = MATCHING_GROUP_REGEXP.exec(path22.source)) {
22961
22961
  if (m[0][0] === "\\") continue;
22962
22962
  keys.push({
22963
22963
  name: m[1] || name2++,
@@ -22965,18 +22965,18 @@ var require_path_to_regexp = __commonJS({
22965
22965
  offset: m.index
22966
22966
  });
22967
22967
  }
22968
- return path21;
22968
+ return path22;
22969
22969
  }
22970
- if (Array.isArray(path21)) {
22971
- path21 = path21.map(function(value) {
22970
+ if (Array.isArray(path22)) {
22971
+ path22 = path22.map(function(value) {
22972
22972
  return pathToRegexp(value, keys, options).source;
22973
22973
  });
22974
- return new RegExp(path21.join("|"), flags);
22974
+ return new RegExp(path22.join("|"), flags);
22975
22975
  }
22976
- if (typeof path21 !== "string") {
22976
+ if (typeof path22 !== "string") {
22977
22977
  throw new TypeError("path must be a string, array of strings, or regular expression");
22978
22978
  }
22979
- path21 = path21.replace(
22979
+ path22 = path22.replace(
22980
22980
  /\\.|(\/)?(\.)?:(\w+)(\(.*?\))?(\*)?(\?)?|[.*]|\/\(/g,
22981
22981
  function(match, slash, format, key, capture, star, optional, offset) {
22982
22982
  if (match[0] === "\\") {
@@ -22993,7 +22993,7 @@ var require_path_to_regexp = __commonJS({
22993
22993
  if (slash || format) {
22994
22994
  backtrack = "";
22995
22995
  } else {
22996
- backtrack += path21.slice(pos, offset);
22996
+ backtrack += path22.slice(pos, offset);
22997
22997
  }
22998
22998
  pos = offset + match.length;
22999
22999
  if (match === "*") {
@@ -23023,7 +23023,7 @@ var require_path_to_regexp = __commonJS({
23023
23023
  return result;
23024
23024
  }
23025
23025
  );
23026
- while (m = MATCHING_GROUP_REGEXP.exec(path21)) {
23026
+ while (m = MATCHING_GROUP_REGEXP.exec(path22)) {
23027
23027
  if (m[0][0] === "\\") continue;
23028
23028
  if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
23029
23029
  keys.splice(keysOffset + i, 0, {
@@ -23035,13 +23035,13 @@ var require_path_to_regexp = __commonJS({
23035
23035
  }
23036
23036
  i++;
23037
23037
  }
23038
- path21 += strict ? "" : path21[path21.length - 1] === "/" ? "?" : "/?";
23038
+ path22 += strict ? "" : path22[path22.length - 1] === "/" ? "?" : "/?";
23039
23039
  if (end) {
23040
- path21 += "$";
23041
- } else if (path21[path21.length - 1] !== "/") {
23042
- path21 += lookahead ? "(?=/|$)" : "(?:/|$)";
23040
+ path22 += "$";
23041
+ } else if (path22[path22.length - 1] !== "/") {
23042
+ path22 += lookahead ? "(?=/|$)" : "(?:/|$)";
23043
23043
  }
23044
- return new RegExp("^" + path21, flags);
23044
+ return new RegExp("^" + path22, flags);
23045
23045
  }
23046
23046
  }
23047
23047
  });
@@ -23054,19 +23054,19 @@ var require_layer = __commonJS({
23054
23054
  var debug = require_src2()("express:router:layer");
23055
23055
  var hasOwnProperty = Object.prototype.hasOwnProperty;
23056
23056
  module2.exports = Layer;
23057
- function Layer(path21, options, fn) {
23057
+ function Layer(path22, options, fn) {
23058
23058
  if (!(this instanceof Layer)) {
23059
- return new Layer(path21, options, fn);
23059
+ return new Layer(path22, options, fn);
23060
23060
  }
23061
- debug("new %o", path21);
23061
+ debug("new %o", path22);
23062
23062
  var opts = options || {};
23063
23063
  this.handle = fn;
23064
23064
  this.name = fn.name || "<anonymous>";
23065
23065
  this.params = void 0;
23066
23066
  this.path = void 0;
23067
- this.regexp = pathRegexp(path21, this.keys = [], opts);
23068
- this.regexp.fast_star = path21 === "*";
23069
- this.regexp.fast_slash = path21 === "/" && opts.end === false;
23067
+ this.regexp = pathRegexp(path22, this.keys = [], opts);
23068
+ this.regexp.fast_star = path22 === "*";
23069
+ this.regexp.fast_slash = path22 === "/" && opts.end === false;
23070
23070
  }
23071
23071
  Layer.prototype.handle_error = function handle_error(error, req, res, next) {
23072
23072
  var fn = this.handle;
@@ -23090,20 +23090,20 @@ var require_layer = __commonJS({
23090
23090
  next(err);
23091
23091
  }
23092
23092
  };
23093
- Layer.prototype.match = function match(path21) {
23093
+ Layer.prototype.match = function match(path22) {
23094
23094
  var match2;
23095
- if (path21 != null) {
23095
+ if (path22 != null) {
23096
23096
  if (this.regexp.fast_slash) {
23097
23097
  this.params = {};
23098
23098
  this.path = "";
23099
23099
  return true;
23100
23100
  }
23101
23101
  if (this.regexp.fast_star) {
23102
- this.params = { "0": decode_param(path21) };
23103
- this.path = path21;
23102
+ this.params = { "0": decode_param(path22) };
23103
+ this.path = path22;
23104
23104
  return true;
23105
23105
  }
23106
- match2 = this.regexp.exec(path21);
23106
+ match2 = this.regexp.exec(path22);
23107
23107
  }
23108
23108
  if (!match2) {
23109
23109
  this.params = void 0;
@@ -23196,10 +23196,10 @@ var require_route = __commonJS({
23196
23196
  var slice = Array.prototype.slice;
23197
23197
  var toString = Object.prototype.toString;
23198
23198
  module2.exports = Route;
23199
- function Route(path21) {
23200
- this.path = path21;
23199
+ function Route(path22) {
23200
+ this.path = path22;
23201
23201
  this.stack = [];
23202
- debug("new %o", path21);
23202
+ debug("new %o", path22);
23203
23203
  this.methods = {};
23204
23204
  }
23205
23205
  Route.prototype._handles_method = function _handles_method(method) {
@@ -23412,8 +23412,8 @@ var require_router = __commonJS({
23412
23412
  if (++sync > 100) {
23413
23413
  return setImmediate(next, err);
23414
23414
  }
23415
- var path21 = getPathname(req);
23416
- if (path21 == null) {
23415
+ var path22 = getPathname(req);
23416
+ if (path22 == null) {
23417
23417
  return done(layerError);
23418
23418
  }
23419
23419
  var layer;
@@ -23421,7 +23421,7 @@ var require_router = __commonJS({
23421
23421
  var route;
23422
23422
  while (match !== true && idx < stack.length) {
23423
23423
  layer = stack[idx++];
23424
- match = matchLayer(layer, path21);
23424
+ match = matchLayer(layer, path22);
23425
23425
  route = layer.route;
23426
23426
  if (typeof match !== "boolean") {
23427
23427
  layerError = layerError || match;
@@ -23459,18 +23459,18 @@ var require_router = __commonJS({
23459
23459
  } else if (route) {
23460
23460
  layer.handle_request(req, res, next);
23461
23461
  } else {
23462
- trim_prefix(layer, layerError, layerPath, path21);
23462
+ trim_prefix(layer, layerError, layerPath, path22);
23463
23463
  }
23464
23464
  sync = 0;
23465
23465
  });
23466
23466
  }
23467
- function trim_prefix(layer, layerError, layerPath, path21) {
23467
+ function trim_prefix(layer, layerError, layerPath, path22) {
23468
23468
  if (layerPath.length !== 0) {
23469
- if (layerPath !== path21.slice(0, layerPath.length)) {
23469
+ if (layerPath !== path22.slice(0, layerPath.length)) {
23470
23470
  next(layerError);
23471
23471
  return;
23472
23472
  }
23473
- var c = path21[layerPath.length];
23473
+ var c = path22[layerPath.length];
23474
23474
  if (c && c !== "/" && c !== ".") return next(layerError);
23475
23475
  debug("trim prefix (%s) from url %s", layerPath, req.url);
23476
23476
  removed = layerPath;
@@ -23548,7 +23548,7 @@ var require_router = __commonJS({
23548
23548
  };
23549
23549
  proto.use = function use(fn) {
23550
23550
  var offset = 0;
23551
- var path21 = "/";
23551
+ var path22 = "/";
23552
23552
  if (typeof fn !== "function") {
23553
23553
  var arg = fn;
23554
23554
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -23556,7 +23556,7 @@ var require_router = __commonJS({
23556
23556
  }
23557
23557
  if (typeof arg !== "function") {
23558
23558
  offset = 1;
23559
- path21 = fn;
23559
+ path22 = fn;
23560
23560
  }
23561
23561
  }
23562
23562
  var callbacks = flatten(slice.call(arguments, offset));
@@ -23568,8 +23568,8 @@ var require_router = __commonJS({
23568
23568
  if (typeof fn !== "function") {
23569
23569
  throw new TypeError("Router.use() requires a middleware function but got a " + gettype(fn));
23570
23570
  }
23571
- debug("use %o %s", path21, fn.name || "<anonymous>");
23572
- var layer = new Layer(path21, {
23571
+ debug("use %o %s", path22, fn.name || "<anonymous>");
23572
+ var layer = new Layer(path22, {
23573
23573
  sensitive: this.caseSensitive,
23574
23574
  strict: false,
23575
23575
  end: false
@@ -23579,9 +23579,9 @@ var require_router = __commonJS({
23579
23579
  }
23580
23580
  return this;
23581
23581
  };
23582
- proto.route = function route(path21) {
23583
- var route2 = new Route(path21);
23584
- var layer = new Layer(path21, {
23582
+ proto.route = function route(path22) {
23583
+ var route2 = new Route(path22);
23584
+ var layer = new Layer(path22, {
23585
23585
  sensitive: this.caseSensitive,
23586
23586
  strict: this.strict,
23587
23587
  end: true
@@ -23591,8 +23591,8 @@ var require_router = __commonJS({
23591
23591
  return route2;
23592
23592
  };
23593
23593
  methods.concat("all").forEach(function(method) {
23594
- proto[method] = function(path21) {
23595
- var route = this.route(path21);
23594
+ proto[method] = function(path22) {
23595
+ var route = this.route(path22);
23596
23596
  route[method].apply(route, slice.call(arguments, 1));
23597
23597
  return this;
23598
23598
  };
@@ -23628,9 +23628,9 @@ var require_router = __commonJS({
23628
23628
  }
23629
23629
  return toString.call(obj).replace(objectRegExp, "$1");
23630
23630
  }
23631
- function matchLayer(layer, path21) {
23631
+ function matchLayer(layer, path22) {
23632
23632
  try {
23633
- return layer.match(path21);
23633
+ return layer.match(path22);
23634
23634
  } catch (err) {
23635
23635
  return err;
23636
23636
  }
@@ -23748,13 +23748,13 @@ var require_view = __commonJS({
23748
23748
  "../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/view.js"(exports2, module2) {
23749
23749
  "use strict";
23750
23750
  var debug = require_src2()("express:view");
23751
- var path21 = require("path");
23752
- var fs20 = require("fs");
23753
- var dirname7 = path21.dirname;
23754
- var basename3 = path21.basename;
23755
- var extname3 = path21.extname;
23756
- var join16 = path21.join;
23757
- var resolve14 = path21.resolve;
23751
+ var path22 = require("path");
23752
+ var fs21 = require("fs");
23753
+ var dirname7 = path22.dirname;
23754
+ var basename4 = path22.basename;
23755
+ var extname3 = path22.extname;
23756
+ var join17 = path22.join;
23757
+ var resolve14 = path22.resolve;
23758
23758
  module2.exports = View;
23759
23759
  function View(name2, options) {
23760
23760
  var opts = options || {};
@@ -23783,17 +23783,17 @@ var require_view = __commonJS({
23783
23783
  this.path = this.lookup(fileName);
23784
23784
  }
23785
23785
  View.prototype.lookup = function lookup(name2) {
23786
- var path22;
23786
+ var path23;
23787
23787
  var roots = [].concat(this.root);
23788
23788
  debug('lookup "%s"', name2);
23789
- for (var i = 0; i < roots.length && !path22; i++) {
23789
+ for (var i = 0; i < roots.length && !path23; i++) {
23790
23790
  var root = roots[i];
23791
23791
  var loc = resolve14(root, name2);
23792
23792
  var dir = dirname7(loc);
23793
- var file = basename3(loc);
23794
- path22 = this.resolve(dir, file);
23793
+ var file = basename4(loc);
23794
+ path23 = this.resolve(dir, file);
23795
23795
  }
23796
- return path22;
23796
+ return path23;
23797
23797
  };
23798
23798
  View.prototype.render = function render(options, callback) {
23799
23799
  debug('render "%s"', this.path);
@@ -23801,21 +23801,21 @@ var require_view = __commonJS({
23801
23801
  };
23802
23802
  View.prototype.resolve = function resolve15(dir, file) {
23803
23803
  var ext = this.ext;
23804
- var path22 = join16(dir, file);
23805
- var stat = tryStat(path22);
23804
+ var path23 = join17(dir, file);
23805
+ var stat = tryStat(path23);
23806
23806
  if (stat && stat.isFile()) {
23807
- return path22;
23807
+ return path23;
23808
23808
  }
23809
- path22 = join16(dir, basename3(file, ext), "index" + ext);
23810
- stat = tryStat(path22);
23809
+ path23 = join17(dir, basename4(file, ext), "index" + ext);
23810
+ stat = tryStat(path23);
23811
23811
  if (stat && stat.isFile()) {
23812
- return path22;
23812
+ return path23;
23813
23813
  }
23814
23814
  };
23815
- function tryStat(path22) {
23816
- debug('stat "%s"', path22);
23815
+ function tryStat(path23) {
23816
+ debug('stat "%s"', path23);
23817
23817
  try {
23818
- return fs20.statSync(path22);
23818
+ return fs21.statSync(path23);
23819
23819
  } catch (e) {
23820
23820
  return void 0;
23821
23821
  }
@@ -23829,7 +23829,7 @@ var require_content_disposition = __commonJS({
23829
23829
  "use strict";
23830
23830
  module2.exports = contentDisposition;
23831
23831
  module2.exports.parse = parse;
23832
- var basename3 = require("path").basename;
23832
+ var basename4 = require("path").basename;
23833
23833
  var Buffer2 = require_safe_buffer().Buffer;
23834
23834
  var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
23835
23835
  var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
@@ -23865,9 +23865,9 @@ var require_content_disposition = __commonJS({
23865
23865
  if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
23866
23866
  throw new TypeError("fallback must be ISO-8859-1 string");
23867
23867
  }
23868
- var name2 = basename3(filename);
23868
+ var name2 = basename4(filename);
23869
23869
  var isQuotedString = TEXT_REGEXP.test(name2);
23870
- var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name2) : basename3(fallback);
23870
+ var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name2) : basename4(fallback);
23871
23871
  var hasFallback = typeof fallbackName === "string" && fallbackName !== name2;
23872
23872
  if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name2)) {
23873
23873
  params["filename*"] = name2;
@@ -24112,8 +24112,8 @@ var require_types = __commonJS({
24112
24112
  var require_mime = __commonJS({
24113
24113
  "../../node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports2, module2) {
24114
24114
  "use strict";
24115
- var path21 = require("path");
24116
- var fs20 = require("fs");
24115
+ var path22 = require("path");
24116
+ var fs21 = require("fs");
24117
24117
  function Mime() {
24118
24118
  this.types = /* @__PURE__ */ Object.create(null);
24119
24119
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -24134,7 +24134,7 @@ var require_mime = __commonJS({
24134
24134
  };
24135
24135
  Mime.prototype.load = function(file) {
24136
24136
  this._loading = file;
24137
- var map = {}, content = fs20.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
24137
+ var map = {}, content = fs21.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
24138
24138
  lines.forEach(function(line) {
24139
24139
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
24140
24140
  map[fields.shift()] = fields;
@@ -24142,8 +24142,8 @@ var require_mime = __commonJS({
24142
24142
  this.define(map);
24143
24143
  this._loading = null;
24144
24144
  };
24145
- Mime.prototype.lookup = function(path22, fallback) {
24146
- var ext = path22.replace(/^.*[\.\/\\]/, "").toLowerCase();
24145
+ Mime.prototype.lookup = function(path23, fallback) {
24146
+ var ext = path23.replace(/^.*[\.\/\\]/, "").toLowerCase();
24147
24147
  return this.types[ext] || fallback || this.default_type;
24148
24148
  };
24149
24149
  Mime.prototype.extension = function(mimeType) {
@@ -24256,33 +24256,33 @@ var require_send = __commonJS({
24256
24256
  var escapeHtml = require_escape_html();
24257
24257
  var etag = require_etag();
24258
24258
  var fresh = require_fresh();
24259
- var fs20 = require("fs");
24259
+ var fs21 = require("fs");
24260
24260
  var mime = require_mime();
24261
24261
  var ms = require_ms();
24262
24262
  var onFinished = require_on_finished();
24263
24263
  var parseRange = require_range_parser();
24264
- var path21 = require("path");
24264
+ var path22 = require("path");
24265
24265
  var statuses = require_statuses();
24266
24266
  var Stream = require("stream");
24267
24267
  var util3 = require("util");
24268
- var extname3 = path21.extname;
24269
- var join16 = path21.join;
24270
- var normalize = path21.normalize;
24271
- var resolve14 = path21.resolve;
24272
- var sep3 = path21.sep;
24268
+ var extname3 = path22.extname;
24269
+ var join17 = path22.join;
24270
+ var normalize = path22.normalize;
24271
+ var resolve14 = path22.resolve;
24272
+ var sep4 = path22.sep;
24273
24273
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
24274
24274
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
24275
24275
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
24276
24276
  module2.exports = send;
24277
24277
  module2.exports.mime = mime;
24278
- function send(req, path22, options) {
24279
- return new SendStream(req, path22, options);
24278
+ function send(req, path23, options) {
24279
+ return new SendStream(req, path23, options);
24280
24280
  }
24281
- function SendStream(req, path22, options) {
24281
+ function SendStream(req, path23, options) {
24282
24282
  Stream.call(this);
24283
24283
  var opts = options || {};
24284
24284
  this.options = opts;
24285
- this.path = path22;
24285
+ this.path = path23;
24286
24286
  this.req = req;
24287
24287
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
24288
24288
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -24328,8 +24328,8 @@ var require_send = __commonJS({
24328
24328
  this._index = index2;
24329
24329
  return this;
24330
24330
  }, "send.index: pass index as option");
24331
- SendStream.prototype.root = function root(path22) {
24332
- this._root = resolve14(String(path22));
24331
+ SendStream.prototype.root = function root(path23) {
24332
+ this._root = resolve14(String(path23));
24333
24333
  debug("root %s", this._root);
24334
24334
  return this;
24335
24335
  };
@@ -24442,10 +24442,10 @@ var require_send = __commonJS({
24442
24442
  var lastModified = this.res.getHeader("Last-Modified");
24443
24443
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
24444
24444
  };
24445
- SendStream.prototype.redirect = function redirect(path22) {
24445
+ SendStream.prototype.redirect = function redirect(path23) {
24446
24446
  var res = this.res;
24447
24447
  if (hasListeners(this, "directory")) {
24448
- this.emit("directory", res, path22);
24448
+ this.emit("directory", res, path23);
24449
24449
  return;
24450
24450
  }
24451
24451
  if (this.hasTrailingSlash()) {
@@ -24465,42 +24465,42 @@ var require_send = __commonJS({
24465
24465
  SendStream.prototype.pipe = function pipe(res) {
24466
24466
  var root = this._root;
24467
24467
  this.res = res;
24468
- var path22 = decode(this.path);
24469
- if (path22 === -1) {
24468
+ var path23 = decode(this.path);
24469
+ if (path23 === -1) {
24470
24470
  this.error(400);
24471
24471
  return res;
24472
24472
  }
24473
- if (~path22.indexOf("\0")) {
24473
+ if (~path23.indexOf("\0")) {
24474
24474
  this.error(400);
24475
24475
  return res;
24476
24476
  }
24477
24477
  var parts;
24478
24478
  if (root !== null) {
24479
- if (path22) {
24480
- path22 = normalize("." + sep3 + path22);
24479
+ if (path23) {
24480
+ path23 = normalize("." + sep4 + path23);
24481
24481
  }
24482
- if (UP_PATH_REGEXP.test(path22)) {
24483
- debug('malicious path "%s"', path22);
24482
+ if (UP_PATH_REGEXP.test(path23)) {
24483
+ debug('malicious path "%s"', path23);
24484
24484
  this.error(403);
24485
24485
  return res;
24486
24486
  }
24487
- parts = path22.split(sep3);
24488
- path22 = normalize(join16(root, path22));
24487
+ parts = path23.split(sep4);
24488
+ path23 = normalize(join17(root, path23));
24489
24489
  } else {
24490
- if (UP_PATH_REGEXP.test(path22)) {
24491
- debug('malicious path "%s"', path22);
24490
+ if (UP_PATH_REGEXP.test(path23)) {
24491
+ debug('malicious path "%s"', path23);
24492
24492
  this.error(403);
24493
24493
  return res;
24494
24494
  }
24495
- parts = normalize(path22).split(sep3);
24496
- path22 = resolve14(path22);
24495
+ parts = normalize(path23).split(sep4);
24496
+ path23 = resolve14(path23);
24497
24497
  }
24498
24498
  if (containsDotFile(parts)) {
24499
24499
  var access = this._dotfiles;
24500
24500
  if (access === void 0) {
24501
24501
  access = parts[parts.length - 1][0] === "." ? this._hidden ? "allow" : "ignore" : "allow";
24502
24502
  }
24503
- debug('%s dotfile "%s"', access, path22);
24503
+ debug('%s dotfile "%s"', access, path23);
24504
24504
  switch (access) {
24505
24505
  case "allow":
24506
24506
  break;
@@ -24514,13 +24514,13 @@ var require_send = __commonJS({
24514
24514
  }
24515
24515
  }
24516
24516
  if (this._index.length && this.hasTrailingSlash()) {
24517
- this.sendIndex(path22);
24517
+ this.sendIndex(path23);
24518
24518
  return res;
24519
24519
  }
24520
- this.sendFile(path22);
24520
+ this.sendFile(path23);
24521
24521
  return res;
24522
24522
  };
24523
- SendStream.prototype.send = function send2(path22, stat) {
24523
+ SendStream.prototype.send = function send2(path23, stat) {
24524
24524
  var len = stat.size;
24525
24525
  var options = this.options;
24526
24526
  var opts = {};
@@ -24532,9 +24532,9 @@ var require_send = __commonJS({
24532
24532
  this.headersAlreadySent();
24533
24533
  return;
24534
24534
  }
24535
- debug('pipe "%s"', path22);
24536
- this.setHeader(path22, stat);
24537
- this.type(path22);
24535
+ debug('pipe "%s"', path23);
24536
+ this.setHeader(path23, stat);
24537
+ this.type(path23);
24538
24538
  if (this.isConditionalGET()) {
24539
24539
  if (this.isPreconditionFailure()) {
24540
24540
  this.error(412);
@@ -24583,28 +24583,28 @@ var require_send = __commonJS({
24583
24583
  res.end();
24584
24584
  return;
24585
24585
  }
24586
- this.stream(path22, opts);
24586
+ this.stream(path23, opts);
24587
24587
  };
24588
- SendStream.prototype.sendFile = function sendFile(path22) {
24588
+ SendStream.prototype.sendFile = function sendFile(path23) {
24589
24589
  var i = 0;
24590
24590
  var self2 = this;
24591
- debug('stat "%s"', path22);
24592
- fs20.stat(path22, function onstat(err, stat) {
24593
- if (err && err.code === "ENOENT" && !extname3(path22) && path22[path22.length - 1] !== sep3) {
24591
+ debug('stat "%s"', path23);
24592
+ fs21.stat(path23, function onstat(err, stat) {
24593
+ if (err && err.code === "ENOENT" && !extname3(path23) && path23[path23.length - 1] !== sep4) {
24594
24594
  return next(err);
24595
24595
  }
24596
24596
  if (err) return self2.onStatError(err);
24597
- if (stat.isDirectory()) return self2.redirect(path22);
24598
- self2.emit("file", path22, stat);
24599
- self2.send(path22, stat);
24597
+ if (stat.isDirectory()) return self2.redirect(path23);
24598
+ self2.emit("file", path23, stat);
24599
+ self2.send(path23, stat);
24600
24600
  });
24601
24601
  function next(err) {
24602
24602
  if (self2._extensions.length <= i) {
24603
24603
  return err ? self2.onStatError(err) : self2.error(404);
24604
24604
  }
24605
- var p = path22 + "." + self2._extensions[i++];
24605
+ var p = path23 + "." + self2._extensions[i++];
24606
24606
  debug('stat "%s"', p);
24607
- fs20.stat(p, function(err2, stat) {
24607
+ fs21.stat(p, function(err2, stat) {
24608
24608
  if (err2) return next(err2);
24609
24609
  if (stat.isDirectory()) return next();
24610
24610
  self2.emit("file", p, stat);
@@ -24612,7 +24612,7 @@ var require_send = __commonJS({
24612
24612
  });
24613
24613
  }
24614
24614
  };
24615
- SendStream.prototype.sendIndex = function sendIndex(path22) {
24615
+ SendStream.prototype.sendIndex = function sendIndex(path23) {
24616
24616
  var i = -1;
24617
24617
  var self2 = this;
24618
24618
  function next(err) {
@@ -24620,9 +24620,9 @@ var require_send = __commonJS({
24620
24620
  if (err) return self2.onStatError(err);
24621
24621
  return self2.error(404);
24622
24622
  }
24623
- var p = join16(path22, self2._index[i]);
24623
+ var p = join17(path23, self2._index[i]);
24624
24624
  debug('stat "%s"', p);
24625
- fs20.stat(p, function(err2, stat) {
24625
+ fs21.stat(p, function(err2, stat) {
24626
24626
  if (err2) return next(err2);
24627
24627
  if (stat.isDirectory()) return next();
24628
24628
  self2.emit("file", p, stat);
@@ -24631,10 +24631,10 @@ var require_send = __commonJS({
24631
24631
  }
24632
24632
  next();
24633
24633
  };
24634
- SendStream.prototype.stream = function stream(path22, options) {
24634
+ SendStream.prototype.stream = function stream(path23, options) {
24635
24635
  var self2 = this;
24636
24636
  var res = this.res;
24637
- var stream2 = fs20.createReadStream(path22, options);
24637
+ var stream2 = fs21.createReadStream(path23, options);
24638
24638
  this.emit("stream", stream2);
24639
24639
  stream2.pipe(res);
24640
24640
  function cleanup() {
@@ -24649,10 +24649,10 @@ var require_send = __commonJS({
24649
24649
  self2.emit("end");
24650
24650
  });
24651
24651
  };
24652
- SendStream.prototype.type = function type(path22) {
24652
+ SendStream.prototype.type = function type(path23) {
24653
24653
  var res = this.res;
24654
24654
  if (res.getHeader("Content-Type")) return;
24655
- var type2 = mime.lookup(path22);
24655
+ var type2 = mime.lookup(path23);
24656
24656
  if (!type2) {
24657
24657
  debug("no content-type");
24658
24658
  return;
@@ -24661,9 +24661,9 @@ var require_send = __commonJS({
24661
24661
  debug("content-type %s", type2);
24662
24662
  res.setHeader("Content-Type", type2 + (charset ? "; charset=" + charset : ""));
24663
24663
  };
24664
- SendStream.prototype.setHeader = function setHeader(path22, stat) {
24664
+ SendStream.prototype.setHeader = function setHeader(path23, stat) {
24665
24665
  var res = this.res;
24666
- this.emit("headers", res, path22, stat);
24666
+ this.emit("headers", res, path23, stat);
24667
24667
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
24668
24668
  debug("accept ranges");
24669
24669
  res.setHeader("Accept-Ranges", "bytes");
@@ -24722,9 +24722,9 @@ var require_send = __commonJS({
24722
24722
  }
24723
24723
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
24724
24724
  }
24725
- function decode(path22) {
24725
+ function decode(path23) {
24726
24726
  try {
24727
- return decodeURIComponent(path22);
24727
+ return decodeURIComponent(path23);
24728
24728
  } catch (err) {
24729
24729
  return -1;
24730
24730
  }
@@ -25634,10 +25634,10 @@ var require_utils2 = __commonJS({
25634
25634
  var querystring = require("querystring");
25635
25635
  exports2.etag = createETagGenerator({ weak: false });
25636
25636
  exports2.wetag = createETagGenerator({ weak: true });
25637
- exports2.isAbsolute = function(path21) {
25638
- if ("/" === path21[0]) return true;
25639
- if (":" === path21[1] && ("\\" === path21[2] || "/" === path21[2])) return true;
25640
- if ("\\\\" === path21.substring(0, 2)) return true;
25637
+ exports2.isAbsolute = function(path22) {
25638
+ if ("/" === path22[0]) return true;
25639
+ if (":" === path22[1] && ("\\" === path22[2] || "/" === path22[2])) return true;
25640
+ if ("\\\\" === path22.substring(0, 2)) return true;
25641
25641
  };
25642
25642
  exports2.flatten = deprecate.function(
25643
25643
  flatten,
@@ -25760,7 +25760,7 @@ var require_application = __commonJS({
25760
25760
  "../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/application.js"(exports2, module2) {
25761
25761
  "use strict";
25762
25762
  var finalhandler = require_finalhandler();
25763
- var Router12 = require_router();
25763
+ var Router13 = require_router();
25764
25764
  var methods = require_methods();
25765
25765
  var middleware = require_init();
25766
25766
  var query = require_query();
@@ -25825,7 +25825,7 @@ var require_application = __commonJS({
25825
25825
  };
25826
25826
  app.lazyrouter = function lazyrouter() {
25827
25827
  if (!this._router) {
25828
- this._router = new Router12({
25828
+ this._router = new Router13({
25829
25829
  caseSensitive: this.enabled("case sensitive routing"),
25830
25830
  strict: this.enabled("strict routing")
25831
25831
  });
@@ -25848,7 +25848,7 @@ var require_application = __commonJS({
25848
25848
  };
25849
25849
  app.use = function use(fn) {
25850
25850
  var offset = 0;
25851
- var path21 = "/";
25851
+ var path22 = "/";
25852
25852
  if (typeof fn !== "function") {
25853
25853
  var arg = fn;
25854
25854
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -25856,7 +25856,7 @@ var require_application = __commonJS({
25856
25856
  }
25857
25857
  if (typeof arg !== "function") {
25858
25858
  offset = 1;
25859
- path21 = fn;
25859
+ path22 = fn;
25860
25860
  }
25861
25861
  }
25862
25862
  var fns = flatten(slice.call(arguments, offset));
@@ -25867,12 +25867,12 @@ var require_application = __commonJS({
25867
25867
  var router = this._router;
25868
25868
  fns.forEach(function(fn2) {
25869
25869
  if (!fn2 || !fn2.handle || !fn2.set) {
25870
- return router.use(path21, fn2);
25870
+ return router.use(path22, fn2);
25871
25871
  }
25872
- debug(".use app under %s", path21);
25873
- fn2.mountpath = path21;
25872
+ debug(".use app under %s", path22);
25873
+ fn2.mountpath = path22;
25874
25874
  fn2.parent = this;
25875
- router.use(path21, function mounted_app(req, res, next) {
25875
+ router.use(path22, function mounted_app(req, res, next) {
25876
25876
  var orig = req.app;
25877
25877
  fn2.handle(req, res, function(err) {
25878
25878
  setPrototypeOf(req, orig.request);
@@ -25884,9 +25884,9 @@ var require_application = __commonJS({
25884
25884
  }, this);
25885
25885
  return this;
25886
25886
  };
25887
- app.route = function route(path21) {
25887
+ app.route = function route(path22) {
25888
25888
  this.lazyrouter();
25889
- return this._router.route(path21);
25889
+ return this._router.route(path22);
25890
25890
  };
25891
25891
  app.engine = function engine(ext, fn) {
25892
25892
  if (typeof fn !== "function") {
@@ -25937,7 +25937,7 @@ var require_application = __commonJS({
25937
25937
  }
25938
25938
  return this;
25939
25939
  };
25940
- app.path = function path21() {
25940
+ app.path = function path22() {
25941
25941
  return this.parent ? this.parent.path() + this.mountpath : "";
25942
25942
  };
25943
25943
  app.enabled = function enabled2(setting) {
@@ -25953,19 +25953,19 @@ var require_application = __commonJS({
25953
25953
  return this.set(setting, false);
25954
25954
  };
25955
25955
  methods.forEach(function(method) {
25956
- app[method] = function(path21) {
25956
+ app[method] = function(path22) {
25957
25957
  if (method === "get" && arguments.length === 1) {
25958
- return this.set(path21);
25958
+ return this.set(path22);
25959
25959
  }
25960
25960
  this.lazyrouter();
25961
- var route = this._router.route(path21);
25961
+ var route = this._router.route(path22);
25962
25962
  route[method].apply(route, slice.call(arguments, 1));
25963
25963
  return this;
25964
25964
  };
25965
25965
  });
25966
- app.all = function all(path21) {
25966
+ app.all = function all(path22) {
25967
25967
  this.lazyrouter();
25968
- var route = this._router.route(path21);
25968
+ var route = this._router.route(path22);
25969
25969
  var args = slice.call(arguments, 1);
25970
25970
  for (var i = 0; i < methods.length; i++) {
25971
25971
  route[methods[i]].apply(route, args);
@@ -26724,7 +26724,7 @@ var require_request = __commonJS({
26724
26724
  var subdomains2 = !isIP(hostname3) ? hostname3.split(".").reverse() : [hostname3];
26725
26725
  return subdomains2.slice(offset);
26726
26726
  });
26727
- defineGetter(req, "path", function path21() {
26727
+ defineGetter(req, "path", function path22() {
26728
26728
  return parse(this).pathname;
26729
26729
  });
26730
26730
  defineGetter(req, "hostname", function hostname3() {
@@ -27047,7 +27047,7 @@ var require_response = __commonJS({
27047
27047
  var http3 = require("http");
27048
27048
  var isAbsolute4 = require_utils2().isAbsolute;
27049
27049
  var onFinished = require_on_finished();
27050
- var path21 = require("path");
27050
+ var path22 = require("path");
27051
27051
  var statuses = require_statuses();
27052
27052
  var merge = require_utils_merge();
27053
27053
  var sign = require_cookie_signature().sign;
@@ -27056,9 +27056,9 @@ var require_response = __commonJS({
27056
27056
  var setCharset = require_utils2().setCharset;
27057
27057
  var cookie = require_cookie();
27058
27058
  var send = require_send();
27059
- var extname3 = path21.extname;
27059
+ var extname3 = path22.extname;
27060
27060
  var mime = send.mime;
27061
- var resolve14 = path21.resolve;
27061
+ var resolve14 = path22.resolve;
27062
27062
  var vary = require_vary();
27063
27063
  var res = Object.create(http3.ServerResponse.prototype);
27064
27064
  module2.exports = res;
@@ -27235,26 +27235,26 @@ var require_response = __commonJS({
27235
27235
  this.type("txt");
27236
27236
  return this.send(body);
27237
27237
  };
27238
- res.sendFile = function sendFile(path22, options, callback) {
27238
+ res.sendFile = function sendFile(path23, options, callback) {
27239
27239
  var done = callback;
27240
27240
  var req = this.req;
27241
27241
  var res2 = this;
27242
27242
  var next = req.next;
27243
27243
  var opts = options || {};
27244
- if (!path22) {
27244
+ if (!path23) {
27245
27245
  throw new TypeError("path argument is required to res.sendFile");
27246
27246
  }
27247
- if (typeof path22 !== "string") {
27247
+ if (typeof path23 !== "string") {
27248
27248
  throw new TypeError("path must be a string to res.sendFile");
27249
27249
  }
27250
27250
  if (typeof options === "function") {
27251
27251
  done = options;
27252
27252
  opts = {};
27253
27253
  }
27254
- if (!opts.root && !isAbsolute4(path22)) {
27254
+ if (!opts.root && !isAbsolute4(path23)) {
27255
27255
  throw new TypeError("path must be absolute or specify root to res.sendFile");
27256
27256
  }
27257
- var pathname = encodeURI(path22);
27257
+ var pathname = encodeURI(path23);
27258
27258
  var file = send(req, pathname, opts);
27259
27259
  sendfile(res2, file, opts, function(err) {
27260
27260
  if (done) return done(err);
@@ -27264,7 +27264,7 @@ var require_response = __commonJS({
27264
27264
  }
27265
27265
  });
27266
27266
  };
27267
- res.sendfile = function(path22, options, callback) {
27267
+ res.sendfile = function(path23, options, callback) {
27268
27268
  var done = callback;
27269
27269
  var req = this.req;
27270
27270
  var res2 = this;
@@ -27274,7 +27274,7 @@ var require_response = __commonJS({
27274
27274
  done = options;
27275
27275
  opts = {};
27276
27276
  }
27277
- var file = send(req, path22, opts);
27277
+ var file = send(req, path23, opts);
27278
27278
  sendfile(res2, file, opts, function(err) {
27279
27279
  if (done) return done(err);
27280
27280
  if (err && err.code === "EISDIR") return next();
@@ -27287,7 +27287,7 @@ var require_response = __commonJS({
27287
27287
  res.sendfile,
27288
27288
  "res.sendfile: Use res.sendFile instead"
27289
27289
  );
27290
- res.download = function download(path22, filename, options, callback) {
27290
+ res.download = function download(path23, filename, options, callback) {
27291
27291
  var done = callback;
27292
27292
  var name2 = filename;
27293
27293
  var opts = options || null;
@@ -27304,7 +27304,7 @@ var require_response = __commonJS({
27304
27304
  opts = filename;
27305
27305
  }
27306
27306
  var headers = {
27307
- "Content-Disposition": contentDisposition(name2 || path22)
27307
+ "Content-Disposition": contentDisposition(name2 || path23)
27308
27308
  };
27309
27309
  if (opts && opts.headers) {
27310
27310
  var keys = Object.keys(opts.headers);
@@ -27317,7 +27317,7 @@ var require_response = __commonJS({
27317
27317
  }
27318
27318
  opts = Object.create(opts);
27319
27319
  opts.headers = headers;
27320
- var fullPath = !opts.root ? resolve14(path22) : path22;
27320
+ var fullPath = !opts.root ? resolve14(path23) : path23;
27321
27321
  return this.sendFile(fullPath, opts, done);
27322
27322
  };
27323
27323
  res.contentType = res.type = function contentType(type) {
@@ -27618,11 +27618,11 @@ var require_serve_static = __commonJS({
27618
27618
  }
27619
27619
  var forwardError = !fallthrough;
27620
27620
  var originalUrl = parseUrl.original(req);
27621
- var path21 = parseUrl(req).pathname;
27622
- if (path21 === "/" && originalUrl.pathname.substr(-1) !== "/") {
27623
- path21 = "";
27621
+ var path22 = parseUrl(req).pathname;
27622
+ if (path22 === "/" && originalUrl.pathname.substr(-1) !== "/") {
27623
+ path22 = "";
27624
27624
  }
27625
- var stream = send(req, path21, opts);
27625
+ var stream = send(req, path22, opts);
27626
27626
  stream.on("directory", onDirectory);
27627
27627
  if (setHeaders) {
27628
27628
  stream.on("headers", setHeaders);
@@ -27690,7 +27690,7 @@ var require_express = __commonJS({
27690
27690
  var mixin = require_merge_descriptors();
27691
27691
  var proto = require_application();
27692
27692
  var Route = require_route();
27693
- var Router12 = require_router();
27693
+ var Router13 = require_router();
27694
27694
  var req = require_request();
27695
27695
  var res = require_response();
27696
27696
  exports2 = module2.exports = createApplication;
@@ -27713,7 +27713,7 @@ var require_express = __commonJS({
27713
27713
  exports2.request = req;
27714
27714
  exports2.response = res;
27715
27715
  exports2.Route = Route;
27716
- exports2.Router = Router12;
27716
+ exports2.Router = Router13;
27717
27717
  exports2.json = bodyParser.json;
27718
27718
  exports2.query = require_query();
27719
27719
  exports2.raw = bodyParser.raw;
@@ -32265,11 +32265,11 @@ function persistNodeStartupTransport(storagePath, transport) {
32265
32265
  transport
32266
32266
  });
32267
32267
  }
32268
- function persistNodeStartupJoin(storagePath, join16) {
32268
+ function persistNodeStartupJoin(storagePath, join17) {
32269
32269
  const startup = resolveNodeStartupMetadata(storagePath);
32270
32270
  persistNodeStartupMetadata(storagePath, {
32271
32271
  ...startup,
32272
- join: join16
32272
+ join: join17
32273
32273
  });
32274
32274
  }
32275
32275
  function resolvePersistedDevTunnelId(storagePath, kind) {
@@ -32612,6 +32612,10 @@ var TASK_PRIORITIES = /* @__PURE__ */ new Set([
32612
32612
  "high",
32613
32613
  "critical"
32614
32614
  ]);
32615
+ var TASK_CONVERSATION_KIND_SET = /* @__PURE__ */ new Set([
32616
+ "meshyChat",
32617
+ "nativeSession"
32618
+ ]);
32615
32619
  var NODE_ROLES = /* @__PURE__ */ new Set([
32616
32620
  "leader",
32617
32621
  "follower"
@@ -32627,6 +32631,9 @@ function isTaskStatus(value) {
32627
32631
  function isTaskPriority(value) {
32628
32632
  return typeof value === "string" && TASK_PRIORITIES.has(value);
32629
32633
  }
32634
+ function isTaskConversationKind(value) {
32635
+ return typeof value === "string" && TASK_CONVERSATION_KIND_SET.has(value);
32636
+ }
32630
32637
  function isNodeRole(value) {
32631
32638
  return typeof value === "string" && NODE_ROLES.has(value);
32632
32639
  }
@@ -33117,7 +33124,8 @@ function parseTask(value) {
33117
33124
  }
33118
33125
  const status = asTaskStatus(value.status);
33119
33126
  const priority = asTaskPriority(value.priority);
33120
- if (typeof value.id !== "string" || typeof value.title !== "string" || typeof value.description !== "string" || typeof value.agent !== "string" || value.project !== null && typeof value.project !== "string" || value.effectiveProjectPath !== null && value.effectiveProjectPath !== void 0 && typeof value.effectiveProjectPath !== "string" || value.branch !== null && value.branch !== void 0 && typeof value.branch !== "string" || !isPlainObject(value.payload) || status === null || priority === null || value.assignedTo !== null && typeof value.assignedTo !== "string" || value.assignedNodeName !== void 0 && value.assignedNodeName !== null && typeof value.assignedNodeName !== "string" || typeof value.createdBy !== "string" || value.result !== null && !isPlainObject(value.result) || value.error !== null && typeof value.error !== "string" || typeof value.retryCount !== "number" || !Number.isFinite(value.retryCount) || typeof value.maxRetries !== "number" || !Number.isFinite(value.maxRetries) || typeof value.createdAt !== "number" || !Number.isFinite(value.createdAt) || typeof value.updatedAt !== "number" || !Number.isFinite(value.updatedAt)) {
33127
+ const conversationKind = value.conversationKind === void 0 ? "meshyChat" : asTaskConversationKind(value.conversationKind);
33128
+ if (typeof value.id !== "string" || typeof value.title !== "string" || typeof value.description !== "string" || typeof value.agent !== "string" || value.project !== null && typeof value.project !== "string" || value.effectiveProjectPath !== null && value.effectiveProjectPath !== void 0 && typeof value.effectiveProjectPath !== "string" || value.branch !== null && value.branch !== void 0 && typeof value.branch !== "string" || conversationKind === null || !isPlainObject(value.payload) || status === null || priority === null || value.assignedTo !== null && typeof value.assignedTo !== "string" || value.assignedNodeName !== void 0 && value.assignedNodeName !== null && typeof value.assignedNodeName !== "string" || typeof value.createdBy !== "string" || value.result !== null && !isPlainObject(value.result) || value.error !== null && typeof value.error !== "string" || typeof value.retryCount !== "number" || !Number.isFinite(value.retryCount) || typeof value.maxRetries !== "number" || !Number.isFinite(value.maxRetries) || typeof value.createdAt !== "number" || !Number.isFinite(value.createdAt) || typeof value.updatedAt !== "number" || !Number.isFinite(value.updatedAt)) {
33121
33129
  return null;
33122
33130
  }
33123
33131
  return {
@@ -33128,6 +33136,7 @@ function parseTask(value) {
33128
33136
  project: value.project ?? null,
33129
33137
  effectiveProjectPath: typeof value.effectiveProjectPath === "string" ? value.effectiveProjectPath : null,
33130
33138
  branch: value.branch === void 0 ? void 0 : typeof value.branch === "string" ? value.branch : null,
33139
+ conversationKind,
33131
33140
  payload: clone(value.payload),
33132
33141
  status,
33133
33142
  priority,
@@ -33177,6 +33186,9 @@ function asTaskStatus(value) {
33177
33186
  function asTaskPriority(value) {
33178
33187
  return isTaskPriority(value) ? value : null;
33179
33188
  }
33189
+ function asTaskConversationKind(value) {
33190
+ return isTaskConversationKind(value) ? value : null;
33191
+ }
33180
33192
  function sortEntries(input) {
33181
33193
  return Array.from(input.entries()).sort(([left], [right]) => left.localeCompare(right));
33182
33194
  }
@@ -33254,19 +33266,19 @@ async function fetchWithTimeout(url, init, timeoutMs = DEFAULT_NODE_REQUEST_TIME
33254
33266
  cleanup();
33255
33267
  }
33256
33268
  }
33257
- async function fetchNodeWithFallback(node, path21, init, timeoutMs = DEFAULT_NODE_REQUEST_TIMEOUT_MS, trace, options) {
33269
+ async function fetchNodeWithFallback(node, path22, init, timeoutMs = DEFAULT_NODE_REQUEST_TIMEOUT_MS, trace, options) {
33258
33270
  let lastError;
33259
33271
  const endpoints = getNodeRequestEndpoints(node, options);
33260
33272
  for (const [index, endpoint] of endpoints.entries()) {
33261
33273
  const attempt = index + 1;
33262
- trace?.onAttempt?.({ attempt, endpoint, path: path21, timeoutMs, totalEndpoints: endpoints.length });
33274
+ trace?.onAttempt?.({ attempt, endpoint, path: path22, timeoutMs, totalEndpoints: endpoints.length });
33263
33275
  try {
33264
- const response = await fetchWithTimeout(`${endpoint}${path21}`, init, timeoutMs);
33265
- trace?.onResponse?.({ attempt, endpoint, path: path21, response, timeoutMs, totalEndpoints: endpoints.length });
33276
+ const response = await fetchWithTimeout(`${endpoint}${path22}`, init, timeoutMs);
33277
+ trace?.onResponse?.({ attempt, endpoint, path: path22, response, timeoutMs, totalEndpoints: endpoints.length });
33266
33278
  return { endpoint, response };
33267
33279
  } catch (error) {
33268
33280
  lastError = error;
33269
- trace?.onError?.({ attempt, endpoint, error, path: path21, timeoutMs, totalEndpoints: endpoints.length });
33281
+ trace?.onError?.({ attempt, endpoint, error, path: path22, timeoutMs, totalEndpoints: endpoints.length });
33270
33282
  }
33271
33283
  }
33272
33284
  throw lastError instanceof Error ? lastError : new Error("No reachable node endpoint");
@@ -33852,6 +33864,7 @@ var TaskEngine = class {
33852
33864
  project: input.project ?? null,
33853
33865
  effectiveProjectPath: null,
33854
33866
  branch: input.branch ?? null,
33867
+ conversationKind: input.conversationKind ?? "meshyChat",
33855
33868
  payload: input.payload,
33856
33869
  status: "pending",
33857
33870
  priority: input.priority ?? "normal",
@@ -34540,8 +34553,11 @@ var NODE_KIND_BY_LEGACY = {
34540
34553
  "node-workdir-tree": "node.workdir.tree",
34541
34554
  "node-workdir-branch-info": "node.workdir.branch-info",
34542
34555
  "node-workdir-branch-create": "node.workdir.branch-create",
34556
+ "node-sessions-list": "node.sessions.list",
34543
34557
  devtunnel: "node.transport.set",
34558
+ "node-agent-upgrade": "node.agent.upgrade",
34544
34559
  "task-cancel": "task.cancel",
34560
+ "task-logs": "task.logs",
34545
34561
  "task-output-summary": "task.output.summary",
34546
34562
  "task-output-tree": "task.output.tree",
34547
34563
  "task-output-content": "task.output.content",
@@ -35305,9 +35321,9 @@ var DataRouter = class {
35305
35321
  /**
35306
35322
  * Returns true if the request should be proxied to the leader.
35307
35323
  */
35308
- shouldProxy(method, path21) {
35324
+ shouldProxy(method, path22) {
35309
35325
  if (this.election.isLeader()) return false;
35310
- if (this.isExcludedPath(path21)) return false;
35326
+ if (this.isExcludedPath(path22)) return false;
35311
35327
  if (method.toUpperCase() === "GET") return false;
35312
35328
  return WRITE_METHODS.has(method.toUpperCase());
35313
35329
  }
@@ -35411,8 +35427,8 @@ var DataRouter = class {
35411
35427
  };
35412
35428
  }
35413
35429
  // ── Helpers ───────────────────────────────────────────────────────────
35414
- isExcludedPath(path21) {
35415
- return EXCLUDED_PATH_PREFIXES.some((prefix) => path21.startsWith(prefix)) || EXCLUDED_PATH_SUFFIXES.some((suffix) => path21.endsWith(suffix));
35430
+ isExcludedPath(path22) {
35431
+ return EXCLUDED_PATH_PREFIXES.some((prefix) => path22.startsWith(prefix)) || EXCLUDED_PATH_SUFFIXES.some((suffix) => path22.endsWith(suffix));
35416
35432
  }
35417
35433
  };
35418
35434
 
@@ -35550,6 +35566,328 @@ var EngineRegistry = class {
35550
35566
  }
35551
35567
  };
35552
35568
 
35569
+ // ../../packages/core/src/agents/native-session-history.ts
35570
+ var fs7 = __toESM(require("fs"), 1);
35571
+ var os4 = __toESM(require("os"), 1);
35572
+ var path7 = __toESM(require("path"), 1);
35573
+ function isRecord2(value) {
35574
+ return typeof value === "object" && value !== null;
35575
+ }
35576
+ function readJsonLines(filePath) {
35577
+ if (!fs7.existsSync(filePath)) {
35578
+ return [];
35579
+ }
35580
+ const content = fs7.readFileSync(filePath, "utf8");
35581
+ if (!content.trim()) {
35582
+ return [];
35583
+ }
35584
+ return content.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => {
35585
+ try {
35586
+ const parsed = JSON.parse(line);
35587
+ return isRecord2(parsed) ? [parsed] : [];
35588
+ } catch {
35589
+ return [];
35590
+ }
35591
+ });
35592
+ }
35593
+ function readFileModifiedAt(filePath) {
35594
+ try {
35595
+ return fs7.statSync(filePath).mtime.toISOString();
35596
+ } catch {
35597
+ return null;
35598
+ }
35599
+ }
35600
+ function compareUpdatedSessions(left, right) {
35601
+ const leftTime = left.updatedAt ? Date.parse(left.updatedAt) : 0;
35602
+ const rightTime = right.updatedAt ? Date.parse(right.updatedAt) : 0;
35603
+ return rightTime - leftTime || left.sessionId.localeCompare(right.sessionId);
35604
+ }
35605
+ function getNativeHomeDir() {
35606
+ return process.env.HOME || process.env.USERPROFILE || os4.homedir();
35607
+ }
35608
+ function findMatchingFiles(rootDir, predicate) {
35609
+ if (!fs7.existsSync(rootDir)) {
35610
+ return [];
35611
+ }
35612
+ const matches = [];
35613
+ const pendingDirs = [rootDir];
35614
+ while (pendingDirs.length > 0) {
35615
+ const currentDir = pendingDirs.shift();
35616
+ if (!currentDir) continue;
35617
+ const entries = fs7.readdirSync(currentDir, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
35618
+ for (const entry of entries) {
35619
+ const entryPath = path7.join(currentDir, entry.name);
35620
+ if (entry.isDirectory()) {
35621
+ pendingDirs.push(entryPath);
35622
+ continue;
35623
+ }
35624
+ if (!entry.isFile() || !predicate(entryPath)) {
35625
+ continue;
35626
+ }
35627
+ let mtimeMs = 0;
35628
+ try {
35629
+ mtimeMs = fs7.statSync(entryPath).mtimeMs;
35630
+ } catch {
35631
+ mtimeMs = 0;
35632
+ }
35633
+ matches.push({ filePath: entryPath, mtimeMs });
35634
+ }
35635
+ }
35636
+ return matches.sort((left, right) => right.mtimeMs - left.mtimeMs || left.filePath.localeCompare(right.filePath)).map((entry) => entry.filePath);
35637
+ }
35638
+ function findFirstMatchingFile(rootDir, predicate) {
35639
+ if (!fs7.existsSync(rootDir)) {
35640
+ return null;
35641
+ }
35642
+ const pendingDirs = [rootDir];
35643
+ while (pendingDirs.length > 0) {
35644
+ const currentDir = pendingDirs.shift();
35645
+ if (!currentDir) continue;
35646
+ const entries = fs7.readdirSync(currentDir, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
35647
+ for (const entry of entries) {
35648
+ const entryPath = path7.join(currentDir, entry.name);
35649
+ if (entry.isDirectory()) {
35650
+ pendingDirs.push(entryPath);
35651
+ continue;
35652
+ }
35653
+ if (entry.isFile() && predicate(entryPath)) {
35654
+ return entryPath;
35655
+ }
35656
+ }
35657
+ }
35658
+ return null;
35659
+ }
35660
+ function buildAssistantTextEvent(text, timestamp) {
35661
+ return {
35662
+ type: "assistant",
35663
+ message: {
35664
+ role: "assistant",
35665
+ content: [{ type: "text", text }]
35666
+ },
35667
+ ...timestamp ? { timestamp } : {}
35668
+ };
35669
+ }
35670
+ function buildAssistantThinkingEvent(thinking, timestamp) {
35671
+ return {
35672
+ type: "assistant",
35673
+ message: {
35674
+ role: "assistant",
35675
+ content: [{ type: "thinking", thinking }]
35676
+ },
35677
+ ...timestamp ? { timestamp } : {}
35678
+ };
35679
+ }
35680
+ function extractCodexReasoningText(item) {
35681
+ if (typeof item.text === "string") {
35682
+ return item.text.trim();
35683
+ }
35684
+ if (Array.isArray(item.summary)) {
35685
+ return item.summary.map((entry) => {
35686
+ if (typeof entry === "string") return entry.trim();
35687
+ if (isRecord2(entry) && typeof entry.text === "string") {
35688
+ return entry.text.trim();
35689
+ }
35690
+ return "";
35691
+ }).filter(Boolean).join("\n\n");
35692
+ }
35693
+ return "";
35694
+ }
35695
+ function truncateSummary(text, maxLength = 96) {
35696
+ const normalized = text.replace(/\s+/g, " ").trim();
35697
+ if (!normalized) {
35698
+ return "";
35699
+ }
35700
+ if (normalized.length <= maxLength) {
35701
+ return normalized;
35702
+ }
35703
+ return `${normalized.slice(0, maxLength - 1).trimEnd()}\u2026`;
35704
+ }
35705
+ function extractTextFromClaudeMessageContent(content) {
35706
+ if (typeof content === "string") {
35707
+ return truncateSummary(content);
35708
+ }
35709
+ if (!Array.isArray(content)) {
35710
+ return "";
35711
+ }
35712
+ for (const part of content) {
35713
+ if (!isRecord2(part)) continue;
35714
+ if (typeof part.text === "string" && part.text.trim()) {
35715
+ return truncateSummary(part.text);
35716
+ }
35717
+ if (part.type === "tool_result" && typeof part.content === "string" && part.content.trim()) {
35718
+ return truncateSummary(part.content);
35719
+ }
35720
+ }
35721
+ return "";
35722
+ }
35723
+ function findClaudeSessionSummary(entries, sessionId) {
35724
+ let cwd = "";
35725
+ let summary = "";
35726
+ let updatedAt = null;
35727
+ for (const entry of entries) {
35728
+ if (typeof entry.timestamp === "string") {
35729
+ updatedAt = entry.timestamp;
35730
+ }
35731
+ if (!cwd && typeof entry.cwd === "string" && entry.cwd.trim()) {
35732
+ cwd = entry.cwd.trim();
35733
+ }
35734
+ if (summary || entry.type !== "user" || !isRecord2(entry.message)) {
35735
+ continue;
35736
+ }
35737
+ const candidate = extractTextFromClaudeMessageContent(entry.message.content);
35738
+ if (candidate) {
35739
+ summary = candidate;
35740
+ }
35741
+ }
35742
+ if (!cwd) {
35743
+ return null;
35744
+ }
35745
+ return {
35746
+ agent: "claudecode",
35747
+ sessionId,
35748
+ cwd,
35749
+ summary: summary || `Claude Code session ${sessionId.slice(0, 12)}`,
35750
+ updatedAt
35751
+ };
35752
+ }
35753
+ function loadCodexSessionIndex() {
35754
+ const indexPath = path7.join(getNativeHomeDir(), ".codex", "session_index.jsonl");
35755
+ const index = /* @__PURE__ */ new Map();
35756
+ for (const entry of readJsonLines(indexPath)) {
35757
+ if (typeof entry.id !== "string" || !entry.id.trim()) {
35758
+ continue;
35759
+ }
35760
+ index.set(entry.id, {
35761
+ ...typeof entry.thread_name === "string" && entry.thread_name.trim() ? { threadName: truncateSummary(entry.thread_name) } : {},
35762
+ ...typeof entry.updated_at === "string" && entry.updated_at.trim() ? { updatedAt: entry.updated_at } : {}
35763
+ });
35764
+ }
35765
+ return index;
35766
+ }
35767
+ function findCodexSessionSummary(entries, filePath, sessionIndex) {
35768
+ let sessionId = path7.basename(filePath, ".jsonl");
35769
+ let cwd = "";
35770
+ let summary = "";
35771
+ let updatedAt = null;
35772
+ for (const entry of entries) {
35773
+ if (typeof entry.timestamp === "string") {
35774
+ updatedAt = entry.timestamp;
35775
+ }
35776
+ if (entry.type === "session_meta" && isRecord2(entry.payload)) {
35777
+ if (typeof entry.payload.id === "string" && entry.payload.id.trim()) {
35778
+ sessionId = entry.payload.id.trim();
35779
+ }
35780
+ if (!cwd && typeof entry.payload.cwd === "string" && entry.payload.cwd.trim()) {
35781
+ cwd = entry.payload.cwd.trim();
35782
+ }
35783
+ continue;
35784
+ }
35785
+ if (!summary && entry.type === "event_msg" && isRecord2(entry.payload) && entry.payload.type === "user_message") {
35786
+ if (typeof entry.payload.message === "string" && entry.payload.message.trim()) {
35787
+ summary = truncateSummary(entry.payload.message);
35788
+ }
35789
+ }
35790
+ }
35791
+ if (!cwd || !sessionId) {
35792
+ return null;
35793
+ }
35794
+ const indexed = sessionIndex.get(sessionId);
35795
+ return {
35796
+ agent: "codex",
35797
+ sessionId,
35798
+ cwd,
35799
+ summary: indexed?.threadName || summary || `Codex session ${sessionId.slice(0, 12)}`,
35800
+ updatedAt: indexed?.updatedAt ?? updatedAt
35801
+ };
35802
+ }
35803
+ function loadClaudeSessionHistory(sessionId) {
35804
+ const projectsDir = path7.join(getNativeHomeDir(), ".claude", "projects");
35805
+ const sessionFile = findFirstMatchingFile(projectsDir, (filePath) => {
35806
+ if (filePath.includes(`${path7.sep}subagents${path7.sep}`)) {
35807
+ return false;
35808
+ }
35809
+ return path7.basename(filePath).toLowerCase() === `${sessionId.toLowerCase()}.jsonl`;
35810
+ });
35811
+ if (!sessionFile) {
35812
+ return { logs: [], sourcePath: null };
35813
+ }
35814
+ const logs = readJsonLines(sessionFile).filter((entry) => {
35815
+ if (entry.type !== "user" && entry.type !== "assistant" || entry.isMeta === true || entry.isSidechain === true) {
35816
+ return false;
35817
+ }
35818
+ return isRecord2(entry.message);
35819
+ });
35820
+ return { logs, sourcePath: sessionFile };
35821
+ }
35822
+ function loadCodexSessionHistory(sessionId) {
35823
+ const sessionsDir = path7.join(getNativeHomeDir(), ".codex", "sessions");
35824
+ const sessionFile = findFirstMatchingFile(sessionsDir, (filePath) => path7.basename(filePath).toLowerCase().includes(sessionId.toLowerCase()) && filePath.toLowerCase().endsWith(".jsonl"));
35825
+ if (!sessionFile) {
35826
+ return { logs: [], sourcePath: null };
35827
+ }
35828
+ const logs = readJsonLines(sessionFile).flatMap((entry) => {
35829
+ if (entry.type !== "event_msg" || !isRecord2(entry.payload)) {
35830
+ return [];
35831
+ }
35832
+ const timestamp = typeof entry.timestamp === "string" ? entry.timestamp : void 0;
35833
+ const payload = entry.payload;
35834
+ if (payload.type === "user_message" && typeof payload.message === "string" && payload.message.trim()) {
35835
+ return [buildTaskUserLogEvent([{ type: "text", text: payload.message.trim() }], timestamp)];
35836
+ }
35837
+ if (payload.type === "agent_message" && typeof payload.message === "string" && payload.message.trim()) {
35838
+ return [buildAssistantTextEvent(payload.message.trim(), timestamp)];
35839
+ }
35840
+ if (payload.type === "agent_reasoning") {
35841
+ const reasoning = extractCodexReasoningText(payload);
35842
+ if (reasoning) {
35843
+ return [buildAssistantThinkingEvent(reasoning, timestamp)];
35844
+ }
35845
+ }
35846
+ return [];
35847
+ });
35848
+ return { logs, sourcePath: sessionFile };
35849
+ }
35850
+ function loadNativeSessionHistory(input) {
35851
+ if (input.agent === "claudecode") {
35852
+ return loadClaudeSessionHistory(input.sessionId);
35853
+ }
35854
+ return loadCodexSessionHistory(input.sessionId);
35855
+ }
35856
+ function listNativeSessions(input) {
35857
+ const limit = Math.min(Math.max(1, input.limit ?? 50), 100);
35858
+ if (input.agent === "claudecode") {
35859
+ const projectsDir = path7.join(getNativeHomeDir(), ".claude", "projects");
35860
+ return findMatchingFiles(projectsDir, (filePath) => {
35861
+ if (filePath.includes(`${path7.sep}subagents${path7.sep}`)) {
35862
+ return false;
35863
+ }
35864
+ return filePath.toLowerCase().endsWith(".jsonl");
35865
+ }).map((filePath) => {
35866
+ const sessionId = path7.basename(filePath, ".jsonl");
35867
+ const summary = findClaudeSessionSummary(readJsonLines(filePath), sessionId);
35868
+ if (!summary) {
35869
+ return null;
35870
+ }
35871
+ return {
35872
+ ...summary,
35873
+ updatedAt: summary.updatedAt ?? readFileModifiedAt(filePath)
35874
+ };
35875
+ }).filter((session) => session !== null).sort(compareUpdatedSessions).slice(0, limit);
35876
+ }
35877
+ const sessionIndex = loadCodexSessionIndex();
35878
+ const sessionsDir = path7.join(getNativeHomeDir(), ".codex", "sessions");
35879
+ return findMatchingFiles(sessionsDir, (filePath) => filePath.toLowerCase().endsWith(".jsonl")).map((filePath) => {
35880
+ const summary = findCodexSessionSummary(readJsonLines(filePath), filePath, sessionIndex);
35881
+ if (!summary) {
35882
+ return null;
35883
+ }
35884
+ return {
35885
+ ...summary,
35886
+ updatedAt: summary.updatedAt ?? readFileModifiedAt(filePath)
35887
+ };
35888
+ }).filter((session) => session !== null).sort(compareUpdatedSessions).slice(0, limit);
35889
+ }
35890
+
35553
35891
  // ../../packages/core/src/tasks/task-forwarding.ts
35554
35892
  function getEventType(event) {
35555
35893
  return typeof event.type === "string" ? event.type : void 0;
@@ -35857,18 +36195,18 @@ function getCurrentGitBranch(workDir) {
35857
36195
  var import_node_child_process3 = require("child_process");
35858
36196
 
35859
36197
  // ../../packages/core/src/agents/cli-invocations.ts
35860
- var fs7 = __toESM(require("fs"), 1);
35861
- var path7 = __toESM(require("path"), 1);
36198
+ var fs8 = __toESM(require("fs"), 1);
36199
+ var path8 = __toESM(require("path"), 1);
35862
36200
  function resolveClaudeInvocation() {
35863
36201
  if (process.platform !== "win32") {
35864
36202
  return { command: "claude", argsPrefix: [] };
35865
36203
  }
35866
- const pathEntries = (process.env.PATH ?? "").split(path7.delimiter).filter(Boolean);
36204
+ const pathEntries = (process.env.PATH ?? "").split(path8.delimiter).filter(Boolean);
35867
36205
  for (const entry of pathEntries) {
35868
- const shimPath = path7.join(entry, "claude.cmd");
35869
- if (!fs7.existsSync(shimPath)) continue;
35870
- const cliPath = path7.join(entry, "node_modules", "@anthropic-ai", "claude-code", "cli.js");
35871
- if (fs7.existsSync(cliPath)) {
36206
+ const shimPath = path8.join(entry, "claude.cmd");
36207
+ if (!fs8.existsSync(shimPath)) continue;
36208
+ const cliPath = path8.join(entry, "node_modules", "@anthropic-ai", "claude-code", "cli.js");
36209
+ if (fs8.existsSync(cliPath)) {
35872
36210
  return {
35873
36211
  command: process.execPath,
35874
36212
  argsPrefix: [cliPath]
@@ -35881,12 +36219,12 @@ function resolveCodexInvocation() {
35881
36219
  if (process.platform !== "win32") {
35882
36220
  return { command: "codex", argsPrefix: [] };
35883
36221
  }
35884
- const pathEntries = (process.env.PATH ?? "").split(path7.delimiter).filter(Boolean);
36222
+ const pathEntries = (process.env.PATH ?? "").split(path8.delimiter).filter(Boolean);
35885
36223
  for (const entry of pathEntries) {
35886
- const shimPath = path7.join(entry, "codex.cmd");
35887
- if (!fs7.existsSync(shimPath)) continue;
35888
- const cliPath = path7.join(entry, "node_modules", "@openai", "codex", "bin", "codex.js");
35889
- if (fs7.existsSync(cliPath)) {
36224
+ const shimPath = path8.join(entry, "codex.cmd");
36225
+ if (!fs8.existsSync(shimPath)) continue;
36226
+ const cliPath = path8.join(entry, "node_modules", "@openai", "codex", "bin", "codex.js");
36227
+ if (fs8.existsSync(cliPath)) {
35890
36228
  return {
35891
36229
  command: process.execPath,
35892
36230
  argsPrefix: [cliPath]
@@ -36039,8 +36377,8 @@ var CodexLiteAdapter = class {
36039
36377
  };
36040
36378
 
36041
36379
  // ../../packages/core/src/agents/engines/claude-code-engine.ts
36042
- var fs8 = __toESM(require("fs"), 1);
36043
- var path8 = __toESM(require("path"), 1);
36380
+ var fs9 = __toESM(require("fs"), 1);
36381
+ var path9 = __toESM(require("path"), 1);
36044
36382
  var import_node_child_process4 = require("child_process");
36045
36383
  var DEFAULT_CLAUDE_MODEL = "sonnet";
36046
36384
  function buildClaudeModeArgs(mode) {
@@ -36077,7 +36415,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
36077
36415
  if (task.agent !== "claudecode") continue;
36078
36416
  const sessionId = task.payload.sessionId;
36079
36417
  if (!sessionId) continue;
36080
- const cwd = path8.resolve(
36418
+ const cwd = path9.resolve(
36081
36419
  task.payload.sessionCwd ?? task.effectiveProjectPath ?? task.project ?? process.cwd()
36082
36420
  );
36083
36421
  this.sessions.set(task.id, { sessionId, cwd, title: task.title });
@@ -36204,6 +36542,13 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
36204
36542
  session = recovered;
36205
36543
  }
36206
36544
  }
36545
+ if (!session) {
36546
+ const persisted = this.recoverPersistedSession(taskId);
36547
+ if (persisted) {
36548
+ this.sessions.set(taskId, persisted);
36549
+ session = persisted;
36550
+ }
36551
+ }
36207
36552
  if (!session) {
36208
36553
  throw new MeshyError("TASK_NOT_FOUND", `No active session for task ${taskId}`, 404);
36209
36554
  }
@@ -36337,8 +36682,8 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
36337
36682
  /** Recover a session by scanning the JSONL log file for the last system.init event. */
36338
36683
  recoverSession(taskId) {
36339
36684
  const logPath = this.getLogPath(taskId);
36340
- if (!fs8.existsSync(logPath)) return null;
36341
- const content = fs8.readFileSync(logPath, "utf-8").trim();
36685
+ if (!fs9.existsSync(logPath)) return null;
36686
+ const content = fs9.readFileSync(logPath, "utf-8").trim();
36342
36687
  if (!content) return null;
36343
36688
  const lines = content.split("\n");
36344
36689
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -36351,7 +36696,7 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
36351
36696
  const persistedCwd = typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0;
36352
36697
  return {
36353
36698
  sessionId: event.session_id,
36354
- cwd: path8.resolve(
36699
+ cwd: path9.resolve(
36355
36700
  (typeof event.cwd === "string" ? event.cwd : persistedCwd) ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()
36356
36701
  ),
36357
36702
  title: task?.title ?? taskId
@@ -36362,11 +36707,25 @@ var ClaudeCodeEngine = class extends ExecutionEngine {
36362
36707
  }
36363
36708
  return null;
36364
36709
  }
36710
+ recoverPersistedSession(taskId) {
36711
+ const task = this.taskEngine.getTask(taskId);
36712
+ const sessionId = typeof task?.payload.sessionId === "string" ? task.payload.sessionId : void 0;
36713
+ if (!sessionId) {
36714
+ return null;
36715
+ }
36716
+ return {
36717
+ sessionId,
36718
+ cwd: path9.resolve(
36719
+ (typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0) ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()
36720
+ ),
36721
+ title: task?.title ?? taskId
36722
+ };
36723
+ }
36365
36724
  };
36366
36725
 
36367
36726
  // ../../packages/core/src/agents/engines/codex-engine.ts
36368
- var fs9 = __toESM(require("fs"), 1);
36369
- var path9 = __toESM(require("path"), 1);
36727
+ var fs10 = __toESM(require("fs"), 1);
36728
+ var path10 = __toESM(require("path"), 1);
36370
36729
  var import_node_child_process5 = require("child_process");
36371
36730
  function buildAssistantEvent(text, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
36372
36731
  return {
@@ -36378,7 +36737,7 @@ function buildAssistantEvent(text, timestamp = (/* @__PURE__ */ new Date()).toIS
36378
36737
  timestamp
36379
36738
  };
36380
36739
  }
36381
- function buildAssistantThinkingEvent(thinking, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
36740
+ function buildAssistantThinkingEvent2(thinking, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
36382
36741
  return {
36383
36742
  type: "assistant",
36384
36743
  message: {
@@ -36388,7 +36747,7 @@ function buildAssistantThinkingEvent(thinking, timestamp = (/* @__PURE__ */ new
36388
36747
  timestamp
36389
36748
  };
36390
36749
  }
36391
- function extractCodexReasoningText(item) {
36750
+ function extractCodexReasoningText2(item) {
36392
36751
  if (typeof item.text === "string") {
36393
36752
  return item.text.trim();
36394
36753
  }
@@ -36446,7 +36805,7 @@ var CodexEngine = class extends ExecutionEngine {
36446
36805
  if (task.agent !== "codex") continue;
36447
36806
  const sessionId = task.payload.sessionId;
36448
36807
  if (!sessionId) continue;
36449
- const cwd = path9.resolve(
36808
+ const cwd = path10.resolve(
36450
36809
  task.payload.sessionCwd ?? task.effectiveProjectPath ?? task.project ?? process.cwd()
36451
36810
  );
36452
36811
  this.sessions.set(task.id, { sessionId, cwd, title: task.title });
@@ -36481,6 +36840,13 @@ var CodexEngine = class extends ExecutionEngine {
36481
36840
  session = recovered;
36482
36841
  }
36483
36842
  }
36843
+ if (!session) {
36844
+ const persisted = this.recoverPersistedSession(taskId);
36845
+ if (persisted) {
36846
+ this.sessions.set(taskId, persisted);
36847
+ session = persisted;
36848
+ }
36849
+ }
36484
36850
  if (!session) {
36485
36851
  throw new MeshyError("TASK_NOT_FOUND", `No active session for task ${taskId}`, 404);
36486
36852
  }
@@ -36626,9 +36992,9 @@ var CodexEngine = class extends ExecutionEngine {
36626
36992
  return buildAssistantEvent(item.text);
36627
36993
  }
36628
36994
  if (item?.type === "reasoning" || item?.type === "agent_reasoning") {
36629
- const reasoning = extractCodexReasoningText(item);
36995
+ const reasoning = extractCodexReasoningText2(item);
36630
36996
  if (reasoning) {
36631
- return buildAssistantThinkingEvent(reasoning);
36997
+ return buildAssistantThinkingEvent2(reasoning);
36632
36998
  }
36633
36999
  }
36634
37000
  }
@@ -36640,13 +37006,13 @@ var CodexEngine = class extends ExecutionEngine {
36640
37006
  if (images.length === 0) {
36641
37007
  return { prompt, imagePaths: [] };
36642
37008
  }
36643
- const attachmentDir = path9.join(this.logDir, "attachments", taskId);
36644
- fs9.mkdirSync(attachmentDir, { recursive: true });
37009
+ const attachmentDir = path10.join(this.logDir, "attachments", taskId);
37010
+ fs10.mkdirSync(attachmentDir, { recursive: true });
36645
37011
  const imagePaths = images.map((image, index) => {
36646
37012
  const fallbackName = `image-${Date.now()}-${index}.${inferExtension(image.mediaType)}`;
36647
37013
  const filename = sanitizeFilename(image.filename ?? fallbackName);
36648
- const filePath = path9.join(attachmentDir, filename);
36649
- fs9.writeFileSync(filePath, Buffer.from(image.data, "base64"));
37014
+ const filePath = path10.join(attachmentDir, filename);
37015
+ fs10.writeFileSync(filePath, Buffer.from(image.data, "base64"));
36650
37016
  return filePath;
36651
37017
  });
36652
37018
  return { prompt, imagePaths };
@@ -36665,8 +37031,8 @@ var CodexEngine = class extends ExecutionEngine {
36665
37031
  /** Recover a session by scanning the JSONL log for the thread.started event. */
36666
37032
  recoverSession(taskId) {
36667
37033
  const logPath = this.getLogPath(taskId);
36668
- if (!fs9.existsSync(logPath)) return null;
36669
- const content = fs9.readFileSync(logPath, "utf-8").trim();
37034
+ if (!fs10.existsSync(logPath)) return null;
37035
+ const content = fs10.readFileSync(logPath, "utf-8").trim();
36670
37036
  if (!content) return null;
36671
37037
  const lines = content.split("\n");
36672
37038
  for (let i = lines.length - 1; i >= 0; i--) {
@@ -36679,7 +37045,7 @@ var CodexEngine = class extends ExecutionEngine {
36679
37045
  const persistedCwd = typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0;
36680
37046
  return {
36681
37047
  sessionId: event.thread_id,
36682
- cwd: path9.resolve(persistedCwd ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()),
37048
+ cwd: path10.resolve(persistedCwd ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()),
36683
37049
  title: task?.title ?? taskId
36684
37050
  };
36685
37051
  }
@@ -36688,11 +37054,25 @@ var CodexEngine = class extends ExecutionEngine {
36688
37054
  }
36689
37055
  return null;
36690
37056
  }
37057
+ recoverPersistedSession(taskId) {
37058
+ const task = this.taskEngine.getTask(taskId);
37059
+ const sessionId = typeof task?.payload.sessionId === "string" ? task.payload.sessionId : void 0;
37060
+ if (!sessionId) {
37061
+ return null;
37062
+ }
37063
+ return {
37064
+ sessionId,
37065
+ cwd: path10.resolve(
37066
+ (typeof task?.payload.sessionCwd === "string" ? task.payload.sessionCwd : void 0) ?? task?.effectiveProjectPath ?? task?.project ?? process.cwd()
37067
+ ),
37068
+ title: task?.title ?? taskId
37069
+ };
37070
+ }
36691
37071
  };
36692
37072
 
36693
37073
  // ../../packages/core/src/storage/storage-paths.ts
36694
- var os4 = __toESM(require("os"), 1);
36695
- var path10 = __toESM(require("path"), 1);
37074
+ var os5 = __toESM(require("os"), 1);
37075
+ var path11 = __toESM(require("path"), 1);
36696
37076
  function resolveDefaultStorageMode(options = {}) {
36697
37077
  const envMode = options.env?.MESHY_STORAGE_MODE;
36698
37078
  if (envMode === "cwd" || envMode === "home") {
@@ -36707,20 +37087,20 @@ function resolveDefaultStorageMode(options = {}) {
36707
37087
  function resolveDefaultStoragePath(options = {}) {
36708
37088
  const mode = resolveDefaultStorageMode(options);
36709
37089
  const envBaseDir = options.env?.MESHY_STORAGE_BASE_DIR;
36710
- const baseDir = mode === "cwd" ? envBaseDir ?? options.cwd ?? process.cwd() : options.homeDir ?? os4.homedir();
36711
- return path10.resolve(baseDir, ".meshy");
37090
+ const baseDir = mode === "cwd" ? envBaseDir ?? options.cwd ?? process.cwd() : options.homeDir ?? os5.homedir();
37091
+ return path11.resolve(baseDir, ".meshy");
36712
37092
  }
36713
37093
  function toSafeNodeStorageName(nodeName) {
36714
37094
  const safeName = nodeName.trim().replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
36715
37095
  return safeName.length > 0 ? safeName : "node";
36716
37096
  }
36717
37097
  function resolveNodeScopedStoragePath(storageRoot, nodeName) {
36718
- return path10.resolve(storageRoot, toSafeNodeStorageName(nodeName));
37098
+ return path11.resolve(storageRoot, toSafeNodeStorageName(nodeName));
36719
37099
  }
36720
37100
 
36721
37101
  // ../../packages/core/src/storage/storage-migration.ts
36722
- var fs10 = __toESM(require("fs"), 1);
36723
- var path11 = __toESM(require("path"), 1);
37102
+ var fs11 = __toESM(require("fs"), 1);
37103
+ var path12 = __toESM(require("path"), 1);
36724
37104
  var LEGACY_FILES = [
36725
37105
  "metadata.json",
36726
37106
  "cluster.json",
@@ -36731,33 +37111,33 @@ var LEGACY_FILES = [
36731
37111
  ];
36732
37112
  var LEGACY_DIRS = ["logs", "task-logs"];
36733
37113
  function migrateLegacyNodeStorage(options) {
36734
- const sourcePath = path11.resolve(options.storageRoot);
37114
+ const sourcePath = path12.resolve(options.storageRoot);
36735
37115
  if (normalizeString2(options.nodeName)) {
36736
37116
  return migrateIntoRequestedNode({ ...options, storageRoot: sourcePath, nodeName: normalizeString2(options.nodeName) });
36737
37117
  }
36738
37118
  return migrateByDiscoveredNodes({ ...options, storageRoot: sourcePath });
36739
37119
  }
36740
37120
  function migrateIntoRequestedNode(options) {
36741
- const sourcePath = path11.resolve(options.storageRoot);
37121
+ const sourcePath = path12.resolve(options.storageRoot);
36742
37122
  const targetPath = resolveNodeScopedStoragePath(sourcePath, options.nodeName);
36743
37123
  const moved = [];
36744
37124
  const skipped = [];
36745
37125
  const entries = collectLegacyEntries(sourcePath, options.nodeName);
36746
37126
  for (const entry of entries) {
36747
- const source = path11.join(sourcePath, entry.sourceName);
36748
- const target = path11.join(targetPath, entry.targetName);
36749
- if (!fs10.existsSync(source)) {
37127
+ const source = path12.join(sourcePath, entry.sourceName);
37128
+ const target = path12.join(targetPath, entry.targetName);
37129
+ if (!fs11.existsSync(source)) {
36750
37130
  continue;
36751
37131
  }
36752
- if (fs10.existsSync(target) && options.overwrite !== true) {
37132
+ if (fs11.existsSync(target) && options.overwrite !== true) {
36753
37133
  skipped.push(entry.targetName);
36754
37134
  continue;
36755
37135
  }
36756
- fs10.mkdirSync(path11.dirname(target), { recursive: true });
36757
- if (fs10.existsSync(target)) {
36758
- fs10.rmSync(target, { recursive: true, force: true });
37136
+ fs11.mkdirSync(path12.dirname(target), { recursive: true });
37137
+ if (fs11.existsSync(target)) {
37138
+ fs11.rmSync(target, { recursive: true, force: true });
36759
37139
  }
36760
- fs10.renameSync(source, target);
37140
+ fs11.renameSync(source, target);
36761
37141
  moved.push(entry.targetName);
36762
37142
  }
36763
37143
  return {
@@ -36772,16 +37152,16 @@ function migrateIntoRequestedNode(options) {
36772
37152
  };
36773
37153
  }
36774
37154
  function migrateByDiscoveredNodes(options) {
36775
- const sourcePath = path11.resolve(options.storageRoot);
37155
+ const sourcePath = path12.resolve(options.storageRoot);
36776
37156
  const moved = [];
36777
37157
  const skipped = [];
36778
37158
  const dropped = [];
36779
37159
  const targetNames = /* @__PURE__ */ new Set();
36780
37160
  const nodeIdToName = /* @__PURE__ */ new Map();
36781
- const nodes = readJsonRecord(path11.join(sourcePath, "nodes.json"));
37161
+ const nodes = readJsonRecord(path12.join(sourcePath, "nodes.json"));
36782
37162
  const nodesByName = /* @__PURE__ */ new Map();
36783
37163
  for (const [key, value] of Object.entries(nodes)) {
36784
- if (!isRecord2(value)) {
37164
+ if (!isRecord3(value)) {
36785
37165
  dropped.push(`node:${key}`);
36786
37166
  continue;
36787
37167
  }
@@ -36795,7 +37175,7 @@ function migrateByDiscoveredNodes(options) {
36795
37175
  nodeIdToName.set(nodeId, nodeName);
36796
37176
  nodesByName.set(nodeName, { ...nodesByName.get(nodeName) ?? {}, [nodeId]: value });
36797
37177
  }
36798
- const metadata = readJsonRecord(path11.join(sourcePath, "metadata.json"));
37178
+ const metadata = readJsonRecord(path12.join(sourcePath, "metadata.json"));
36799
37179
  const metadataNodeName = normalizeString2(metadata.defaultNodeName);
36800
37180
  if (metadataNodeName) {
36801
37181
  targetNames.add(metadataNodeName);
@@ -36825,7 +37205,7 @@ function migrateByDiscoveredNodes(options) {
36825
37205
  }
36826
37206
  moveScopedPath(
36827
37207
  identity.sourcePath,
36828
- path11.join(resolveNodeScopedStoragePath(sourcePath, identity.nodeName), "node-identity.json"),
37208
+ path12.join(resolveNodeScopedStoragePath(sourcePath, identity.nodeName), "node-identity.json"),
36829
37209
  `${identity.nodeName}/node-identity.json`,
36830
37210
  options.overwrite === true,
36831
37211
  moved,
@@ -36837,8 +37217,8 @@ function migrateByDiscoveredNodes(options) {
36837
37217
  migrateNodeScopedOrDrop(sourcePath, resolveElectionNodeName(sourcePath, nodeIdToName) ?? inferredSingleNodeName, "election.json", options.overwrite === true, moved, skipped, dropped);
36838
37218
  migrateNodeScopedOrDrop(sourcePath, inferredSingleNodeName, "cluster.json", options.overwrite === true, moved, skipped, dropped);
36839
37219
  migrateNodeScopedOrDrop(sourcePath, inferredSingleNodeName, "logs", options.overwrite === true, moved, skipped, dropped);
36840
- cleanupEmptyDir(path11.join(sourcePath, "task-logs"));
36841
- const targetNodeNames = [...targetNames].filter((nodeName) => fs10.existsSync(resolveNodeScopedStoragePath(sourcePath, nodeName))).sort();
37220
+ cleanupEmptyDir(path12.join(sourcePath, "task-logs"));
37221
+ const targetNodeNames = [...targetNames].filter((nodeName) => fs11.existsSync(resolveNodeScopedStoragePath(sourcePath, nodeName))).sort();
36842
37222
  const targetPaths = targetNodeNames.map((nodeName) => resolveNodeScopedStoragePath(sourcePath, nodeName));
36843
37223
  return {
36844
37224
  migrated: moved.length > 0 && skipped.length === 0,
@@ -36855,9 +37235,9 @@ function migrateTasksAndShares(sourcePath, nodeIdToName, targetNames, overwrite,
36855
37235
  const taskNodeNames = /* @__PURE__ */ new Set();
36856
37236
  const taskIdToNodeName = /* @__PURE__ */ new Map();
36857
37237
  const tasksByName = /* @__PURE__ */ new Map();
36858
- const tasks = readJsonRecord(path11.join(sourcePath, "tasks.json"));
37238
+ const tasks = readJsonRecord(path12.join(sourcePath, "tasks.json"));
36859
37239
  for (const [key, value] of Object.entries(tasks)) {
36860
- if (!isRecord2(value)) {
37240
+ if (!isRecord3(value)) {
36861
37241
  dropped.push(`task:${key}`);
36862
37242
  continue;
36863
37243
  }
@@ -36876,16 +37256,16 @@ function migrateTasksAndShares(sourcePath, nodeIdToName, targetNames, overwrite,
36876
37256
  for (const [nodeName, taskGroup] of tasksByName) {
36877
37257
  writeScopedJson(sourcePath, nodeName, "tasks.json", taskGroup, overwrite, moved, skipped);
36878
37258
  }
36879
- if (skipped.length === taskSkipStart && fs10.existsSync(path11.join(sourcePath, "tasks.json"))) {
37259
+ if (skipped.length === taskSkipStart && fs11.existsSync(path12.join(sourcePath, "tasks.json"))) {
36880
37260
  if (tasksByName.size === 0) {
36881
37261
  dropped.push("tasks.json");
36882
37262
  }
36883
- fs10.rmSync(path11.join(sourcePath, "tasks.json"), { force: true });
37263
+ fs11.rmSync(path12.join(sourcePath, "tasks.json"), { force: true });
36884
37264
  }
36885
37265
  const sharesByName = /* @__PURE__ */ new Map();
36886
- const shares = readJsonRecord(path11.join(sourcePath, "shares.json"));
37266
+ const shares = readJsonRecord(path12.join(sourcePath, "shares.json"));
36887
37267
  for (const [key, value] of Object.entries(shares)) {
36888
- if (!isRecord2(value)) {
37268
+ if (!isRecord3(value)) {
36889
37269
  dropped.push(`share:${key}`);
36890
37270
  continue;
36891
37271
  }
@@ -36912,22 +37292,22 @@ function migrateTasksAndShares(sourcePath, nodeIdToName, targetNames, overwrite,
36912
37292
  return taskNodeNames;
36913
37293
  }
36914
37294
  function migrateTaskLogs(sourcePath, taskIdToNodeName, overwrite, moved, skipped, dropped) {
36915
- const sourceDir = path11.join(sourcePath, "task-logs");
36916
- if (!fs10.existsSync(sourceDir)) return;
36917
- for (const fileName of fs10.readdirSync(sourceDir)) {
36918
- const source = path11.join(sourceDir, fileName);
36919
- const stat = fs10.statSync(source);
37295
+ const sourceDir = path12.join(sourcePath, "task-logs");
37296
+ if (!fs11.existsSync(sourceDir)) return;
37297
+ for (const fileName of fs11.readdirSync(sourceDir)) {
37298
+ const source = path12.join(sourceDir, fileName);
37299
+ const stat = fs11.statSync(source);
36920
37300
  if (!stat.isFile()) continue;
36921
37301
  const taskId = fileName.endsWith(".jsonl") ? fileName.slice(0, -".jsonl".length) : fileName;
36922
37302
  const nodeName = taskIdToNodeName.get(taskId);
36923
37303
  if (!nodeName) {
36924
- fs10.rmSync(source, { force: true });
37304
+ fs11.rmSync(source, { force: true });
36925
37305
  dropped.push(`task-log:${fileName}`);
36926
37306
  continue;
36927
37307
  }
36928
37308
  moveScopedPath(
36929
37309
  source,
36930
- path11.join(resolveNodeScopedStoragePath(sourcePath, nodeName), "task-logs", fileName),
37310
+ path12.join(resolveNodeScopedStoragePath(sourcePath, nodeName), "task-logs", fileName),
36931
37311
  `${nodeName}/task-logs/${fileName}`,
36932
37312
  overwrite,
36933
37313
  moved,
@@ -36936,8 +37316,8 @@ function migrateTaskLogs(sourcePath, taskIdToNodeName, overwrite, moved, skipped
36936
37316
  }
36937
37317
  }
36938
37318
  function migrateNodeScopedOrDrop(sourcePath, nodeName, sourceName, overwrite, moved, skipped, dropped) {
36939
- const source = path11.join(sourcePath, sourceName);
36940
- if (!fs10.existsSync(source)) return;
37319
+ const source = path12.join(sourcePath, sourceName);
37320
+ if (!fs11.existsSync(source)) return;
36941
37321
  if (!nodeName) {
36942
37322
  removeLegacyPath(source);
36943
37323
  dropped.push(sourceName);
@@ -36945,7 +37325,7 @@ function migrateNodeScopedOrDrop(sourcePath, nodeName, sourceName, overwrite, mo
36945
37325
  }
36946
37326
  moveScopedPath(
36947
37327
  source,
36948
- path11.join(resolveNodeScopedStoragePath(sourcePath, nodeName), sourceName),
37328
+ path12.join(resolveNodeScopedStoragePath(sourcePath, nodeName), sourceName),
36949
37329
  `${nodeName}/${sourceName}`,
36950
37330
  overwrite,
36951
37331
  moved,
@@ -36954,37 +37334,37 @@ function migrateNodeScopedOrDrop(sourcePath, nodeName, sourceName, overwrite, mo
36954
37334
  }
36955
37335
  function writeScopedJson(sourcePath, nodeName, fileName, value, overwrite, moved, skipped) {
36956
37336
  if (Object.keys(value).length === 0) return;
36957
- const target = path11.join(resolveNodeScopedStoragePath(sourcePath, nodeName), fileName);
37337
+ const target = path12.join(resolveNodeScopedStoragePath(sourcePath, nodeName), fileName);
36958
37338
  const label = `${nodeName}/${fileName}`;
36959
- if (fs10.existsSync(target) && !overwrite) {
37339
+ if (fs11.existsSync(target) && !overwrite) {
36960
37340
  skipped.push(label);
36961
37341
  return;
36962
37342
  }
36963
- fs10.mkdirSync(path11.dirname(target), { recursive: true });
36964
- fs10.writeFileSync(target, JSON.stringify(value, null, 2) + "\n", "utf-8");
37343
+ fs11.mkdirSync(path12.dirname(target), { recursive: true });
37344
+ fs11.writeFileSync(target, JSON.stringify(value, null, 2) + "\n", "utf-8");
36965
37345
  moved.push(label);
36966
37346
  }
36967
37347
  function moveScopedPath(source, target, label, overwrite, moved, skipped) {
36968
- if (!fs10.existsSync(source)) return;
36969
- if (fs10.existsSync(target) && !overwrite) {
37348
+ if (!fs11.existsSync(source)) return;
37349
+ if (fs11.existsSync(target) && !overwrite) {
36970
37350
  skipped.push(label);
36971
37351
  return;
36972
37352
  }
36973
- fs10.mkdirSync(path11.dirname(target), { recursive: true });
36974
- if (fs10.existsSync(target)) {
36975
- fs10.rmSync(target, { recursive: true, force: true });
37353
+ fs11.mkdirSync(path12.dirname(target), { recursive: true });
37354
+ if (fs11.existsSync(target)) {
37355
+ fs11.rmSync(target, { recursive: true, force: true });
36976
37356
  }
36977
- fs10.renameSync(source, target);
37357
+ fs11.renameSync(source, target);
36978
37358
  moved.push(label);
36979
37359
  }
36980
37360
  function collectIdentityEntries(storageRoot) {
36981
- if (!fs10.existsSync(storageRoot)) return [];
37361
+ if (!fs11.existsSync(storageRoot)) return [];
36982
37362
  const entries = [];
36983
- for (const sourceName of fs10.readdirSync(storageRoot)) {
37363
+ for (const sourceName of fs11.readdirSync(storageRoot)) {
36984
37364
  const match = /^node-identity-(.+)\.json$/.exec(sourceName);
36985
37365
  if (sourceName !== "node-identity.json" && !match) continue;
36986
- const sourcePath = path11.join(storageRoot, sourceName);
36987
- if (!fs10.statSync(sourcePath).isFile()) continue;
37366
+ const sourcePath = path12.join(storageRoot, sourceName);
37367
+ if (!fs11.statSync(sourcePath).isFile()) continue;
36988
37368
  const identity = readJsonRecord(sourcePath);
36989
37369
  const nodeName = normalizeString2(identity.name) ?? (match ? match[1] : void 0);
36990
37370
  entries.push({ sourceName, sourcePath, nodeName });
@@ -36992,27 +37372,27 @@ function collectIdentityEntries(storageRoot) {
36992
37372
  return entries;
36993
37373
  }
36994
37374
  function resolveElectionNodeName(sourcePath, nodeIdToName) {
36995
- const election = readJsonRecord(path11.join(sourcePath, "election.json"));
37375
+ const election = readJsonRecord(path12.join(sourcePath, "election.json"));
36996
37376
  const leaderId = normalizeString2(election.leaderId);
36997
37377
  return leaderId ? nodeIdToName.get(leaderId) : void 0;
36998
37378
  }
36999
37379
  function removeLegacyFile(sourcePath, fileName, dropped) {
37000
- const target = path11.join(sourcePath, fileName);
37001
- if (!fs10.existsSync(target)) return;
37002
- fs10.rmSync(target, { force: true });
37380
+ const target = path12.join(sourcePath, fileName);
37381
+ if (!fs11.existsSync(target)) return;
37382
+ fs11.rmSync(target, { force: true });
37003
37383
  if (fileName !== "nodes.json" && fileName !== "shares.json") {
37004
37384
  dropped.push(fileName);
37005
37385
  }
37006
37386
  }
37007
37387
  function cleanupEmptyDir(dirPath) {
37008
- if (!fs10.existsSync(dirPath)) return;
37009
- if (fs10.readdirSync(dirPath).length === 0) {
37010
- fs10.rmSync(dirPath, { recursive: true, force: true });
37388
+ if (!fs11.existsSync(dirPath)) return;
37389
+ if (fs11.readdirSync(dirPath).length === 0) {
37390
+ fs11.rmSync(dirPath, { recursive: true, force: true });
37011
37391
  }
37012
37392
  }
37013
37393
  function removeLegacyPath(targetPath) {
37014
- if (fs10.existsSync(targetPath)) {
37015
- fs10.rmSync(targetPath, { recursive: true, force: true });
37394
+ if (fs11.existsSync(targetPath)) {
37395
+ fs11.rmSync(targetPath, { recursive: true, force: true });
37016
37396
  }
37017
37397
  }
37018
37398
  function collectLegacyEntries(storageRoot, nodeName) {
@@ -37026,16 +37406,16 @@ function collectLegacyEntries(storageRoot, nodeName) {
37026
37406
  }
37027
37407
  const exactIdentity = `node-identity-${safeName}.json`;
37028
37408
  entries.push({ sourceName: exactIdentity, targetName: "node-identity.json" });
37029
- const legacyIdentity = path11.join(storageRoot, "node-identity.json");
37030
- if (fs10.existsSync(legacyIdentity)) {
37409
+ const legacyIdentity = path12.join(storageRoot, "node-identity.json");
37410
+ if (fs11.existsSync(legacyIdentity)) {
37031
37411
  entries.push({ sourceName: "node-identity.json", targetName: "node-identity.json" });
37032
37412
  }
37033
37413
  return entries;
37034
37414
  }
37035
37415
  function readJsonRecord(filePath) {
37036
37416
  try {
37037
- const parsed = JSON.parse(fs10.readFileSync(filePath, "utf-8"));
37038
- return isRecord2(parsed) ? parsed : {};
37417
+ const parsed = JSON.parse(fs11.readFileSync(filePath, "utf-8"));
37418
+ return isRecord3(parsed) ? parsed : {};
37039
37419
  } catch {
37040
37420
  return {};
37041
37421
  }
@@ -37045,12 +37425,12 @@ function normalizeString2(value) {
37045
37425
  const trimmed = value.trim();
37046
37426
  return trimmed.length > 0 ? trimmed : void 0;
37047
37427
  }
37048
- function isRecord2(value) {
37428
+ function isRecord3(value) {
37049
37429
  return typeof value === "object" && value !== null && !Array.isArray(value);
37050
37430
  }
37051
37431
 
37052
37432
  // ../../packages/core/src/node/node.ts
37053
- var path13 = __toESM(require("path"), 1);
37433
+ var path14 = __toESM(require("path"), 1);
37054
37434
 
37055
37435
  // ../../packages/core/src/messaging/node-local-message-handler.ts
37056
37436
  async function handleLocalNodeMessage(deps, message) {
@@ -37095,8 +37475,8 @@ async function handleLocalNodeMessage(deps, message) {
37095
37475
  }
37096
37476
 
37097
37477
  // ../../packages/core/src/node/node-identity.ts
37098
- var fs11 = __toESM(require("fs"), 1);
37099
- var path12 = __toESM(require("path"), 1);
37478
+ var fs12 = __toESM(require("fs"), 1);
37479
+ var path13 = __toESM(require("path"), 1);
37100
37480
 
37101
37481
  // ../../node_modules/.pnpm/nanoid@5.1.7/node_modules/nanoid/index.js
37102
37482
  var import_node_crypto6 = require("crypto");
@@ -37130,17 +37510,17 @@ function nanoid(size = 21) {
37130
37510
 
37131
37511
  // ../../packages/core/src/node/node-identity.ts
37132
37512
  function loadOrCreateNodeId(storagePath, nodeName) {
37133
- const identityPath = path12.join(storagePath, "node-identity.json");
37513
+ const identityPath = path13.join(storagePath, "node-identity.json");
37134
37514
  try {
37135
- if (fs11.existsSync(identityPath)) {
37136
- const raw = JSON.parse(fs11.readFileSync(identityPath, "utf-8"));
37515
+ if (fs12.existsSync(identityPath)) {
37516
+ const raw = JSON.parse(fs12.readFileSync(identityPath, "utf-8"));
37137
37517
  if (typeof raw.id === "string" && raw.id.length > 0) return raw.id;
37138
37518
  }
37139
37519
  } catch {
37140
37520
  }
37141
37521
  const id = nanoid();
37142
- fs11.mkdirSync(path12.dirname(identityPath), { recursive: true });
37143
- fs11.writeFileSync(identityPath, JSON.stringify({ id, name: nodeName }, null, 2) + "\n", "utf-8");
37522
+ fs12.mkdirSync(path13.dirname(identityPath), { recursive: true });
37523
+ fs12.writeFileSync(identityPath, JSON.stringify({ id, name: nodeName }, null, 2) + "\n", "utf-8");
37144
37524
  return id;
37145
37525
  }
37146
37526
 
@@ -37184,7 +37564,7 @@ var MeshyNode = class {
37184
37564
  await this.transport.start(this.config.node.port);
37185
37565
  const endpoint = await this.transport.getEndpoint();
37186
37566
  const now = Date.now();
37187
- const workDir = path13.resolve(this.config.node.workDir ?? process.cwd());
37567
+ const workDir = path14.resolve(this.config.node.workDir ?? process.cwd());
37188
37568
  this.selfInfo = {
37189
37569
  id: nodeId,
37190
37570
  name: this.config.node.name,
@@ -37214,7 +37594,7 @@ var MeshyNode = class {
37214
37594
  this.logger,
37215
37595
  this.getSettingsSnapshot
37216
37596
  );
37217
- const logDir = path13.join(this.config.storage.path, "task-logs");
37597
+ const logDir = path14.join(this.config.storage.path, "task-logs");
37218
37598
  this.taskEngine = new TaskEngine(this.store, this.nodeRegistry, this.eventBus, logDir);
37219
37599
  this.heartbeat.setGetAssignedTasks((nodeId2) => {
37220
37600
  const result = this.taskEngine.listTasks({ assignedTo: nodeId2, status: "assigned" });
@@ -37911,7 +38291,7 @@ async function apiFetch(ctx, port, apiPath) {
37911
38291
  const body = await res.json().catch(() => null);
37912
38292
  throw new Error(body?.error?.message ?? `API error: ${res.status} ${res.statusText}`);
37913
38293
  }
37914
- return res.json();
38294
+ return await res.json();
37915
38295
  }
37916
38296
  async function apiWrite(ctx, method, port, apiPath, body) {
37917
38297
  const res = await ctx.fetchImpl(`http://localhost:${port}${apiPath}`, {
@@ -37923,7 +38303,7 @@ async function apiWrite(ctx, method, port, apiPath, body) {
37923
38303
  const data = await res.json().catch(() => null);
37924
38304
  throw new Error(data?.error?.message ?? `HTTP ${res.status}`);
37925
38305
  }
37926
- return res.json();
38306
+ return await res.json();
37927
38307
  }
37928
38308
  function writeLines(stream, lines) {
37929
38309
  stream.write(`${lines.join("\n")}
@@ -38282,7 +38662,7 @@ function formatBanner(info) {
38282
38662
  }
38283
38663
 
38284
38664
  // src/bootstrap/process.ts
38285
- var fs12 = __toESM(require("fs"), 1);
38665
+ var fs13 = __toESM(require("fs"), 1);
38286
38666
  var nodePath = __toESM(require("path"), 1);
38287
38667
  var startupFatalLogPath;
38288
38668
  function getErrorMessage2(err) {
@@ -38307,8 +38687,8 @@ function writeStartupFatalError(err, logPath = startupFatalLogPath) {
38307
38687
  if (!logPath) {
38308
38688
  return void 0;
38309
38689
  }
38310
- fs12.mkdirSync(nodePath.dirname(logPath), { recursive: true });
38311
- fs12.appendFileSync(logPath, formatFatalErrorForLog(err), "utf-8");
38690
+ fs13.mkdirSync(nodePath.dirname(logPath), { recursive: true });
38691
+ fs13.appendFileSync(logPath, formatFatalErrorForLog(err), "utf-8");
38312
38692
  return logPath;
38313
38693
  }
38314
38694
  async function closeHttpServer(server, options = {}) {
@@ -38825,8 +39205,8 @@ function getErrorMap() {
38825
39205
 
38826
39206
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
38827
39207
  var makeIssue = (params) => {
38828
- const { data, path: path21, errorMaps, issueData } = params;
38829
- const fullPath = [...path21, ...issueData.path || []];
39208
+ const { data, path: path22, errorMaps, issueData } = params;
39209
+ const fullPath = [...path22, ...issueData.path || []];
38830
39210
  const fullIssue = {
38831
39211
  ...issueData,
38832
39212
  path: fullPath
@@ -38942,11 +39322,11 @@ var errorUtil;
38942
39322
 
38943
39323
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
38944
39324
  var ParseInputLazyPath = class {
38945
- constructor(parent, value, path21, key) {
39325
+ constructor(parent, value, path22, key) {
38946
39326
  this._cachedPath = [];
38947
39327
  this.parent = parent;
38948
39328
  this.data = value;
38949
- this._path = path21;
39329
+ this._path = path22;
38950
39330
  this._key = key;
38951
39331
  }
38952
39332
  get path() {
@@ -42451,7 +42831,15 @@ var SystemAgentInfoSchema = external_exports.object({
42451
42831
  version: external_exports.string().nullable(),
42452
42832
  checkedAt: external_exports.string(),
42453
42833
  detail: external_exports.string().nullable().optional(),
42454
- metadataStatus: external_exports.string().nullable().optional()
42834
+ metadataStatus: external_exports.string().nullable().optional(),
42835
+ update: external_exports.object({
42836
+ packageName: external_exports.string(),
42837
+ currentVersion: external_exports.string().nullable(),
42838
+ latestVersion: external_exports.string().nullable(),
42839
+ updateAvailable: external_exports.boolean(),
42840
+ checkedAt: external_exports.string(),
42841
+ detail: external_exports.string().nullable().optional()
42842
+ }).optional()
42455
42843
  });
42456
42844
  var NodeSettingsSnapshotSchema = external_exports.object({
42457
42845
  collectedAt: external_exports.number(),
@@ -42513,6 +42901,7 @@ var JoinTaskSchema = external_exports.object({
42513
42901
  agent: external_exports.string(),
42514
42902
  project: external_exports.string().nullable(),
42515
42903
  effectiveProjectPath: external_exports.string().nullable(),
42904
+ conversationKind: external_exports.enum(["meshyChat", "nativeSession"]).optional(),
42516
42905
  payload: external_exports.record(external_exports.unknown()),
42517
42906
  status: external_exports.enum(["pending", "assigned", "running", "completed", "failed", "cancelled", "archived"]),
42518
42907
  priority: external_exports.enum(["low", "normal", "high", "critical"]),
@@ -42611,6 +43000,13 @@ var GitRemoteBranchOptionSchema = external_exports.object({
42611
43000
  branch: external_exports.string(),
42612
43001
  ref: external_exports.string()
42613
43002
  });
43003
+ var NativeSessionSummarySchema = external_exports.object({
43004
+ agent: external_exports.enum(["codex", "claudecode"]),
43005
+ sessionId: external_exports.string(),
43006
+ cwd: external_exports.string(),
43007
+ summary: external_exports.string(),
43008
+ updatedAt: external_exports.string().nullable()
43009
+ });
42614
43010
  var NodeListQuery = external_exports.object({
42615
43011
  status: external_exports.enum(["online", "busy", "offline"]).optional(),
42616
43012
  capability: external_exports.string().optional()
@@ -42640,6 +43036,10 @@ var NodeWorkDirBranchQuery = external_exports.object({
42640
43036
  offset: external_exports.coerce.number().int().min(0).default(0),
42641
43037
  allowAbsolute: QueryBoolean
42642
43038
  });
43039
+ var NodeNativeSessionsQuery = external_exports.object({
43040
+ agent: external_exports.enum(["codex", "claudecode"]),
43041
+ limit: external_exports.coerce.number().int().min(1).max(100).default(50)
43042
+ });
42643
43043
  var NodeWorkDirTreeResponse = external_exports.object({
42644
43044
  nodeId: external_exports.string(),
42645
43045
  rootPath: external_exports.string(),
@@ -42676,6 +43076,11 @@ var CreateNodeWorkDirBranchBody = external_exports.object({
42676
43076
  var CreateNodeWorkDirBranchResponse = NodeWorkDirBranchResponse.extend({
42677
43077
  createdBranch: external_exports.string()
42678
43078
  });
43079
+ var NodeNativeSessionsResponse = external_exports.object({
43080
+ nodeId: external_exports.string(),
43081
+ agent: external_exports.enum(["codex", "claudecode"]),
43082
+ sessions: external_exports.array(NativeSessionSummarySchema)
43083
+ });
42679
43084
  var UpdateNodeBody = external_exports.object({
42680
43085
  name: external_exports.string().min(1).optional(),
42681
43086
  capabilities: external_exports.array(external_exports.string()).optional()
@@ -42683,7 +43088,9 @@ var UpdateNodeBody = external_exports.object({
42683
43088
 
42684
43089
  // ../../packages/api/src/schemas/tasks.ts
42685
43090
  var AGENT_OPTIONS = ["mars", "codex", "claudecode", "eureka"];
43091
+ var NATIVE_SESSION_AGENT_OPTIONS = ["codex", "claudecode"];
42686
43092
  var TASK_MODE_OPTIONS = ["bypass", "plan", "edit", "dangerous"];
43093
+ var TASK_CONVERSATION_KIND_OPTIONS = ["meshyChat", "nativeSession"];
42687
43094
  var TaskPayload = external_exports.record(external_exports.unknown()).superRefine((payload, ctx) => {
42688
43095
  const mode = payload.mode;
42689
43096
  if (mode !== void 0 && !TASK_MODE_OPTIONS.includes(mode)) {
@@ -42720,6 +43127,7 @@ var TaskListResponse = external_exports.object({
42720
43127
  project: external_exports.string().nullable(),
42721
43128
  effectiveProjectPath: external_exports.string().nullable(),
42722
43129
  branch: external_exports.string().nullable().optional(),
43130
+ conversationKind: external_exports.enum(TASK_CONVERSATION_KIND_OPTIONS).optional(),
42723
43131
  payload: external_exports.record(external_exports.unknown()),
42724
43132
  status: external_exports.enum(["pending", "assigned", "running", "completed", "failed", "cancelled", "archived"]),
42725
43133
  priority: external_exports.enum(["low", "normal", "high", "critical"]),
@@ -42750,6 +43158,7 @@ var AssignTaskBody = external_exports.object({
42750
43158
  nodeId: external_exports.string().min(1)
42751
43159
  });
42752
43160
  var TaskResponse = TaskListResponse.shape.tasks.element;
43161
+ var TaskLogEvent = external_exports.record(external_exports.unknown());
42753
43162
  var TaskMessageTextPart = external_exports.object({
42754
43163
  type: external_exports.literal("text"),
42755
43164
  text: external_exports.string().trim().min(1)
@@ -42782,6 +43191,19 @@ var SendMessageBody = external_exports.union([
42782
43191
  content: [{ type: "text", text: value.message }]
42783
43192
  }))
42784
43193
  ]);
43194
+ var AttachNativeSessionBody = external_exports.object({
43195
+ title: external_exports.string().trim().min(1).max(120).optional(),
43196
+ agent: external_exports.enum(NATIVE_SESSION_AGENT_OPTIONS),
43197
+ sessionId: external_exports.string().trim().min(1),
43198
+ cwd: external_exports.string().trim().min(1),
43199
+ assignTo: external_exports.string().min(1).optional(),
43200
+ priority: external_exports.enum(["low", "normal", "high", "critical"]).default("normal"),
43201
+ mode: external_exports.enum(TASK_MODE_OPTIONS).optional()
43202
+ });
43203
+ var WorkerImportTaskBody = external_exports.object({
43204
+ task: TaskResponse,
43205
+ logs: external_exports.array(TaskLogEvent).default([])
43206
+ });
42785
43207
  var TaskLogsQuery = external_exports.object({
42786
43208
  after: external_exports.coerce.number().int().min(0).optional()
42787
43209
  });
@@ -42804,9 +43226,9 @@ var BatchTaskIdsBody = external_exports.object({
42804
43226
  });
42805
43227
 
42806
43228
  // ../../packages/api/src/app/server.ts
42807
- var path18 = __toESM(require("path"), 1);
42808
- var fs17 = __toESM(require("fs"), 1);
42809
- var import_express12 = __toESM(require_express2(), 1);
43229
+ var path19 = __toESM(require("path"), 1);
43230
+ var fs18 = __toESM(require("fs"), 1);
43231
+ var import_express13 = __toESM(require_express2(), 1);
42810
43232
 
42811
43233
  // ../../packages/api/src/middleware/auth.ts
42812
43234
  var SKIP_AUTH_PATHS = ["/api/system/health"];
@@ -43231,7 +43653,7 @@ function createClusterControlRoutes() {
43231
43653
  }
43232
43654
 
43233
43655
  // ../../packages/api/src/routes/nodes.ts
43234
- var import_express4 = __toESM(require_express2(), 1);
43656
+ var import_express5 = __toESM(require_express2(), 1);
43235
43657
 
43236
43658
  // ../../packages/api/src/node/devtunnel-guard.ts
43237
43659
  var BLOCKING_TASK_STATUSES = /* @__PURE__ */ new Set(["assigned", "running"]);
@@ -43257,11 +43679,11 @@ function assertCanChangeNodeDevTunnel(taskEngine, nodeId) {
43257
43679
  var import_express3 = __toESM(require_express2(), 1);
43258
43680
 
43259
43681
  // ../../packages/api/src/node/node-workdir-service.ts
43260
- var path15 = __toESM(require("path"), 1);
43682
+ var path16 = __toESM(require("path"), 1);
43261
43683
 
43262
43684
  // ../../packages/api/src/output/helpers.ts
43263
- var fs13 = __toESM(require("fs"), 1);
43264
- var path14 = __toESM(require("path"), 1);
43685
+ var fs14 = __toESM(require("fs"), 1);
43686
+ var path15 = __toESM(require("path"), 1);
43265
43687
  var MAX_INLINE_SIZE = 512 * 1024;
43266
43688
  var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
43267
43689
  ".txt",
@@ -43374,15 +43796,15 @@ function mimeForExt(ext) {
43374
43796
  return MIME_MAP[ext] ?? "application/octet-stream";
43375
43797
  }
43376
43798
  function resolveOutputPath(root, relativePath) {
43377
- const resolved = path14.resolve(root, relativePath);
43378
- const normalizedRoot = path14.resolve(root);
43379
- if (!resolved.startsWith(normalizedRoot + path14.sep) && resolved !== normalizedRoot) {
43799
+ const resolved = path15.resolve(root, relativePath);
43800
+ const normalizedRoot = path15.resolve(root);
43801
+ if (!resolved.startsWith(normalizedRoot + path15.sep) && resolved !== normalizedRoot) {
43380
43802
  throw new Error("Path traversal detected");
43381
43803
  }
43382
43804
  return resolved;
43383
43805
  }
43384
43806
  function classifyFile(filePath) {
43385
- const ext = path14.extname(filePath).toLowerCase();
43807
+ const ext = path15.extname(filePath).toLowerCase();
43386
43808
  if (ext === ".json" || ext === ".jsonl" || ext === ".ndjson") {
43387
43809
  return { kind: "json", mimeType: "application/json" };
43388
43810
  }
@@ -43412,21 +43834,21 @@ function listDirectory(root, relativePath, options = {}) {
43412
43834
  return listResolvedDirectory(absPath, relativePath, options);
43413
43835
  }
43414
43836
  function listAbsoluteDirectory(absoluteDir, options = {}) {
43415
- if (!path14.isAbsolute(absoluteDir)) {
43837
+ if (!path15.isAbsolute(absoluteDir)) {
43416
43838
  throw new Error("listAbsoluteDirectory requires an absolute path");
43417
43839
  }
43418
43840
  return listResolvedDirectory(absoluteDir, absoluteDir, { ...options, childPathStyle: "absolute" });
43419
43841
  }
43420
43842
  function listResolvedDirectory(absPath, relativeBase, options = {}) {
43421
- if (!fs13.existsSync(absPath) || !fs13.statSync(absPath).isDirectory()) {
43843
+ if (!fs14.existsSync(absPath) || !fs14.statSync(absPath).isDirectory()) {
43422
43844
  return [];
43423
43845
  }
43424
- const entries = fs13.readdirSync(absPath, { withFileTypes: true });
43846
+ const entries = fs14.readdirSync(absPath, { withFileTypes: true });
43425
43847
  const result = [];
43426
43848
  const childPathStyle = options.childPathStyle ?? "relative";
43427
43849
  for (const entry of entries) {
43428
43850
  if (entry.name.startsWith(".")) continue;
43429
- const entryRelPath = childPathStyle === "absolute" ? path14.join(absPath, entry.name) : path14.join(relativeBase || ".", entry.name).split(path14.sep).join("/");
43851
+ const entryRelPath = childPathStyle === "absolute" ? path15.join(absPath, entry.name) : path15.join(relativeBase || ".", entry.name).split(path15.sep).join("/");
43430
43852
  if (entry.isDirectory()) {
43431
43853
  result.push({
43432
43854
  path: entryRelPath,
@@ -43436,8 +43858,8 @@ function listResolvedDirectory(absPath, relativeBase, options = {}) {
43436
43858
  } else if (options.directoriesOnly) {
43437
43859
  continue;
43438
43860
  } else if (entry.isFile()) {
43439
- const fullPath = path14.join(absPath, entry.name);
43440
- const stat = fs13.statSync(fullPath);
43861
+ const fullPath = path15.join(absPath, entry.name);
43862
+ const stat = fs14.statSync(fullPath);
43441
43863
  const { kind, mimeType } = classifyFile(entry.name);
43442
43864
  result.push({
43443
43865
  path: entryRelPath,
@@ -43457,11 +43879,11 @@ function listResolvedDirectory(absPath, relativeBase, options = {}) {
43457
43879
  }
43458
43880
  function detectHtmlEntries(root) {
43459
43881
  const entries = [];
43460
- if (fs13.existsSync(path14.join(root, "index.html"))) {
43882
+ if (fs14.existsSync(path15.join(root, "index.html"))) {
43461
43883
  entries.push({ path: "index.html", label: "index.html" });
43462
43884
  }
43463
43885
  try {
43464
- const topLevel = fs13.readdirSync(root, { withFileTypes: true });
43886
+ const topLevel = fs14.readdirSync(root, { withFileTypes: true });
43465
43887
  const htmlFiles = topLevel.filter(
43466
43888
  (e) => e.isFile() && e.name.endsWith(".html") && !e.name.startsWith(".")
43467
43889
  );
@@ -43472,8 +43894,8 @@ function detectHtmlEntries(root) {
43472
43894
  }
43473
43895
  const subdirs = topLevel.filter((e) => e.isDirectory() && !e.name.startsWith("."));
43474
43896
  for (const dir of subdirs) {
43475
- const subIndex = path14.join(root, dir.name, "index.html");
43476
- if (fs13.existsSync(subIndex)) {
43897
+ const subIndex = path15.join(root, dir.name, "index.html");
43898
+ if (fs14.existsSync(subIndex)) {
43477
43899
  entries.push({
43478
43900
  path: `${dir.name}/index.html`,
43479
43901
  label: `${dir.name}/index.html`
@@ -43485,11 +43907,11 @@ function detectHtmlEntries(root) {
43485
43907
  return entries;
43486
43908
  }
43487
43909
  function getOutputSummary(root) {
43488
- const rootName = path14.basename(root);
43910
+ const rootName = path15.basename(root);
43489
43911
  const htmlEntries = detectHtmlEntries(root);
43490
43912
  let fileCount;
43491
43913
  try {
43492
- const entries = fs13.readdirSync(root, { withFileTypes: true });
43914
+ const entries = fs14.readdirSync(root, { withFileTypes: true });
43493
43915
  fileCount = entries.filter((e) => !e.name.startsWith(".")).length;
43494
43916
  } catch {
43495
43917
  fileCount = void 0;
@@ -43505,14 +43927,14 @@ function getOutputSummary(root) {
43505
43927
  }
43506
43928
  function readFileContent(root, relativePath) {
43507
43929
  const absPath = resolveOutputPath(root, relativePath);
43508
- if (!fs13.existsSync(absPath) || !fs13.statSync(absPath).isFile()) {
43930
+ if (!fs14.existsSync(absPath) || !fs14.statSync(absPath).isFile()) {
43509
43931
  throw new Error("File not found");
43510
43932
  }
43511
- const stat = fs13.statSync(absPath);
43933
+ const stat = fs14.statSync(absPath);
43512
43934
  const { kind, mimeType } = classifyFile(absPath);
43513
43935
  if (kind === "image" || kind === "pdf" || kind === "binary") {
43514
43936
  const truncated2 = stat.size > MAX_INLINE_SIZE;
43515
- const buffer = truncated2 ? Buffer.alloc(0) : fs13.readFileSync(absPath);
43937
+ const buffer = truncated2 ? Buffer.alloc(0) : fs14.readFileSync(absPath);
43516
43938
  return {
43517
43939
  path: relativePath,
43518
43940
  kind,
@@ -43523,7 +43945,7 @@ function readFileContent(root, relativePath) {
43523
43945
  };
43524
43946
  }
43525
43947
  const truncated = stat.size > MAX_INLINE_SIZE;
43526
- const content = truncated ? fs13.readFileSync(absPath, "utf-8").slice(0, MAX_INLINE_SIZE) : fs13.readFileSync(absPath, "utf-8");
43948
+ const content = truncated ? fs14.readFileSync(absPath, "utf-8").slice(0, MAX_INLINE_SIZE) : fs14.readFileSync(absPath, "utf-8");
43527
43949
  return {
43528
43950
  path: relativePath,
43529
43951
  kind,
@@ -43742,7 +44164,7 @@ function getGitDiff(dirPath) {
43742
44164
  const branch = git2(["rev-parse", "--abbrev-ref", "HEAD"], dirPath) || null;
43743
44165
  const staged = git2(["diff", "--cached"], dirPath);
43744
44166
  const unstaged = git2(["diff"], dirPath);
43745
- const statusOutput = git2(["status", "--porcelain"], dirPath);
44167
+ const statusOutput = git2(["status", "--porcelain", "-uall"], dirPath);
43746
44168
  const changedFiles = [];
43747
44169
  const untrackedFiles = [];
43748
44170
  for (const line of statusOutput.split("\n")) {
@@ -43768,14 +44190,14 @@ function getGitDiff(dirPath) {
43768
44190
 
43769
44191
  // ../../packages/api/src/node/node-workdir-service.ts
43770
44192
  function isAbsolutePath(p) {
43771
- return path15.isAbsolute(p) || /^[A-Za-z]:[\\/]/.test(p);
44193
+ return path16.isAbsolute(p) || /^[A-Za-z]:[\\/]/.test(p);
43772
44194
  }
43773
44195
  function resolveNodeWorkDirTarget(nodeId, rootPath, currentPath, allowAbsolute) {
43774
44196
  if (!rootPath) {
43775
44197
  throw new MeshyError("VALIDATION_ERROR", `Node ${nodeId} does not expose a working directory`, 400);
43776
44198
  }
43777
44199
  const useAbsolute = allowAbsolute && isAbsolutePath(currentPath);
43778
- const resolvedPath = useAbsolute ? path15.resolve(currentPath) : currentPath;
44200
+ const resolvedPath = useAbsolute ? path16.resolve(currentPath) : currentPath;
43779
44201
  return {
43780
44202
  rootPath,
43781
44203
  resolvedPath,
@@ -43860,13 +44282,13 @@ function createLocalNodeWorkDirBranch(nodeId, rootPath, currentPath, options) {
43860
44282
  }
43861
44283
  function computeParentPath(rootPath, currentPath, useAbsolute) {
43862
44284
  if (useAbsolute) {
43863
- const parent = path15.dirname(currentPath);
44285
+ const parent = path16.dirname(currentPath);
43864
44286
  return parent === currentPath ? null : parent;
43865
44287
  }
43866
44288
  const normalized = currentPath.replace(/\\/g, "/").replace(/\/+$/, "");
43867
44289
  if (normalized === "" || normalized === ".") {
43868
- const absParent = path15.dirname(path15.resolve(rootPath));
43869
- return absParent === path15.resolve(rootPath) ? null : absParent;
44290
+ const absParent = path16.dirname(path16.resolve(rootPath));
44291
+ return absParent === path16.resolve(rootPath) ? null : absParent;
43870
44292
  }
43871
44293
  const segments = normalized.split("/").filter(Boolean);
43872
44294
  segments.pop();
@@ -43966,7 +44388,44 @@ function sendLocalNodeWorkDirBranchCreate(req, res, nodeId, options = {}) {
43966
44388
  }
43967
44389
 
43968
44390
  // ../../packages/api/src/tasks/task-route-utils.ts
43969
- var fs14 = __toESM(require("fs"), 1);
44391
+ var fs15 = __toESM(require("fs"), 1);
44392
+
44393
+ // ../../packages/api/src/node/node-message-compat.ts
44394
+ var LEGACY_KIND_BY_NODE_MESSAGE = {
44395
+ "node.workdir.tree": "node-workdir-tree",
44396
+ "node.workdir.branch-info": "node-workdir-branch-info",
44397
+ "node.workdir.branch-create": "node-workdir-branch-create",
44398
+ "node.sessions.list": "node-sessions-list",
44399
+ "node.transport.set": "devtunnel",
44400
+ "node.agent.upgrade": "node-agent-upgrade",
44401
+ "task.cancel": "task-cancel",
44402
+ "task.logs": "task-logs",
44403
+ "task.output.summary": "task-output-summary",
44404
+ "task.output.tree": "task-output-tree",
44405
+ "task.output.content": "task-output-content",
44406
+ "task.output.download": "task-output-download",
44407
+ "task.output.diff": "task-output-diff",
44408
+ "task.preview.create": "task-preview-session"
44409
+ };
44410
+ function canRequestNodeMessage(heartbeat) {
44411
+ return !!(heartbeat?.requestNodeMessage || heartbeat?.requestWorkerControl);
44412
+ }
44413
+ function requestFallbackNodeMessage(heartbeat, nodeId, message) {
44414
+ if (heartbeat.requestNodeMessage) return heartbeat.requestNodeMessage(nodeId, message);
44415
+ if (heartbeat.requestWorkerControl) return heartbeat.requestWorkerControl(nodeId, toLegacyWorkerControl2(message));
44416
+ throw new Error("Node message fallback is not available");
44417
+ }
44418
+ function toLegacyWorkerControl2(message) {
44419
+ return {
44420
+ ...typeof message.payload === "object" && message.payload !== null ? message.payload : {},
44421
+ kind: LEGACY_KIND_BY_NODE_MESSAGE[message.kind] ?? message.kind
44422
+ };
44423
+ }
44424
+
44425
+ // ../../packages/api/src/tasks/task-route-utils.ts
44426
+ function isRecord4(value) {
44427
+ return typeof value === "object" && value !== null;
44428
+ }
43970
44429
  function restoreTaskState(taskEngine, task) {
43971
44430
  taskEngine.updateTask(task.id, {
43972
44431
  status: task.status,
@@ -43981,10 +44440,10 @@ function readLocalTaskLogs(engineRegistry, taskId, after, agent) {
43981
44440
  throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${agent}`, 400);
43982
44441
  }
43983
44442
  const logPath = engine.getLogPath(taskId);
43984
- if (!fs14.existsSync(logPath)) {
44443
+ if (!fs15.existsSync(logPath)) {
43985
44444
  return { logs: [], total: 0 };
43986
44445
  }
43987
- const content = fs14.readFileSync(logPath, "utf-8");
44446
+ const content = fs15.readFileSync(logPath, "utf-8");
43988
44447
  const allLines = content.trim().split("\n").filter(Boolean);
43989
44448
  const logs = [];
43990
44449
  for (let i = after; i < allLines.length; i++) {
@@ -43995,6 +44454,169 @@ function readLocalTaskLogs(engineRegistry, taskId, after, agent) {
43995
44454
  }
43996
44455
  return { logs, total: allLines.length };
43997
44456
  }
44457
+ function recordLocalTaskLogs(engineRegistry, task, logs) {
44458
+ if (logs.length === 0) {
44459
+ return;
44460
+ }
44461
+ const engine = engineRegistry.get(task.agent);
44462
+ if (!engine) {
44463
+ throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${task.agent}`, 400);
44464
+ }
44465
+ for (const event of logs) {
44466
+ engine.recordOutput(task.id, event);
44467
+ }
44468
+ }
44469
+ function parseEventTimestamp(event) {
44470
+ if (typeof event.timestamp !== "string") {
44471
+ return null;
44472
+ }
44473
+ const parsed = Date.parse(event.timestamp);
44474
+ return Number.isNaN(parsed) ? null : parsed;
44475
+ }
44476
+ function getTaskUserMessageSignature(value) {
44477
+ const content = normalizeTaskUserMessageContent(value);
44478
+ if (content.length === 0) {
44479
+ return null;
44480
+ }
44481
+ return content.map((part) => {
44482
+ if (part.type === "text") return `t:${part.text}`;
44483
+ if (part.type === "tool_result") return `r:${part.toolUseId}:${part.isError === true ? "1" : "0"}:${part.content}`;
44484
+ const dataStart = part.data.slice(0, 32);
44485
+ const dataEnd = part.data.slice(-32);
44486
+ return `i:${part.mediaType}:${part.data.length}:${dataStart}:${dataEnd}`;
44487
+ }).join("|");
44488
+ }
44489
+ function normalizeStructuredValue(value) {
44490
+ if (Array.isArray(value)) {
44491
+ return value.map((entry) => normalizeStructuredValue(entry));
44492
+ }
44493
+ if (!isRecord4(value)) {
44494
+ return value;
44495
+ }
44496
+ return Object.fromEntries(
44497
+ Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey)).map(([key, entryValue]) => [key, normalizeStructuredValue(entryValue)])
44498
+ );
44499
+ }
44500
+ function getTranscriptEventSignature(event) {
44501
+ if (event.type === "user") {
44502
+ const signature = getTaskUserMessageSignature(isRecord4(event.message) ? event.message.content : event.message) ?? getTaskUserMessageSignature(event.content);
44503
+ return signature ? `user:${signature}` : null;
44504
+ }
44505
+ if (event.type === "assistant") {
44506
+ if (typeof event.message === "string") {
44507
+ return `assistant:${JSON.stringify(event.message)}`;
44508
+ }
44509
+ if (isRecord4(event.message) && "content" in event.message) {
44510
+ return `assistant:${JSON.stringify(normalizeStructuredValue(event.message.content))}`;
44511
+ }
44512
+ if (Array.isArray(event.content)) {
44513
+ return `assistant:${JSON.stringify(normalizeStructuredValue(event.content))}`;
44514
+ }
44515
+ if (isRecord4(event.message)) {
44516
+ return `assistant:${JSON.stringify(normalizeStructuredValue(event.message))}`;
44517
+ }
44518
+ }
44519
+ return null;
44520
+ }
44521
+ function sortLogsChronologically(events) {
44522
+ return events.map((event, index) => ({ event, index })).sort((left, right) => {
44523
+ const leftTimestamp = parseEventTimestamp(left.event);
44524
+ const rightTimestamp = parseEventTimestamp(right.event);
44525
+ if (leftTimestamp !== null && rightTimestamp !== null && leftTimestamp !== rightTimestamp) {
44526
+ return leftTimestamp - rightTimestamp;
44527
+ }
44528
+ return left.index - right.index;
44529
+ }).map((entry) => entry.event);
44530
+ }
44531
+ function timestampsMatch(left, right) {
44532
+ const leftTimestamp = parseEventTimestamp(left);
44533
+ const rightTimestamp = parseEventTimestamp(right);
44534
+ if (leftTimestamp === null || rightTimestamp === null) {
44535
+ return true;
44536
+ }
44537
+ return Math.abs(leftTimestamp - rightTimestamp) <= 6e4;
44538
+ }
44539
+ function transcriptEvents(events) {
44540
+ return events.flatMap((event, index) => {
44541
+ const signature = getTranscriptEventSignature(event);
44542
+ return signature ? [{ index, event, signature }] : [];
44543
+ });
44544
+ }
44545
+ function findLocalTranscriptDuplicates(nativeLogs, localLogs) {
44546
+ const nativeTranscript = transcriptEvents(nativeLogs);
44547
+ const localTranscript = transcriptEvents(localLogs);
44548
+ if (nativeTranscript.length === 0 || localTranscript.length === 0) {
44549
+ return /* @__PURE__ */ new Set();
44550
+ }
44551
+ const duplicates = /* @__PURE__ */ new Set();
44552
+ for (const localEvent of localTranscript) {
44553
+ if (nativeTranscript.some((nativeEvent) => nativeEvent.signature === localEvent.signature && timestampsMatch(nativeEvent.event, localEvent.event))) {
44554
+ duplicates.add(localEvent.index);
44555
+ }
44556
+ }
44557
+ return duplicates;
44558
+ }
44559
+ function mergeNativeSessionLogs(nativeLogs, localLogs) {
44560
+ if (localLogs.length === 0) {
44561
+ return nativeLogs;
44562
+ }
44563
+ const duplicateLocalIndexes = findLocalTranscriptDuplicates(nativeLogs, localLogs);
44564
+ const retainedLocalLogs = localLogs.filter((_, index) => !duplicateLocalIndexes.has(index));
44565
+ if (retainedLocalLogs.length === 0) {
44566
+ return nativeLogs;
44567
+ }
44568
+ return sortLogsChronologically([...nativeLogs, ...retainedLocalLogs]);
44569
+ }
44570
+ function readLocalTaskLogsWithNativeHistory(engineRegistry, task, taskId, after, agent) {
44571
+ const local = readLocalTaskLogs(engineRegistry, taskId, after, agent);
44572
+ const sessionId = typeof task?.payload?.sessionId === "string" ? task.payload.sessionId : "";
44573
+ if (after > 0 || task?.conversationKind !== "nativeSession" || !sessionId || task.agent !== "codex" && task.agent !== "claudecode") {
44574
+ return local;
44575
+ }
44576
+ const history = loadNativeSessionHistory({ agent: task.agent, sessionId });
44577
+ if (history.logs.length === 0) {
44578
+ return local;
44579
+ }
44580
+ if (local.total > 0) {
44581
+ const logs = mergeNativeSessionLogs(history.logs, local.logs);
44582
+ return { logs, total: logs.length };
44583
+ }
44584
+ recordLocalTaskLogs(engineRegistry, task, history.logs);
44585
+ return readLocalTaskLogs(engineRegistry, taskId, after, agent);
44586
+ }
44587
+ async function seedTaskSnapshotOnWorker(task, logs, node, log2, timeoutMs = 1e4) {
44588
+ const proxyPath = "/api/worker/import-task";
44589
+ const { endpoint, response } = await fetchNodeWithFallback(
44590
+ node,
44591
+ proxyPath,
44592
+ {
44593
+ method: "POST",
44594
+ headers: { "Content-Type": "application/json" },
44595
+ body: JSON.stringify({ task, logs })
44596
+ },
44597
+ timeoutMs,
44598
+ void 0,
44599
+ { preferPublicEndpoint: true }
44600
+ );
44601
+ if (!response.ok) {
44602
+ const failure = await response.text().catch(() => "");
44603
+ throw new MeshyError("NODE_OFFLINE", failure || `Failed to seed task on ${node.name} (${response.status})`, 502);
44604
+ }
44605
+ const body = await response.json().catch(() => null);
44606
+ const seededLogs = Array.isArray(body?.logs) ? body.logs : logs;
44607
+ log2.info("seeded task snapshot on worker", {
44608
+ taskId: task.id,
44609
+ assignedTo: node.id,
44610
+ endpoint,
44611
+ importedLogCount: seededLogs.length
44612
+ });
44613
+ return seededLogs;
44614
+ }
44615
+ async function requestTaskLogsOverKeepalive(heartbeat, nodeId, task, after) {
44616
+ if (!canRequestNodeMessage(heartbeat)) return null;
44617
+ const message = createNodeMessage("task.logs", { taskId: task.id, after, task }, { expectsResponse: true });
44618
+ return requestFallbackNodeMessage(heartbeat, nodeId, message);
44619
+ }
43998
44620
  async function sendProxyResponse(res, proxyRes) {
43999
44621
  const contentType = proxyRes.headers.get("content-type");
44000
44622
  const contentDisposition = proxyRes.headers.get("content-disposition");
@@ -44005,6 +44627,43 @@ async function sendProxyResponse(res, proxyRes) {
44005
44627
  if (cacheControl) res.setHeader("Cache-Control", cacheControl);
44006
44628
  res.status(proxyRes.status).send(body);
44007
44629
  }
44630
+ async function maybeProxyReadToLeader(req, res, options = {}) {
44631
+ const { dataRouter, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
44632
+ const methods = new Set((options.methods ?? ["GET"]).map((method) => method.toUpperCase()));
44633
+ if (!methods.has(req.method.toUpperCase()) || nodeRegistry?.isLeader?.() !== false || !dataRouter?.proxyToLeader) {
44634
+ return false;
44635
+ }
44636
+ const leaderEndpoint = dataRouter.getLeaderEndpoint?.();
44637
+ if (!leaderEndpoint) {
44638
+ return false;
44639
+ }
44640
+ try {
44641
+ const result = await dataRouter.proxyToLeader(req);
44642
+ for (const [key, value] of Object.entries(result.headers)) {
44643
+ if (key.toLowerCase() === "content-length" || key.toLowerCase() === "transfer-encoding") continue;
44644
+ res.setHeader(key, value);
44645
+ }
44646
+ res.status(result.status).json(result.body);
44647
+ return true;
44648
+ } catch (error) {
44649
+ const log2 = rootLogger?.child?.("tasks/leader-read-proxy") ?? rootLogger;
44650
+ log2?.warn?.("leader read proxy failed", {
44651
+ path: req.originalUrl ?? req.url,
44652
+ leaderEndpoint,
44653
+ error: error instanceof Error ? error.message : String(error)
44654
+ });
44655
+ throw error instanceof MeshyError ? error : new MeshyError("NODE_OFFLINE", "Leader unreachable", 502);
44656
+ }
44657
+ }
44658
+
44659
+ // ../../packages/api/src/node/node-native-session-service.ts
44660
+ function getLocalNodeNativeSessions(nodeId, agent, limit) {
44661
+ return {
44662
+ nodeId,
44663
+ agent,
44664
+ sessions: listNativeSessions({ agent, limit })
44665
+ };
44666
+ }
44008
44667
 
44009
44668
  // ../../packages/api/src/tasks/task-cancellation.ts
44010
44669
  var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
@@ -44066,29 +44725,29 @@ function cancelTaskOnCurrentNode(deps, taskId, options = {}) {
44066
44725
  }
44067
44726
 
44068
44727
  // ../../packages/api/src/tasks/task-output-service.ts
44069
- var fs16 = __toESM(require("fs"), 1);
44070
- var path17 = __toESM(require("path"), 1);
44728
+ var fs17 = __toESM(require("fs"), 1);
44729
+ var path18 = __toESM(require("path"), 1);
44071
44730
 
44072
44731
  // ../../packages/api/src/preview/preview-server.ts
44073
44732
  var crypto3 = __toESM(require("crypto"), 1);
44074
- var fs15 = __toESM(require("fs"), 1);
44075
- var path16 = __toESM(require("path"), 1);
44733
+ var fs16 = __toESM(require("fs"), 1);
44734
+ var path17 = __toESM(require("path"), 1);
44076
44735
  var http2 = __toESM(require("http"), 1);
44077
44736
  function resolvePreviewPath(rootPath, relativePath) {
44078
44737
  const sanitizedPath = relativePath.replace(/\\/g, "/");
44079
- const resolvedPath = path16.resolve(rootPath, sanitizedPath);
44080
- const normalizedRoot = path16.resolve(rootPath);
44081
- if (!resolvedPath.startsWith(normalizedRoot + path16.sep) && resolvedPath !== normalizedRoot) {
44738
+ const resolvedPath = path17.resolve(rootPath, sanitizedPath);
44739
+ const normalizedRoot = path17.resolve(rootPath);
44740
+ if (!resolvedPath.startsWith(normalizedRoot + path17.sep) && resolvedPath !== normalizedRoot) {
44082
44741
  throw new Error("Invalid preview path");
44083
44742
  }
44084
44743
  return {
44085
44744
  absolutePath: resolvedPath,
44086
- normalizedPath: path16.relative(normalizedRoot, resolvedPath).split(path16.sep).join("/")
44745
+ normalizedPath: path17.relative(normalizedRoot, resolvedPath).split(path17.sep).join("/")
44087
44746
  };
44088
44747
  }
44089
44748
  function resolvePreviewEntryPath(rootPath, entryPath) {
44090
44749
  const { absolutePath, normalizedPath } = resolvePreviewPath(rootPath, entryPath ?? "index.html");
44091
- if (!fs15.existsSync(absolutePath) || !fs15.statSync(absolutePath).isFile()) {
44750
+ if (!fs16.existsSync(absolutePath) || !fs16.statSync(absolutePath).isFile()) {
44092
44751
  throw new Error("Preview entry not found");
44093
44752
  }
44094
44753
  return normalizedPath;
@@ -44152,7 +44811,7 @@ var MIME_MAP2 = {
44152
44811
  ".pdf": "application/pdf"
44153
44812
  };
44154
44813
  function getMime(filePath) {
44155
- return MIME_MAP2[path16.extname(filePath).toLowerCase()] ?? "application/octet-stream";
44814
+ return MIME_MAP2[path17.extname(filePath).toLowerCase()] ?? "application/octet-stream";
44156
44815
  }
44157
44816
  function sendPreviewAssetResponse(sessionManager, token, requestedPath, res) {
44158
44817
  const session = sessionManager.get(token);
@@ -44170,13 +44829,13 @@ function sendPreviewAssetResponse(sessionManager, token, requestedPath, res) {
44170
44829
  res.end("Invalid path");
44171
44830
  return;
44172
44831
  }
44173
- if (!fs15.existsSync(resolved) || !fs15.statSync(resolved).isFile()) {
44832
+ if (!fs16.existsSync(resolved) || !fs16.statSync(resolved).isFile()) {
44174
44833
  res.writeHead(404, { "Content-Type": "text/plain" });
44175
44834
  res.end("File not found");
44176
44835
  return;
44177
44836
  }
44178
44837
  const mime = getMime(resolved);
44179
- const content = fs15.readFileSync(resolved);
44838
+ const content = fs16.readFileSync(resolved);
44180
44839
  res.writeHead(200, {
44181
44840
  "Content-Type": mime,
44182
44841
  "Content-Length": content.length,
@@ -44449,13 +45108,13 @@ function getLocalTaskOutputDownload(taskEngine, taskId, filePath) {
44449
45108
  const rootPath = getTaskOutputRoot(taskEngine, taskId);
44450
45109
  try {
44451
45110
  const absolutePath = resolveOutputPath(rootPath, filePath);
44452
- if (!fs16.existsSync(absolutePath) || !fs16.statSync(absolutePath).isFile()) {
45111
+ if (!fs17.existsSync(absolutePath) || !fs17.statSync(absolutePath).isFile()) {
44453
45112
  throw new MeshyError("TASK_NOT_FOUND", `File not found: ${filePath}`, 404);
44454
45113
  }
44455
45114
  const { mimeType } = classifyFile(absolutePath);
44456
- const fileName = path17.basename(absolutePath).replace(/"/g, "");
45115
+ const fileName = path18.basename(absolutePath).replace(/"/g, "");
44457
45116
  return {
44458
- content: fs16.readFileSync(absolutePath),
45117
+ content: fs17.readFileSync(absolutePath),
44459
45118
  headers: {
44460
45119
  "Content-Type": mimeType,
44461
45120
  "Content-Disposition": `inline; filename="${fileName}"`,
@@ -44498,6 +45157,289 @@ async function createPreviewSessionPayload(deps, taskId, entryPath, requestOrigi
44498
45157
  };
44499
45158
  }
44500
45159
 
45160
+ // ../../packages/api/src/node/agent-upgrade-service.ts
45161
+ var import_node_child_process9 = require("child_process");
45162
+
45163
+ // ../../packages/api/src/app/system-info.ts
45164
+ var os6 = __toESM(require("os"), 1);
45165
+ var import_node_child_process8 = require("child_process");
45166
+ var RUNTIME_TOOLS = [
45167
+ { id: "claude", label: "Claude Code", command: "claude", packageName: "@anthropic-ai/claude-code" },
45168
+ { id: "codex", label: "Codex", command: "codex", packageName: "@openai/codex" }
45169
+ ];
45170
+ var runtimeToolUpdateCache = /* @__PURE__ */ new Map();
45171
+ function clearRuntimeToolUpdateCache(packageName) {
45172
+ if (packageName) {
45173
+ runtimeToolUpdateCache.delete(packageName);
45174
+ return;
45175
+ }
45176
+ runtimeToolUpdateCache.clear();
45177
+ }
45178
+ function runRuntimeToolCommand(command, args, platform2) {
45179
+ const result = (0, import_node_child_process8.spawnSync)(command, args, {
45180
+ encoding: "utf-8",
45181
+ shell: platform2 === "win32" && command !== "where",
45182
+ windowsHide: true,
45183
+ timeout: 2500
45184
+ });
45185
+ return {
45186
+ status: result.status,
45187
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
45188
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
45189
+ error: result.error?.message ?? null
45190
+ };
45191
+ }
45192
+ function normalizeOutput(output) {
45193
+ if (!output) {
45194
+ return null;
45195
+ }
45196
+ const firstLine = output.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
45197
+ return firstLine ?? null;
45198
+ }
45199
+ function formatLocalDate(date) {
45200
+ const year = date.getFullYear();
45201
+ const month = String(date.getMonth() + 1).padStart(2, "0");
45202
+ const day = String(date.getDate()).padStart(2, "0");
45203
+ return `${year}-${month}-${day}`;
45204
+ }
45205
+ function resolveCommandPath(command, commandRunner, platform2) {
45206
+ const lookupCommand = platform2 === "win32" ? "where" : "which";
45207
+ const result = commandRunner(lookupCommand, [command]);
45208
+ if (result.status === 0) {
45209
+ return { path: normalizeOutput(result.stdout) };
45210
+ }
45211
+ return {
45212
+ path: null,
45213
+ detail: normalizeOutput(result.stderr) ?? result.error ?? null
45214
+ };
45215
+ }
45216
+ function extractSemver(value) {
45217
+ return value?.match(/\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/)?.[0] ?? null;
45218
+ }
45219
+ function normalizePackageVersion(output) {
45220
+ if (!output) return null;
45221
+ const trimmed = output.trim();
45222
+ try {
45223
+ const parsed = JSON.parse(trimmed);
45224
+ if (typeof parsed === "string") {
45225
+ return parsed.trim() || null;
45226
+ }
45227
+ } catch {
45228
+ }
45229
+ return normalizeOutput(trimmed);
45230
+ }
45231
+ function normalizeInstalledPackageVersion(output, packageName) {
45232
+ if (!output) return null;
45233
+ const trimmed = output.trim();
45234
+ try {
45235
+ const parsed = JSON.parse(trimmed);
45236
+ const version2 = parsed.dependencies?.[packageName]?.version;
45237
+ if (typeof version2 === "string") {
45238
+ return version2.trim() || null;
45239
+ }
45240
+ } catch {
45241
+ }
45242
+ return extractSemver(normalizeOutput(trimmed));
45243
+ }
45244
+ function resolveInstalledPackageVersion(definition, commandRunner) {
45245
+ const result = commandRunner("npm", ["list", "-g", definition.packageName, "--depth=0", "--json"]);
45246
+ return normalizeInstalledPackageVersion(result.stdout ?? null, definition.packageName);
45247
+ }
45248
+ function compareSemver(left, right) {
45249
+ const leftParts = left.split(/[.-]/).map((part) => Number.parseInt(part, 10));
45250
+ const rightParts = right.split(/[.-]/).map((part) => Number.parseInt(part, 10));
45251
+ for (let index = 0; index < 3; index += 1) {
45252
+ const delta = (leftParts[index] || 0) - (rightParts[index] || 0);
45253
+ if (delta !== 0) return delta;
45254
+ }
45255
+ return 0;
45256
+ }
45257
+ function checkToolUpdate(definition, installedVersion, checkedAt, commandRunner, checkedOn, updateCache) {
45258
+ const currentVersion = extractSemver(installedVersion);
45259
+ const cached = updateCache.get(definition.packageName);
45260
+ let latestVersion = cached?.latestVersion ?? null;
45261
+ let detail = cached?.detail ?? null;
45262
+ let updateCheckedAt = cached?.checkedAt ?? checkedAt;
45263
+ if (cached?.checkedOn !== checkedOn) {
45264
+ const latestResult = commandRunner("npm", ["view", definition.packageName, "version", "--json"]);
45265
+ latestVersion = latestResult.status === 0 ? normalizePackageVersion(latestResult.stdout ?? null) : null;
45266
+ detail = latestResult.status === 0 ? null : normalizeOutput(latestResult.stderr) ?? latestResult.error ?? "Update check failed";
45267
+ updateCheckedAt = checkedAt;
45268
+ updateCache.set(definition.packageName, {
45269
+ checkedOn,
45270
+ checkedAt,
45271
+ latestVersion,
45272
+ detail
45273
+ });
45274
+ }
45275
+ return {
45276
+ packageName: definition.packageName,
45277
+ currentVersion,
45278
+ latestVersion,
45279
+ updateAvailable: Boolean(currentVersion && latestVersion && compareSemver(latestVersion, currentVersion) > 0),
45280
+ checkedAt: updateCheckedAt,
45281
+ detail
45282
+ };
45283
+ }
45284
+ function inspectTool(definition, commandRunner, checkedAt, checkedOn, updateCache, platform2) {
45285
+ const resolved = resolveCommandPath(definition.command, commandRunner, platform2);
45286
+ if (!resolved.path) {
45287
+ return {
45288
+ id: definition.id,
45289
+ label: definition.label,
45290
+ command: definition.command,
45291
+ available: false,
45292
+ path: null,
45293
+ version: null,
45294
+ checkedAt,
45295
+ detail: resolved.detail ?? "Command not found on PATH",
45296
+ update: checkToolUpdate(definition, null, checkedAt, commandRunner, checkedOn, updateCache)
45297
+ };
45298
+ }
45299
+ const versionResult = commandRunner(definition.command, ["--version"]);
45300
+ const commandVersion = normalizeOutput(versionResult.stdout) ?? normalizeOutput(versionResult.stderr);
45301
+ const version2 = extractSemver(commandVersion) ? commandVersion : resolveInstalledPackageVersion(definition, commandRunner);
45302
+ const detail = versionResult.status === 0 ? null : normalizeOutput(versionResult.stderr) ?? versionResult.error ?? "Version check failed";
45303
+ return {
45304
+ id: definition.id,
45305
+ label: definition.label,
45306
+ command: definition.command,
45307
+ available: true,
45308
+ path: resolved.path,
45309
+ version: version2,
45310
+ checkedAt,
45311
+ detail,
45312
+ update: checkToolUpdate(definition, version2, checkedAt, commandRunner, checkedOn, updateCache)
45313
+ };
45314
+ }
45315
+ function inspectRuntimeTools(options = {}) {
45316
+ const platform2 = options.platform ?? process.platform;
45317
+ const commandRunner = options.commandRunner ?? ((command, args) => runRuntimeToolCommand(command, args, platform2));
45318
+ const now = options.now ?? /* @__PURE__ */ new Date();
45319
+ const checkedAt = now.toISOString();
45320
+ const checkedOn = formatLocalDate(now);
45321
+ const updateCache = options.updateCache ?? runtimeToolUpdateCache;
45322
+ return RUNTIME_TOOLS.map((definition) => inspectTool(definition, commandRunner, checkedAt, checkedOn, updateCache, platform2));
45323
+ }
45324
+ function getOsSnapshot() {
45325
+ const cpus2 = os6.cpus();
45326
+ return {
45327
+ platform: os6.platform(),
45328
+ release: os6.release(),
45329
+ arch: os6.arch(),
45330
+ hostname: os6.hostname(),
45331
+ cpuModel: cpus2[0]?.model ?? null,
45332
+ cpuCount: cpus2.length,
45333
+ totalMemoryBytes: os6.totalmem(),
45334
+ freeMemoryBytes: os6.freemem()
45335
+ };
45336
+ }
45337
+ function buildNodeSettingsSnapshot(options) {
45338
+ const uptime = process.uptime();
45339
+ const runtimeMetadata = options.runtimeMetadata;
45340
+ const agents = (options.inspectRuntimeTools?.() ?? inspectRuntimeTools()).map((agent) => ({
45341
+ ...agent,
45342
+ metadataStatus: runtimeMetadata?.components?.[agent.id]?.status ?? null
45343
+ }));
45344
+ return {
45345
+ collectedAt: Date.now(),
45346
+ version: runtimeMetadata?.packageVersion ?? "0.1.0",
45347
+ packageName: runtimeMetadata?.packageName ?? "meshy",
45348
+ uptime,
45349
+ auth: options.auth,
45350
+ os: getOsSnapshot(),
45351
+ runtime: {
45352
+ nodeVersion: process.version,
45353
+ pid: process.pid,
45354
+ startedAt: Date.now() - Math.floor(uptime * 1e3),
45355
+ cwd: process.cwd(),
45356
+ workDir: options.workDir ?? null,
45357
+ storagePath: options.storagePath ?? null,
45358
+ localDashboardOrigin: options.localDashboardOrigin ?? null
45359
+ },
45360
+ agents,
45361
+ startupRequirements: {
45362
+ lastCheckedAt: runtimeMetadata?.startupRequirementsLastCheckedAt,
45363
+ lastCheckedOn: runtimeMetadata?.startupRequirementsLastCheckedOn,
45364
+ components: runtimeMetadata?.components ?? {}
45365
+ },
45366
+ components: runtimeMetadata?.components ?? {},
45367
+ repository: runtimeMetadata?.repository ?? {},
45368
+ packages: runtimeMetadata?.packages ?? {}
45369
+ };
45370
+ }
45371
+
45372
+ // ../../packages/api/src/node/agent-upgrade-service.ts
45373
+ var AGENT_PACKAGES = {
45374
+ claude: "@anthropic-ai/claude-code",
45375
+ codex: "@openai/codex"
45376
+ };
45377
+ var OUTPUT_LIMIT = 4e3;
45378
+ function summarizeOutput(value) {
45379
+ const text = value ?? "";
45380
+ return text.length > OUTPUT_LIMIT ? `${text.slice(0, OUTPUT_LIMIT)}\u2026` : text;
45381
+ }
45382
+ function defaultCommandRunner(command, args) {
45383
+ const result = (0, import_node_child_process9.spawnSync)(command, args, {
45384
+ encoding: "utf-8",
45385
+ shell: process.platform === "win32",
45386
+ windowsHide: true,
45387
+ timeout: 18e4
45388
+ });
45389
+ return {
45390
+ status: result.status,
45391
+ stdout: typeof result.stdout === "string" ? result.stdout : "",
45392
+ stderr: typeof result.stderr === "string" ? result.stderr : "",
45393
+ error: result.error?.message ?? null
45394
+ };
45395
+ }
45396
+ function isRuntimeAgentId(value) {
45397
+ return value === "claude" || value === "codex";
45398
+ }
45399
+ function buildUpgradeArgs(agent, packageName) {
45400
+ const args = ["install", "-g", `${packageName}@latest`];
45401
+ if (agent === "claude") {
45402
+ args.push("--include=optional", "--ignore-scripts=false");
45403
+ }
45404
+ return args;
45405
+ }
45406
+ function upgradeRuntimeAgent(agent, options = {}) {
45407
+ const packageName = AGENT_PACKAGES[agent];
45408
+ if (!packageName) {
45409
+ throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${agent}`, 400);
45410
+ }
45411
+ const command = "npm";
45412
+ const args = buildUpgradeArgs(agent, packageName);
45413
+ const result = (options.commandRunner ?? defaultCommandRunner)(command, args);
45414
+ const ok = result.status === 0 && !result.error;
45415
+ if (ok) {
45416
+ clearRuntimeToolUpdateCache(packageName);
45417
+ }
45418
+ const detail = result.error ?? (summarizeOutput(result.stderr) || "Agent upgrade failed");
45419
+ return {
45420
+ ok,
45421
+ agent,
45422
+ packageName,
45423
+ command,
45424
+ args,
45425
+ status: result.status,
45426
+ stdout: summarizeOutput(result.stdout),
45427
+ stderr: summarizeOutput(result.stderr),
45428
+ detail: ok ? null : detail
45429
+ };
45430
+ }
45431
+ function upgradeRuntimeAgentForDeps(deps, agent) {
45432
+ const result = deps.upgradeRuntimeAgent?.(agent) ?? upgradeRuntimeAgent(agent);
45433
+ if (result.ok) {
45434
+ const settingsSnapshot = deps.refreshSettingsSnapshot?.();
45435
+ if (settingsSnapshot) {
45436
+ deps.nodeRegistry.updateSettingsSnapshot(deps.nodeRegistry.getSelf().id, settingsSnapshot);
45437
+ return { ...result, settingsSnapshot };
45438
+ }
45439
+ }
45440
+ return result;
45441
+ }
45442
+
44501
45443
  // ../../packages/api/src/node/worker-control.ts
44502
45444
  function jsonResponse(requestId, statusCode, body) {
44503
45445
  return {
@@ -44541,6 +45483,12 @@ function payloadValue(request, key, fallback) {
44541
45483
  const value = request.payload[key];
44542
45484
  return value === void 0 ? fallback : value;
44543
45485
  }
45486
+ function maybeImportTaskSnapshot(deps, request) {
45487
+ if (!request.kind.startsWith("task.output.") && request.kind !== "task.preview.create" && request.kind !== "task.logs") return;
45488
+ const task = payloadValue(request, "task", null);
45489
+ if (!task || deps.taskEngine.getTask(task.id)) return;
45490
+ deps.taskEngine.importTasks([task]);
45491
+ }
44544
45492
  async function executeWorkerControlRequest(deps, request) {
44545
45493
  const startedAt = Date.now();
44546
45494
  const log2 = deps.logger.child("worker-control");
@@ -44553,6 +45501,7 @@ async function executeWorkerControlRequest(deps, request) {
44553
45501
  });
44554
45502
  try {
44555
45503
  let response;
45504
+ maybeImportTaskSnapshot(deps, request);
44556
45505
  switch (request.kind) {
44557
45506
  case "node.workdir.tree": {
44558
45507
  const self2 = deps.nodeRegistry.getSelf();
@@ -44611,6 +45560,19 @@ async function executeWorkerControlRequest(deps, request) {
44611
45560
  );
44612
45561
  break;
44613
45562
  }
45563
+ case "node.sessions.list": {
45564
+ const self2 = deps.nodeRegistry.getSelf();
45565
+ response = jsonResponse(
45566
+ request.id,
45567
+ 200,
45568
+ getLocalNodeNativeSessions(
45569
+ self2.id,
45570
+ payloadValue(request, "agent", "codex"),
45571
+ payloadValue(request, "limit", 50)
45572
+ )
45573
+ );
45574
+ break;
45575
+ }
44614
45576
  case "node.transport.set": {
44615
45577
  assertCanChangeNodeDevTunnel(deps.taskEngine, deps.nodeRegistry.getSelf().id);
44616
45578
  if (payloadValue(request, "enabled", false)) {
@@ -44637,6 +45599,14 @@ async function executeWorkerControlRequest(deps, request) {
44637
45599
  });
44638
45600
  break;
44639
45601
  }
45602
+ case "node.agent.upgrade": {
45603
+ const agent = payloadValue(request, "agent", "");
45604
+ if (!isRuntimeAgentId(agent)) {
45605
+ throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${agent}`, 400);
45606
+ }
45607
+ response = jsonResponse(request.id, 200, upgradeRuntimeAgentForDeps(deps, agent));
45608
+ break;
45609
+ }
44640
45610
  case "task.cancel": {
44641
45611
  const taskId = payloadValue(request, "taskId", "");
44642
45612
  const result = cancelTaskOnCurrentNode({
@@ -44657,6 +45627,16 @@ async function executeWorkerControlRequest(deps, request) {
44657
45627
  });
44658
45628
  break;
44659
45629
  }
45630
+ case "task.logs": {
45631
+ const taskId = payloadValue(request, "taskId", "");
45632
+ const task = deps.taskEngine.getTask(taskId);
45633
+ response = jsonResponse(
45634
+ request.id,
45635
+ 200,
45636
+ readLocalTaskLogsWithNativeHistory(deps.engineRegistry, task, taskId, payloadValue(request, "after", 0), task?.agent ?? "claudecode")
45637
+ );
45638
+ break;
45639
+ }
44660
45640
  case "task.output.summary": {
44661
45641
  response = jsonResponse(
44662
45642
  request.id,
@@ -44758,38 +45738,100 @@ function sendWorkerControlResponse(res, response) {
44758
45738
  res.status(response.statusCode).send(response.body);
44759
45739
  }
44760
45740
 
44761
- // ../../packages/api/src/node/node-message-compat.ts
44762
- var LEGACY_KIND_BY_NODE_MESSAGE = {
44763
- "node.workdir.tree": "node-workdir-tree",
44764
- "node.workdir.branch-info": "node-workdir-branch-info",
44765
- "node.workdir.branch-create": "node-workdir-branch-create",
44766
- "node.transport.set": "devtunnel",
44767
- "task.cancel": "task-cancel",
44768
- "task.output.summary": "task-output-summary",
44769
- "task.output.tree": "task-output-tree",
44770
- "task.output.content": "task-output-content",
44771
- "task.output.download": "task-output-download",
44772
- "task.output.diff": "task-output-diff",
44773
- "task.preview.create": "task-preview-session"
44774
- };
44775
- function canRequestNodeMessage(heartbeat) {
44776
- return !!(heartbeat?.requestNodeMessage || heartbeat?.requestWorkerControl);
45741
+ // ../../packages/api/src/routes/node-native-sessions.ts
45742
+ var import_express4 = __toESM(require_express2(), 1);
45743
+ function sendLocalNodeNativeSessions(req, res, nodeId, options = {}) {
45744
+ const query = NodeNativeSessionsQuery.parse(req.query);
45745
+ const { nodeRegistry } = req.app.locals.deps;
45746
+ const self2 = nodeRegistry.getSelf();
45747
+ if (options.requireSelfNode && nodeId !== self2.id) {
45748
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
45749
+ }
45750
+ res.json(getLocalNodeNativeSessions(self2.id, query.agent, query.limit));
44777
45751
  }
44778
- function requestFallbackNodeMessage(heartbeat, nodeId, message) {
44779
- if (heartbeat.requestNodeMessage) return heartbeat.requestNodeMessage(nodeId, message);
44780
- if (heartbeat.requestWorkerControl) return heartbeat.requestWorkerControl(nodeId, toLegacyWorkerControl2(message));
44781
- throw new Error("Node message fallback is not available");
45752
+
45753
+ // ../../packages/api/src/routes/node-agent-upgrade.ts
45754
+ function isRecord5(value) {
45755
+ return typeof value === "object" && value !== null && !Array.isArray(value);
44782
45756
  }
44783
- function toLegacyWorkerControl2(message) {
44784
- return {
44785
- ...typeof message.payload === "object" && message.payload !== null ? message.payload : {},
44786
- kind: LEGACY_KIND_BY_NODE_MESSAGE[message.kind] ?? message.kind
44787
- };
45757
+ function readSettingsSnapshot(value) {
45758
+ if (!isRecord5(value)) return void 0;
45759
+ const snapshot = value.settingsSnapshot;
45760
+ if (!isRecord5(snapshot)) return void 0;
45761
+ return snapshot;
45762
+ }
45763
+ function applySyncedSettingsSnapshot(deps, nodeId, body) {
45764
+ const settingsSnapshot = readSettingsSnapshot(body);
45765
+ if (settingsSnapshot) {
45766
+ deps.nodeRegistry.updateSettingsSnapshot(nodeId, settingsSnapshot);
45767
+ }
45768
+ }
45769
+ function parseAgent(value) {
45770
+ if (isRuntimeAgentId(value)) return value;
45771
+ throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${value}`, 400);
45772
+ }
45773
+ function upgradeSelfNode(deps, nodeId, agent) {
45774
+ const result = upgradeRuntimeAgentForDeps(deps, agent);
45775
+ applySyncedSettingsSnapshot(deps, nodeId, result);
45776
+ return result;
45777
+ }
45778
+ async function fallbackUpgrade(deps, res, nodeId, agent) {
45779
+ if (!canRequestNodeMessage(deps.heartbeat)) {
45780
+ throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to upgrade ${agent}`, 502);
45781
+ }
45782
+ const controlResponse = await requestFallbackNodeMessage(
45783
+ deps.heartbeat,
45784
+ nodeId,
45785
+ createNodeMessage("node.agent.upgrade", { agent }, { expectsResponse: true })
45786
+ );
45787
+ applySyncedSettingsSnapshot(deps, nodeId, controlResponse.body);
45788
+ sendWorkerControlResponse(res, controlResponse);
45789
+ }
45790
+ async function proxyUpgrade(deps, nodeId, agent) {
45791
+ const node = deps.nodeRegistry.getNode(nodeId);
45792
+ if (!node) {
45793
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
45794
+ }
45795
+ const { response } = await fetchNodeWithFallback(node, `/api/nodes/${nodeId}/agents/${agent}/upgrade`, {
45796
+ method: "POST",
45797
+ headers: { "Content-Type": "application/json" }
45798
+ }, void 0, void 0, { preferPublicEndpoint: true });
45799
+ const body = await response.json().catch(() => ({ error: response.statusText }));
45800
+ if (!response.ok) {
45801
+ throw new MeshyError("NODE_OFFLINE", `Remote node returned ${response.status}`, response.status, body);
45802
+ }
45803
+ applySyncedSettingsSnapshot(deps, nodeId, body);
45804
+ return body;
45805
+ }
45806
+ async function sendNodeAgentUpgrade(req, res, nodeId, agentParam) {
45807
+ const deps = req.app.locals.deps;
45808
+ const agent = parseAgent(agentParam);
45809
+ const self2 = deps.nodeRegistry.getSelf();
45810
+ const isSelf = nodeId === self2.id;
45811
+ if (!isSelf && !deps.election.isLeader()) {
45812
+ throw new MeshyError("NOT_LEADER", "Only the leader can upgrade agents on other nodes", 403);
45813
+ }
45814
+ if (isSelf) {
45815
+ res.json(upgradeSelfNode(deps, nodeId, agent));
45816
+ return;
45817
+ }
45818
+ const canPushToNode = deps.heartbeat?.canPushToNode?.(nodeId) ?? true;
45819
+ if (!canPushToNode) {
45820
+ await fallbackUpgrade(deps, res, nodeId, agent);
45821
+ return;
45822
+ }
45823
+ try {
45824
+ res.json(await proxyUpgrade(deps, nodeId, agent));
45825
+ } catch (err) {
45826
+ if (!canRequestNodeMessage(deps.heartbeat)) throw err;
45827
+ await fallbackUpgrade(deps, res, nodeId, agent);
45828
+ }
44788
45829
  }
44789
45830
 
44790
45831
  // ../../packages/api/src/routes/nodes.ts
44791
45832
  var NODE_WORKDIR_PROXY_TIMEOUT_MS = 1e4;
44792
45833
  var NODE_WORKDIR_BRANCH_PROXY_TIMEOUT_MS = 25e3;
45834
+ var NODE_NATIVE_SESSIONS_PROXY_TIMEOUT_MS = 1e4;
44793
45835
  function describeProxyError2(error) {
44794
45836
  if (error instanceof Error) {
44795
45837
  const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
@@ -45053,45 +46095,121 @@ async function maybeHandleRemoteNodeWorkDirBranchCreateRequest(req, res, nodeId)
45053
46095
  throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to create a git branch`, 502);
45054
46096
  }
45055
46097
  }
46098
+ async function maybeHandleRemoteNodeNativeSessionsRequest(req, res, nodeId) {
46099
+ const query = NodeNativeSessionsQuery.parse(req.query);
46100
+ const { nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
46101
+ const selfId = nodeRegistry.getSelf().id;
46102
+ if (nodeId === selfId) {
46103
+ return false;
46104
+ }
46105
+ const node = nodeRegistry.getNode(nodeId);
46106
+ if (!node) {
46107
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
46108
+ }
46109
+ const log2 = rootLogger.child("nodes/native-sessions");
46110
+ const proxyPath = req.originalUrl ?? `/api/nodes/${nodeId}/native-sessions`;
46111
+ const fallbackRequest = createNodeMessage("node.sessions.list", {
46112
+ agent: query.agent,
46113
+ limit: query.limit
46114
+ }, { expectsResponse: true });
46115
+ const canPushToNode = heartbeat?.canPushToNode?.(nodeId) ?? true;
46116
+ if (!canPushToNode && canRequestNodeMessage(heartbeat)) {
46117
+ log2.warn("node native sessions request falling back to keepalive control", {
46118
+ nodeId,
46119
+ proxyPath
46120
+ });
46121
+ const controlResponse = await requestFallbackNodeMessage(heartbeat, nodeId, fallbackRequest);
46122
+ sendWorkerControlResponse(res, controlResponse);
46123
+ return true;
46124
+ }
46125
+ try {
46126
+ const { endpoint, response } = await fetchNodeWithFallback(
46127
+ node,
46128
+ proxyPath,
46129
+ void 0,
46130
+ NODE_NATIVE_SESSIONS_PROXY_TIMEOUT_MS,
46131
+ createNodeWorkdirProxyTrace(log2, nodeId, proxyPath),
46132
+ { preferPublicEndpoint: true }
46133
+ );
46134
+ log2.debug("proxying node native sessions request", {
46135
+ nodeId,
46136
+ endpoint,
46137
+ proxyPath
46138
+ });
46139
+ await sendProxyResponse(res, response);
46140
+ return true;
46141
+ } catch (err) {
46142
+ const errorDetails = describeProxyError2(err);
46143
+ log2.warn("node native sessions proxy error", {
46144
+ nodeId,
46145
+ proxyPath,
46146
+ timeoutMs: NODE_NATIVE_SESSIONS_PROXY_TIMEOUT_MS,
46147
+ ...errorDetails
46148
+ });
46149
+ if (canRequestNodeMessage(heartbeat)) {
46150
+ log2.warn("node native sessions proxy failed, falling back to keepalive control", {
46151
+ nodeId,
46152
+ proxyPath,
46153
+ timeoutMs: NODE_NATIVE_SESSIONS_PROXY_TIMEOUT_MS,
46154
+ ...errorDetails
46155
+ });
46156
+ const controlResponse = await requestFallbackNodeMessage(heartbeat, nodeId, fallbackRequest);
46157
+ sendWorkerControlResponse(res, controlResponse);
46158
+ return true;
46159
+ }
46160
+ throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to list its native sessions`, 502);
46161
+ }
46162
+ }
45056
46163
  function createNodeRoutes() {
45057
- const router = (0, import_express4.Router)();
46164
+ const router = (0, import_express5.Router)();
45058
46165
  router.get("/", asyncHandler3(async (req, res) => {
45059
46166
  const { nodeRegistry } = req.app.locals.deps;
45060
46167
  const query = NodeListQuery.parse(req.query);
45061
46168
  let nodes = nodeRegistry.getAllNodes();
45062
46169
  if (query.status) {
45063
- nodes = nodes.filter((n) => n.status === query.status);
46170
+ nodes = nodes.filter((node) => node.status === query.status);
45064
46171
  }
45065
- if (query.capability) {
46172
+ const capability = query.capability;
46173
+ if (capability) {
45066
46174
  nodes = nodes.filter(
45067
- (n) => n.capabilities && n.capabilities.includes(query.capability)
46175
+ (node) => node.capabilities && node.capabilities.includes(capability)
45068
46176
  );
45069
46177
  }
45070
46178
  res.json({ nodes });
45071
46179
  }));
45072
46180
  router.get("/:id", asyncHandler3(async (req, res) => {
45073
46181
  const { nodeRegistry } = req.app.locals.deps;
45074
- const node = nodeRegistry.getNode(req.params.id);
46182
+ const nodeId = req.params.id;
46183
+ const node = nodeRegistry.getNode(nodeId);
45075
46184
  if (!node) {
45076
- throw new MeshyError("NODE_NOT_FOUND", `Node ${req.params.id} not found`, 404);
46185
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
45077
46186
  }
45078
46187
  res.json(node);
45079
46188
  }));
45080
46189
  router.get("/:id/status", asyncHandler3(async (req, res) => {
45081
46190
  const { nodeRegistry, taskEngine } = req.app.locals.deps;
45082
- const node = nodeRegistry.getNode(req.params.id);
46191
+ const nodeId = req.params.id;
46192
+ const node = nodeRegistry.getNode(nodeId);
45083
46193
  if (!node) {
45084
- throw new MeshyError("NODE_NOT_FOUND", `Node ${req.params.id} not found`, 404);
45085
- }
45086
- const { tasks } = taskEngine.listTasks({ assignedTo: req.params.id });
45087
- const taskSummary = tasks.map((t) => ({
45088
- id: t.id,
45089
- title: t.title,
45090
- status: t.status,
45091
- priority: t.priority
46194
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
46195
+ }
46196
+ const { tasks } = taskEngine.listTasks({ assignedTo: nodeId });
46197
+ const taskSummary = tasks.map((task) => ({
46198
+ id: task.id,
46199
+ title: task.title,
46200
+ status: task.status,
46201
+ priority: task.priority
45092
46202
  }));
45093
46203
  res.json({ node, tasks: taskSummary });
45094
46204
  }));
46205
+ router.get("/:id/native-sessions", asyncHandler3(async (req, res) => {
46206
+ const nodeId = req.params.id;
46207
+ const handled = await maybeHandleRemoteNodeNativeSessionsRequest(req, res, nodeId);
46208
+ if (handled) {
46209
+ return;
46210
+ }
46211
+ sendLocalNodeNativeSessions(req, res, nodeId);
46212
+ }));
45095
46213
  router.get("/:id/workdir/tree", asyncHandler3(async (req, res) => {
45096
46214
  const nodeId = req.params.id;
45097
46215
  const handled = await maybeHandleRemoteNodeWorkDirRequest(req, res, nodeId);
@@ -45116,6 +46234,9 @@ function createNodeRoutes() {
45116
46234
  }
45117
46235
  sendLocalNodeWorkDirBranchCreate(req, res, nodeId);
45118
46236
  }));
46237
+ router.post("/:id/agents/:agent/upgrade", asyncHandler3(async (req, res) => {
46238
+ await sendNodeAgentUpgrade(req, res, req.params.id, req.params.agent);
46239
+ }));
45119
46240
  router.patch("/:id", asyncHandler3(async (req, res) => {
45120
46241
  const { nodeRegistry, persistNodeNamePreference } = req.app.locals.deps;
45121
46242
  const updates = UpdateNodeBody.parse(req.body);
@@ -45141,14 +46262,15 @@ function createNodeRoutes() {
45141
46262
  }));
45142
46263
  router.delete("/:id", asyncHandler3(async (req, res) => {
45143
46264
  const { nodeRegistry, election } = req.app.locals.deps;
46265
+ const nodeId = req.params.id;
45144
46266
  if (!election.isLeader()) {
45145
46267
  throw new MeshyError("NOT_LEADER", "Only the leader node can delete nodes", 403);
45146
46268
  }
45147
- const node = nodeRegistry.getNode(req.params.id);
46269
+ const node = nodeRegistry.getNode(nodeId);
45148
46270
  if (!node) {
45149
- throw new MeshyError("NODE_NOT_FOUND", `Node ${req.params.id} not found`, 404);
46271
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
45150
46272
  }
45151
- nodeRegistry.removeNode(req.params.id);
46273
+ nodeRegistry.removeNode(nodeId);
45152
46274
  res.json({ ok: true });
45153
46275
  }));
45154
46276
  router.post("/:id/devtunnel", asyncHandler3(async (req, res) => {
@@ -45249,12 +46371,12 @@ function createNodeRoutes() {
45249
46371
  }
45250
46372
 
45251
46373
  // ../../packages/api/src/routes/node-messages.ts
45252
- var import_express5 = __toESM(require_express2(), 1);
46374
+ var import_express6 = __toESM(require_express2(), 1);
45253
46375
  function asyncHandler4(fn) {
45254
46376
  return (req, res, next) => fn(req, res, next).catch(next);
45255
46377
  }
45256
46378
  function createNodeMessageRoutes() {
45257
- const router = (0, import_express5.Router)();
46379
+ const router = (0, import_express6.Router)();
45258
46380
  router.post("/messages", asyncHandler4(async (req, res) => {
45259
46381
  const response = await handleNodeMessage(req.app.locals.deps, req.body);
45260
46382
  if (response) {
@@ -45334,7 +46456,7 @@ async function handleTaskMessage(deps, message) {
45334
46456
  }
45335
46457
 
45336
46458
  // ../../packages/api/src/routes/tasks.ts
45337
- var import_express7 = __toESM(require_express2(), 1);
46459
+ var import_express8 = __toESM(require_express2(), 1);
45338
46460
 
45339
46461
  // ../../packages/api/src/tasks/task-remote-cancellation.ts
45340
46462
  async function cancelRemoteTaskExecution(deps) {
@@ -45403,8 +46525,307 @@ function startLocalTaskFollowUp(deps, task, content, assignedTo, metadata) {
45403
46525
  }
45404
46526
  }
45405
46527
 
46528
+ // ../../packages/api/src/tasks/task-session-import.ts
46529
+ var TASK_IMPORT_PROXY_TIMEOUT_MS = 1e4;
46530
+ function buildImportedSessionTitle(agent, sessionId) {
46531
+ const label = agent === "codex" ? "Codex" : "Claude Code";
46532
+ const suffix = sessionId.trim().slice(0, 12);
46533
+ return `${label} session ${suffix || "attached"}`;
46534
+ }
46535
+ function resolveTargetImportNode(nodeRegistry, nodeId, agent) {
46536
+ const self2 = nodeRegistry.getSelf();
46537
+ const node = nodeRegistry.getNode(nodeId) ?? (self2?.id === nodeId ? self2 : null);
46538
+ if (!node) {
46539
+ throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
46540
+ }
46541
+ if (node.status === "offline") {
46542
+ throw new MeshyError("NODE_OFFLINE", `Node ${node.name} is offline`, 400);
46543
+ }
46544
+ if (node.supportedAgents && node.supportedAgents.length > 0 && !node.supportedAgents.includes(agent)) {
46545
+ throw new MeshyError("VALIDATION_ERROR", `Node ${node.name} does not support agent ${agent}`, 400);
46546
+ }
46547
+ return node;
46548
+ }
46549
+ async function attachNativeSession(deps, body) {
46550
+ const log2 = deps.logger.child("tasks/import-session");
46551
+ const selfId = deps.nodeRegistry.getSelf()?.id;
46552
+ const targetNodeId = body.assignTo ?? selfId;
46553
+ if (!targetNodeId) {
46554
+ throw new MeshyError("VALIDATION_ERROR", "No target node is available for session import", 400);
46555
+ }
46556
+ const targetNode = resolveTargetImportNode(deps.nodeRegistry, targetNodeId, body.agent);
46557
+ const history = loadNativeSessionHistory({
46558
+ agent: body.agent,
46559
+ sessionId: body.sessionId
46560
+ });
46561
+ let importedLogs = history.logs;
46562
+ const task = deps.taskEngine.createTask({
46563
+ title: body.title?.trim() || buildImportedSessionTitle(body.agent, body.sessionId),
46564
+ description: `Attached native ${body.agent === "codex" ? "Codex" : "Claude Code"} session`,
46565
+ agent: body.agent,
46566
+ project: body.cwd,
46567
+ conversationKind: "nativeSession",
46568
+ payload: {
46569
+ sessionId: body.sessionId,
46570
+ sessionCwd: body.cwd,
46571
+ ...body.mode ? { mode: body.mode } : {}
46572
+ },
46573
+ priority: body.priority,
46574
+ createdBy: "api"
46575
+ });
46576
+ const importedTask = deps.taskEngine.updateTask(task.id, {
46577
+ status: "completed",
46578
+ assignedTo: targetNode.id,
46579
+ assignedNodeName: targetNode.name,
46580
+ effectiveProjectPath: body.cwd
46581
+ });
46582
+ if (!importedTask) {
46583
+ deps.taskEngine.deleteTask(task.id);
46584
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${task.id} not found after session import`, 500);
46585
+ }
46586
+ try {
46587
+ if (targetNode.id !== selfId) {
46588
+ importedLogs = await seedTaskSnapshotOnWorker(importedTask, importedLogs, targetNode, log2, TASK_IMPORT_PROXY_TIMEOUT_MS);
46589
+ }
46590
+ } catch (error) {
46591
+ deps.taskEngine.deleteTask(task.id);
46592
+ throw error;
46593
+ }
46594
+ if (importedLogs.length > 0) {
46595
+ try {
46596
+ recordLocalTaskLogs(deps.engineRegistry, importedTask, importedLogs);
46597
+ log2.info("imported native session history into local task logs", {
46598
+ taskId: importedTask.id,
46599
+ assignedTo: importedTask.assignedTo,
46600
+ importedLogCount: importedLogs.length,
46601
+ sourcePath: history.sourcePath
46602
+ });
46603
+ } catch (error) {
46604
+ log2.warn("failed to mirror imported native session history locally", {
46605
+ taskId: importedTask.id,
46606
+ assignedTo: importedTask.assignedTo,
46607
+ importedLogCount: importedLogs.length,
46608
+ sourcePath: history.sourcePath,
46609
+ error: error instanceof Error ? error.message : String(error)
46610
+ });
46611
+ }
46612
+ } else {
46613
+ log2.info("no native session history found to import", {
46614
+ taskId: importedTask.id,
46615
+ assignedTo: importedTask.assignedTo,
46616
+ sessionId: body.sessionId,
46617
+ sourcePath: history.sourcePath
46618
+ });
46619
+ }
46620
+ return importedTask;
46621
+ }
46622
+
46623
+ // ../../packages/api/src/tasks/task-log-proxy.ts
46624
+ var TASK_LOG_PROXY_PURPOSE_HEADER = "x-meshy-proxy-purpose";
46625
+ var TASK_LOG_PROXY_SOURCE_HEADER = "x-meshy-proxy-source-node";
46626
+ var TASK_LOG_PROXY_TASK_HEADER = "x-meshy-task-snapshot";
46627
+ var TASK_LOG_PROXY_PURPOSE = "task-logs";
46628
+ function encodeTaskSnapshot(task) {
46629
+ return Buffer.from(JSON.stringify(task), "utf8").toString("base64url");
46630
+ }
46631
+ function decodeTaskSnapshot(value) {
46632
+ if (!value) return void 0;
46633
+ try {
46634
+ const task = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
46635
+ return typeof task?.id === "string" ? task : void 0;
46636
+ } catch {
46637
+ return void 0;
46638
+ }
46639
+ }
46640
+ function createTaskLogsProxyHeaders(sourceNodeId, task) {
46641
+ return {
46642
+ [TASK_LOG_PROXY_PURPOSE_HEADER]: TASK_LOG_PROXY_PURPOSE,
46643
+ [TASK_LOG_PROXY_TASK_HEADER]: encodeTaskSnapshot(task),
46644
+ ...sourceNodeId ? { [TASK_LOG_PROXY_SOURCE_HEADER]: sourceNodeId } : {}
46645
+ };
46646
+ }
46647
+ function getTaskLogsProxyRequestMetadata(req) {
46648
+ const purpose = req.get(TASK_LOG_PROXY_PURPOSE_HEADER);
46649
+ const sourceNodeId = req.get(TASK_LOG_PROXY_SOURCE_HEADER) ?? void 0;
46650
+ return { isProxy: purpose === TASK_LOG_PROXY_PURPOSE, sourceNodeId, task: decodeTaskSnapshot(req.get(TASK_LOG_PROXY_TASK_HEADER)) };
46651
+ }
46652
+ function describeProxyError3(error) {
46653
+ if (error instanceof Error) {
46654
+ const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
46655
+ return {
46656
+ errorName: error.name,
46657
+ errorMessage: error.message,
46658
+ errorCategory
46659
+ };
46660
+ }
46661
+ return {
46662
+ errorName: "UnknownError",
46663
+ errorMessage: String(error),
46664
+ errorCategory: "unknown"
46665
+ };
46666
+ }
46667
+ function createTaskLogsProxyTrace(log2, taskId, nodeId, proxyPath) {
46668
+ return {
46669
+ onAttempt: ({ attempt, endpoint, timeoutMs, totalEndpoints }) => {
46670
+ log2.debug("task logs proxy attempt", { taskId, nodeId, proxyPath, endpoint, attempt, totalEndpoints, timeoutMs });
46671
+ },
46672
+ onResponse: ({ attempt, endpoint, response, timeoutMs, totalEndpoints }) => {
46673
+ log2.info("task logs proxy response", {
46674
+ taskId,
46675
+ nodeId,
46676
+ proxyPath,
46677
+ endpoint,
46678
+ attempt,
46679
+ totalEndpoints,
46680
+ timeoutMs,
46681
+ ok: response.ok,
46682
+ statusCode: response.status
46683
+ });
46684
+ },
46685
+ onError: ({ attempt, endpoint, error, timeoutMs, totalEndpoints }) => {
46686
+ log2.warn("task logs proxy attempt failed", {
46687
+ taskId,
46688
+ nodeId,
46689
+ proxyPath,
46690
+ endpoint,
46691
+ attempt,
46692
+ totalEndpoints,
46693
+ timeoutMs,
46694
+ ...describeProxyError3(error)
46695
+ });
46696
+ }
46697
+ };
46698
+ }
46699
+
46700
+ // ../../packages/api/src/tasks/task-log-response.ts
46701
+ var TASK_LOG_PROXY_TIMEOUT_MS = 1e4;
46702
+ async function sendTaskLogsResponse(req, res, taskId) {
46703
+ const { engineRegistry, taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
46704
+ const log2 = rootLogger.child("tasks/logs");
46705
+ const query = TaskLogsQuery.parse(req.query);
46706
+ const after = query.after ?? 0;
46707
+ const proxyRequest = getTaskLogsProxyRequestMetadata(req);
46708
+ let task = taskEngine.getTask(taskId);
46709
+ if (!task && proxyRequest.task?.id === taskId) {
46710
+ taskEngine.importTasks([proxyRequest.task]);
46711
+ task = taskEngine.getTask(taskId) ?? proxyRequest.task;
46712
+ log2.info("imported task snapshot from proxied task logs request", {
46713
+ taskId,
46714
+ assignedTo: task.assignedTo,
46715
+ sourceNodeId: proxyRequest.sourceNodeId
46716
+ });
46717
+ }
46718
+ if (!task && !proxyRequest.isProxy && await maybeProxyReadToLeader(req, res)) return;
46719
+ const selfId = nodeRegistry.getSelf()?.id;
46720
+ const isLeader = nodeRegistry.isLeader();
46721
+ const isFollowerRemoteTask = !isLeader && !!(task?.assignedTo && task.assignedTo !== selfId);
46722
+ const needsProxy = isLeader && !!(task?.assignedTo && task.assignedTo !== selfId);
46723
+ if (proxyRequest.isProxy) {
46724
+ log2.info("received proxied task logs request", {
46725
+ taskId,
46726
+ after,
46727
+ taskFound: !!task,
46728
+ assignedTo: task?.assignedTo,
46729
+ selfId,
46730
+ isLeader,
46731
+ sourceNodeId: proxyRequest.sourceNodeId,
46732
+ forwardedHost: req.get("x-forwarded-host"),
46733
+ forwardedFor: req.get("x-forwarded-for")
46734
+ });
46735
+ }
46736
+ if (!task) throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46737
+ log2.debug("log request", {
46738
+ taskId,
46739
+ assignedTo: task?.assignedTo,
46740
+ selfId,
46741
+ isLeader,
46742
+ needsProxy
46743
+ });
46744
+ if (isLeader) {
46745
+ const local2 = readLocalTaskLogsWithNativeHistory(engineRegistry, task, taskId, after, task?.agent ?? "claudecode");
46746
+ if (local2.total > 0 || !needsProxy) {
46747
+ log2.debug("serving leader-local task logs", {
46748
+ taskId,
46749
+ assignedTo: task?.assignedTo,
46750
+ selfId,
46751
+ total: local2.total,
46752
+ after
46753
+ });
46754
+ res.json(local2);
46755
+ return;
46756
+ }
46757
+ log2.debug("leader-local task log missing, falling back to worker proxy", {
46758
+ taskId,
46759
+ assignedTo: task?.assignedTo,
46760
+ selfId
46761
+ });
46762
+ }
46763
+ const assignedTo = task.assignedTo;
46764
+ if (needsProxy && assignedTo) {
46765
+ const node = nodeRegistry.getNode(assignedTo);
46766
+ log2.debug("proxy target", { nodeId: node?.id, endpoint: node?.endpoint, devtunnel: node?.devtunnelEndpoint, status: node?.status });
46767
+ if (node) {
46768
+ const seededLogs = await seedTaskSnapshotOnWorker(task, [], node, log2).catch((err) => {
46769
+ log2.warn("failed to seed task snapshot before task logs proxy", {
46770
+ taskId,
46771
+ assignedTo,
46772
+ ...describeProxyError3(err)
46773
+ });
46774
+ return [];
46775
+ });
46776
+ if (seededLogs.length > 0) recordLocalTaskLogs(engineRegistry, task, seededLogs);
46777
+ const proxyPath = `/api/tasks/${taskId}/logs?after=${after}`;
46778
+ try {
46779
+ const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
46780
+ node,
46781
+ proxyPath,
46782
+ { headers: createTaskLogsProxyHeaders(selfId, task) },
46783
+ TASK_LOG_PROXY_TIMEOUT_MS,
46784
+ createTaskLogsProxyTrace(log2, taskId, node.id, proxyPath),
46785
+ { preferPublicEndpoint: true }
46786
+ );
46787
+ const proxyUrl = `${endpoint}${proxyPath}`;
46788
+ log2.info("proxying task logs request", {
46789
+ taskId,
46790
+ assignedTo,
46791
+ endpoint,
46792
+ proxyPath,
46793
+ url: proxyUrl
46794
+ });
46795
+ if (!proxyRes.ok) throw new MeshyError("NODE_OFFLINE", `Worker log proxy failed (${proxyRes.status})`, 502);
46796
+ const data = await proxyRes.json();
46797
+ log2.debug("proxy returned", { logs: data.logs?.length ?? 0, total: data.total });
46798
+ res.json(data);
46799
+ return;
46800
+ } catch (err) {
46801
+ log2.warn("task logs proxy failed; falling back to keepalive control", {
46802
+ taskId,
46803
+ assignedTo,
46804
+ timeoutMs: TASK_LOG_PROXY_TIMEOUT_MS,
46805
+ ...describeProxyError3(err)
46806
+ });
46807
+ const fallback = await requestTaskLogsOverKeepalive(heartbeat, assignedTo, task, after);
46808
+ if (fallback) {
46809
+ sendWorkerControlResponse(res, fallback);
46810
+ return;
46811
+ }
46812
+ }
46813
+ }
46814
+ }
46815
+ const local = readLocalTaskLogsWithNativeHistory(engineRegistry, task, taskId, after, task?.agent ?? "claudecode");
46816
+ if (!proxyRequest.isProxy && isFollowerRemoteTask && local.total === 0 && await maybeProxyReadToLeader(req, res)) return;
46817
+ log2.debug("serving local task logs after proxy miss", {
46818
+ taskId,
46819
+ assignedTo: task?.assignedTo,
46820
+ selfId,
46821
+ total: local.total,
46822
+ after
46823
+ });
46824
+ res.json(local);
46825
+ }
46826
+
45406
46827
  // ../../packages/api/src/routes/task-output.ts
45407
- var import_express6 = __toESM(require_express2(), 1);
46828
+ var import_express7 = __toESM(require_express2(), 1);
45408
46829
 
45409
46830
  // ../../packages/api/src/app/request-origin.ts
45410
46831
  function getFirstHeaderValue(value) {
@@ -45458,7 +46879,7 @@ function resolveRequestOrigin(req) {
45458
46879
 
45459
46880
  // ../../packages/api/src/routes/task-output.ts
45460
46881
  var TASK_OUTPUT_PROXY_TIMEOUT_MS = 1e4;
45461
- function describeProxyError3(error) {
46882
+ function describeProxyError4(error) {
45462
46883
  if (error instanceof Error) {
45463
46884
  const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
45464
46885
  return {
@@ -45511,7 +46932,7 @@ function createTaskOutputProxyTrace(log2, taskId, assignedTo, kind, proxyPath) {
45511
46932
  attempt,
45512
46933
  totalEndpoints,
45513
46934
  timeoutMs,
45514
- ...describeProxyError3(error)
46935
+ ...describeProxyError4(error)
45515
46936
  });
45516
46937
  }
45517
46938
  };
@@ -45529,11 +46950,26 @@ function rewritePreviewPayloadIfNeeded(req, nodeId, payload) {
45529
46950
  }
45530
46951
  return rewritePreviewSessionPayloadForProxy(previewProxyManager, payload, nodeId);
45531
46952
  }
46953
+ function withTaskSnapshot(message, task) {
46954
+ if (!message || typeof message.payload !== "object" || message.payload === null) return message;
46955
+ return { ...message, payload: { ...message.payload, task } };
46956
+ }
46957
+ async function sendTaskOutputProxyResponse(req, res, nodeId, proxyRes, fallbackRequest) {
46958
+ if (fallbackRequest?.kind === "task.preview.create" && proxyRes.ok) {
46959
+ const body = await proxyRes.json().catch(() => null);
46960
+ if (isPreviewSessionPayload(body)) {
46961
+ res.status(proxyRes.status).json(rewritePreviewPayloadIfNeeded(req, nodeId, body));
46962
+ return;
46963
+ }
46964
+ }
46965
+ await sendProxyResponse(res, proxyRes);
46966
+ }
45532
46967
  async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, init, fallbackRequest) {
45533
46968
  const { taskEngine, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
45534
46969
  const log2 = rootLogger.child("tasks/output");
45535
46970
  const task = taskEngine.getTask(taskId);
45536
46971
  if (!task) {
46972
+ if (await maybeProxyReadToLeader(req, res, { methods: ["GET", "POST"] })) return true;
45537
46973
  throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
45538
46974
  }
45539
46975
  const selfId = nodeRegistry.getSelf()?.id;
@@ -45550,14 +46986,15 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
45550
46986
  throw new MeshyError("NODE_NOT_FOUND", `Assigned node ${assignedNodeId} not found`, 404);
45551
46987
  }
45552
46988
  if (!node.endpoint && !node.devtunnelEndpoint) {
45553
- if (fallbackRequest && canRequestNodeMessage(heartbeat)) {
46989
+ const hydratedFallbackRequest2 = withTaskSnapshot(fallbackRequest, task);
46990
+ if (hydratedFallbackRequest2 && canRequestNodeMessage(heartbeat)) {
45554
46991
  log2.warn("worker output endpoint missing, falling back to keepalive control", {
45555
46992
  taskId,
45556
46993
  assignedTo: assignedNodeId,
45557
- kind: fallbackRequest.kind
46994
+ kind: hydratedFallbackRequest2.kind
45558
46995
  });
45559
- const controlResponse = await requestFallbackNodeMessage(heartbeat, assignedNodeId, fallbackRequest);
45560
- if (fallbackRequest.kind === "task.preview.create" && controlResponse.bodyEncoding === "json" && isPreviewSessionPayload(controlResponse.body)) {
46996
+ const controlResponse = await requestFallbackNodeMessage(heartbeat, assignedNodeId, hydratedFallbackRequest2);
46997
+ if (hydratedFallbackRequest2.kind === "task.preview.create" && controlResponse.bodyEncoding === "json" && isPreviewSessionPayload(controlResponse.body)) {
45561
46998
  res.status(controlResponse.statusCode).json(
45562
46999
  rewritePreviewPayloadIfNeeded(req, assignedNodeId, controlResponse.body)
45563
47000
  );
@@ -45571,6 +47008,7 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
45571
47008
  const qs = new URL(req.originalUrl ?? req.url, "http://localhost").search;
45572
47009
  const proxyPath = `/api/tasks/${taskId}/output${subPath}${qs}`;
45573
47010
  const messageKind = fallbackRequest?.kind ?? "task.output.proxy";
47011
+ const hydratedFallbackRequest = withTaskSnapshot(fallbackRequest, task);
45574
47012
  try {
45575
47013
  const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
45576
47014
  node,
@@ -45587,26 +47025,35 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
45587
47025
  proxyPath,
45588
47026
  outputEndpoint: endpoint
45589
47027
  });
45590
- if (fallbackRequest?.kind === "task.preview.create" && proxyRes.ok) {
45591
- const body = await proxyRes.json().catch(() => null);
45592
- if (isPreviewSessionPayload(body)) {
45593
- res.status(proxyRes.status).json(rewritePreviewPayloadIfNeeded(req, assignedNodeId, body));
47028
+ if (proxyRes.status === 404) {
47029
+ const seededLogs = await seedTaskSnapshotOnWorker(task, [], node, log2).catch((seedError) => {
47030
+ log2.warn("failed to seed task snapshot after worker output 404", {
47031
+ taskId,
47032
+ assignedTo: assignedNodeId,
47033
+ kind: messageKind,
47034
+ error: seedError instanceof Error ? seedError.message : String(seedError)
47035
+ });
47036
+ return null;
47037
+ });
47038
+ if (seededLogs !== null) {
47039
+ const retry = await fetchNodeWithFallback(node, proxyPath, init, TASK_OUTPUT_PROXY_TIMEOUT_MS);
47040
+ await sendTaskOutputProxyResponse(req, res, assignedNodeId, retry.response, fallbackRequest);
45594
47041
  return true;
45595
47042
  }
45596
47043
  }
45597
- await sendProxyResponse(res, proxyRes);
47044
+ await sendTaskOutputProxyResponse(req, res, assignedNodeId, proxyRes, fallbackRequest);
45598
47045
  return true;
45599
47046
  } catch (err) {
45600
- if (fallbackRequest && canRequestNodeMessage(heartbeat)) {
47047
+ if (hydratedFallbackRequest && canRequestNodeMessage(heartbeat)) {
45601
47048
  log2.warn("worker output proxy failed, falling back to keepalive control", {
45602
47049
  taskId,
45603
47050
  assignedTo: assignedNodeId,
45604
- kind: fallbackRequest.kind,
47051
+ kind: hydratedFallbackRequest.kind,
45605
47052
  timeoutMs: TASK_OUTPUT_PROXY_TIMEOUT_MS,
45606
- ...describeProxyError3(err)
47053
+ ...describeProxyError4(err)
45607
47054
  });
45608
- const controlResponse = await requestFallbackNodeMessage(heartbeat, assignedNodeId, fallbackRequest);
45609
- if (fallbackRequest.kind === "task.preview.create" && controlResponse.bodyEncoding === "json" && isPreviewSessionPayload(controlResponse.body)) {
47055
+ const controlResponse = await requestFallbackNodeMessage(heartbeat, assignedNodeId, hydratedFallbackRequest);
47056
+ if (hydratedFallbackRequest.kind === "task.preview.create" && controlResponse.bodyEncoding === "json" && isPreviewSessionPayload(controlResponse.body)) {
45610
47057
  res.status(controlResponse.statusCode).json(
45611
47058
  rewritePreviewPayloadIfNeeded(req, assignedNodeId, controlResponse.body)
45612
47059
  );
@@ -45620,13 +47067,13 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
45620
47067
  assignedTo: assignedNodeId,
45621
47068
  kind: messageKind,
45622
47069
  timeoutMs: TASK_OUTPUT_PROXY_TIMEOUT_MS,
45623
- ...describeProxyError3(err)
47070
+ ...describeProxyError4(err)
45624
47071
  });
45625
47072
  throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
45626
47073
  }
45627
47074
  }
45628
47075
  function createTaskOutputRoutes(options = {}) {
45629
- const router = (0, import_express6.Router)();
47076
+ const router = (0, import_express7.Router)();
45630
47077
  const allowRemoteProxy = options.allowRemoteProxy ?? true;
45631
47078
  router.get("/:id/output", asyncHandler5(async (req, res) => {
45632
47079
  const taskId = req.params.id;
@@ -45747,62 +47194,6 @@ function createTaskOutputRoutes(options = {}) {
45747
47194
  var TERMINAL_STATUSES3 = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
45748
47195
  var ARCHIVABLE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "archived"]);
45749
47196
  var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned", "running"]);
45750
- var TASK_LOG_PROXY_TIMEOUT_MS = 1e4;
45751
- function describeProxyError4(error) {
45752
- if (error instanceof Error) {
45753
- const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
45754
- return {
45755
- errorName: error.name,
45756
- errorMessage: error.message,
45757
- errorCategory
45758
- };
45759
- }
45760
- return {
45761
- errorName: "UnknownError",
45762
- errorMessage: String(error),
45763
- errorCategory: "unknown"
45764
- };
45765
- }
45766
- function createTaskLogsProxyTrace(log2, taskId, nodeId, proxyPath) {
45767
- return {
45768
- onAttempt: ({ attempt, endpoint, timeoutMs, totalEndpoints }) => {
45769
- log2.debug("task logs proxy attempt", {
45770
- taskId,
45771
- nodeId,
45772
- proxyPath,
45773
- endpoint,
45774
- attempt,
45775
- totalEndpoints,
45776
- timeoutMs
45777
- });
45778
- },
45779
- onResponse: ({ attempt, endpoint, response, timeoutMs, totalEndpoints }) => {
45780
- log2.info("task logs proxy response", {
45781
- taskId,
45782
- nodeId,
45783
- proxyPath,
45784
- endpoint,
45785
- attempt,
45786
- totalEndpoints,
45787
- timeoutMs,
45788
- ok: response.ok,
45789
- statusCode: response.status
45790
- });
45791
- },
45792
- onError: ({ attempt, endpoint, error, timeoutMs, totalEndpoints }) => {
45793
- log2.warn("task logs proxy attempt failed", {
45794
- taskId,
45795
- nodeId,
45796
- proxyPath,
45797
- endpoint,
45798
- attempt,
45799
- totalEndpoints,
45800
- timeoutMs,
45801
- ...describeProxyError4(error)
45802
- });
45803
- }
45804
- };
45805
- }
45806
47197
  function shouldGenerateTitle(task) {
45807
47198
  return task.payload.titleSource === "derived";
45808
47199
  }
@@ -45917,7 +47308,7 @@ function buildShareUrl(origin, shareId) {
45917
47308
  return `${origin.replace(/\/+$/, "")}/shared/tasks/${encodeURIComponent(shareId)}`;
45918
47309
  }
45919
47310
  function createTaskRoutes() {
45920
- const router = (0, import_express7.Router)();
47311
+ const router = (0, import_express8.Router)();
45921
47312
  router.post("/", asyncHandler6(async (req, res) => {
45922
47313
  const { taskEngine, nodeRegistry, liteAgentRunner, logger: rootLogger, workDir } = req.app.locals.deps;
45923
47314
  const body = CreateTaskBody.parse(req.body);
@@ -45940,6 +47331,17 @@ function createTaskRoutes() {
45940
47331
  scheduleTitleGeneration({ taskEngine, liteAgentRunner, logger: rootLogger, workDir }, task);
45941
47332
  res.status(201).json(withAssignedNodeMetadata(task, nodeRegistry));
45942
47333
  }));
47334
+ router.post("/import-session", asyncHandler6(async (req, res) => {
47335
+ const { taskEngine, nodeRegistry, engineRegistry, logger: rootLogger, shareOrigin } = req.app.locals.deps;
47336
+ const body = AttachNativeSessionBody.parse(req.body);
47337
+ const importedTask = await attachNativeSession({
47338
+ taskEngine,
47339
+ nodeRegistry,
47340
+ engineRegistry,
47341
+ logger: rootLogger
47342
+ }, body);
47343
+ res.status(201).json(toTaskResponse(importedTask, nodeRegistry, taskEngine, shareOrigin));
47344
+ }));
45943
47345
  router.get("/", asyncHandler6(async (req, res) => {
45944
47346
  const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
45945
47347
  const query = TaskListQuery.parse(req.query);
@@ -45991,6 +47393,7 @@ function createTaskRoutes() {
45991
47393
  const taskId = req.params.id;
45992
47394
  const task = taskEngine.getTask(taskId);
45993
47395
  if (!task) {
47396
+ if (await maybeProxyReadToLeader(req, res)) return;
45994
47397
  throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
45995
47398
  }
45996
47399
  res.json(toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin));
@@ -46049,13 +47452,14 @@ function createTaskRoutes() {
46049
47452
  const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
46050
47453
  const log2 = rootLogger.child("tasks/patch");
46051
47454
  const updates = UpdateTaskBody.parse(req.body);
46052
- const existing = taskEngine.getTask(req.params.id);
47455
+ const taskId = req.params.id;
47456
+ const existing = taskEngine.getTask(taskId);
46053
47457
  if (!existing) {
46054
- throw new MeshyError("TASK_NOT_FOUND", `Task ${req.params.id} not found`, 404);
47458
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46055
47459
  }
46056
47460
  if (updates.status !== void 0 && TERMINAL_STATUSES3.has(existing.status) && ACTIVE_STATUSES.has(updates.status)) {
46057
47461
  log2.warn("ignoring stale status regression for terminal task", {
46058
- taskId: req.params.id,
47462
+ taskId,
46059
47463
  currentStatus: existing.status,
46060
47464
  incomingStatus: updates.status
46061
47465
  });
@@ -46071,33 +47475,35 @@ function createTaskRoutes() {
46071
47475
  }
46072
47476
  if (updates.status !== void 0 && existing.status === "archived" && updates.status !== "archived") {
46073
47477
  log2.warn("ignoring status change for archived task", {
46074
- taskId: req.params.id,
47478
+ taskId,
46075
47479
  currentStatus: existing.status,
46076
47480
  incomingStatus: updates.status
46077
47481
  });
46078
47482
  res.json(withAssignedNodeMetadata(existing, nodeRegistry));
46079
47483
  return;
46080
47484
  }
46081
- const task = taskEngine.updateTask(req.params.id, updates);
47485
+ const task = taskEngine.updateTask(taskId, updates);
46082
47486
  if (!task) {
46083
- throw new MeshyError("TASK_NOT_FOUND", `Task ${req.params.id} not found`, 404);
47487
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46084
47488
  }
46085
47489
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
46086
47490
  }));
46087
47491
  router.delete("/:id", asyncHandler6(async (req, res) => {
46088
47492
  const { taskEngine } = req.app.locals.deps;
46089
- const result = taskEngine.deleteTask(req.params.id);
47493
+ const taskId = req.params.id;
47494
+ const result = taskEngine.deleteTask(taskId);
46090
47495
  if (!result) {
46091
- throw new MeshyError("TASK_NOT_FOUND", `Task ${req.params.id} not found`, 404);
47496
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46092
47497
  }
46093
47498
  res.json({ ok: true });
46094
47499
  }));
46095
47500
  router.post("/:id/cancel", asyncHandler6(async (req, res) => {
46096
47501
  const { taskEngine, nodeRegistry, engineRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
46097
47502
  const log2 = rootLogger.child("tasks/cancel");
46098
- const task = taskEngine.getTask(req.params.id);
47503
+ const taskId = req.params.id;
47504
+ const task = taskEngine.getTask(taskId);
46099
47505
  if (!task) {
46100
- throw new MeshyError("TASK_NOT_FOUND", `Task ${req.params.id} not found`, 404);
47506
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46101
47507
  }
46102
47508
  if (TERMINAL_STATUSES3.has(task.status)) {
46103
47509
  throw new MeshyError("VALIDATION_ERROR", `Task ${task.id} cannot be cancelled (status: ${task.status})`, 400);
@@ -46141,97 +47547,16 @@ function createTaskRoutes() {
46141
47547
  res.json(withAssignedNodeMetadata(task, nodeRegistry));
46142
47548
  }));
46143
47549
  router.get("/:id/logs", asyncHandler6(async (req, res) => {
46144
- const { engineRegistry, taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
46145
- const log2 = rootLogger.child("tasks/logs");
46146
- const query = TaskLogsQuery.parse(req.query);
46147
- const after = query.after ?? 0;
46148
- const taskId = req.params.id;
46149
- const task = taskEngine.getTask(taskId);
46150
- const selfId = nodeRegistry.getSelf()?.id;
46151
- const isLeader = nodeRegistry.isLeader();
46152
- const needsProxy = isLeader && !!(task?.assignedTo && task.assignedTo !== selfId);
46153
- log2.debug("log request", {
46154
- taskId,
46155
- assignedTo: task?.assignedTo,
46156
- selfId,
46157
- isLeader,
46158
- needsProxy
46159
- });
46160
- if (isLeader) {
46161
- const local2 = readLocalTaskLogs(engineRegistry, taskId, after, task?.agent ?? "claudecode");
46162
- if (local2.total > 0 || !needsProxy) {
46163
- log2.debug("serving leader-local task logs", {
46164
- taskId,
46165
- assignedTo: task?.assignedTo,
46166
- selfId,
46167
- total: local2.total,
46168
- after
46169
- });
46170
- res.json(local2);
46171
- return;
46172
- }
46173
- log2.debug("leader-local task log missing, falling back to worker proxy", {
46174
- taskId,
46175
- assignedTo: task?.assignedTo,
46176
- selfId
46177
- });
46178
- }
46179
- if (needsProxy) {
46180
- const node = nodeRegistry.getNode(task.assignedTo);
46181
- log2.debug("proxy target", { nodeId: node?.id, endpoint: node?.endpoint, devtunnel: node?.devtunnelEndpoint, status: node?.status });
46182
- if (node) {
46183
- const proxyPath = `/api/tasks/${taskId}/logs?after=${after}`;
46184
- try {
46185
- const { endpoint, response: proxyRes } = await fetchNodeWithFallback(
46186
- node,
46187
- proxyPath,
46188
- void 0,
46189
- TASK_LOG_PROXY_TIMEOUT_MS,
46190
- createTaskLogsProxyTrace(log2, taskId, node.id, proxyPath),
46191
- { preferPublicEndpoint: true }
46192
- );
46193
- const proxyUrl = `${endpoint}${proxyPath}`;
46194
- log2.info("proxying task logs request", {
46195
- taskId,
46196
- assignedTo: task.assignedTo,
46197
- endpoint,
46198
- proxyPath,
46199
- url: proxyUrl
46200
- });
46201
- log2.debug("proxy response", { status: proxyRes.status });
46202
- if (proxyRes.ok) {
46203
- const data = await proxyRes.json();
46204
- log2.debug("proxy returned", { logs: data?.logs?.length ?? 0, total: data?.total });
46205
- res.json(data);
46206
- return;
46207
- }
46208
- } catch (err) {
46209
- log2.warn("task logs proxy failed; serving local logs after proxy miss", {
46210
- taskId,
46211
- assignedTo: task.assignedTo,
46212
- timeoutMs: TASK_LOG_PROXY_TIMEOUT_MS,
46213
- ...describeProxyError4(err)
46214
- });
46215
- }
46216
- }
46217
- }
46218
- const local = readLocalTaskLogs(engineRegistry, taskId, after, task?.agent ?? "claudecode");
46219
- log2.debug("serving local task logs after proxy miss", {
46220
- taskId,
46221
- assignedTo: task?.assignedTo,
46222
- selfId,
46223
- total: local.total,
46224
- after
46225
- });
46226
- res.json(local);
47550
+ await sendTaskLogsResponse(req, res, req.params.id);
46227
47551
  }));
46228
47552
  router.post("/:id/message", asyncHandler6(async (req, res) => {
46229
47553
  const { taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
46230
47554
  const log2 = rootLogger.child("tasks/message");
46231
47555
  const body = SendMessageBody.parse(req.body);
46232
- const task = taskEngine.getTask(req.params.id);
47556
+ const taskId = req.params.id;
47557
+ const task = taskEngine.getTask(taskId);
46233
47558
  if (!task) {
46234
- throw new MeshyError("TASK_NOT_FOUND", `Task ${req.params.id} not found`, 404);
47559
+ throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
46235
47560
  }
46236
47561
  if (!supportsFollowUpAgent(task.agent)) {
46237
47562
  throw new MeshyError("VALIDATION_ERROR", `Agent ${task.agent} does not support chat messages`, 400);
@@ -46287,7 +47612,7 @@ function createTaskRoutes() {
46287
47612
  }
46288
47613
 
46289
47614
  // ../../packages/api/src/routes/shared.ts
46290
- var import_express8 = __toESM(require_express2(), 1);
47615
+ var import_express9 = __toESM(require_express2(), 1);
46291
47616
  function asyncHandler7(fn) {
46292
47617
  return (req, res, next) => fn(req, res, next).catch(next);
46293
47618
  }
@@ -46315,6 +47640,7 @@ function toSharedConversation(share, task) {
46315
47640
  title: task.title,
46316
47641
  description: task.description,
46317
47642
  agent: task.agent,
47643
+ conversationKind: task.conversationKind,
46318
47644
  status: task.status,
46319
47645
  priority: task.priority,
46320
47646
  assignedNodeName: task.assignedNodeName ?? null,
@@ -46326,7 +47652,7 @@ function toSharedConversation(share, task) {
46326
47652
  };
46327
47653
  }
46328
47654
  function createSharedRoutes() {
46329
- const router = (0, import_express8.Router)();
47655
+ const router = (0, import_express9.Router)();
46330
47656
  router.get("/conversations/:shareId", asyncHandler7(async (req, res) => {
46331
47657
  const { taskEngine } = req.app.locals.deps;
46332
47658
  const shareId = req.params.shareId;
@@ -46338,15 +47664,10 @@ function createSharedRoutes() {
46338
47664
  res.json(toSharedConversation(share, task));
46339
47665
  }));
46340
47666
  router.get("/conversations/:shareId/logs", asyncHandler7(async (req, res) => {
46341
- const { taskEngine, engineRegistry } = req.app.locals.deps;
46342
- const query = TaskLogsQuery.parse(req.query);
47667
+ const { taskEngine } = req.app.locals.deps;
46343
47668
  const shareId = req.params.shareId;
46344
47669
  const share = assertActiveShare(taskEngine.getTaskShare(shareId));
46345
- const task = taskEngine.getTask(share.taskId);
46346
- if (!task) {
46347
- throw new MeshyError("TASK_NOT_FOUND", "Shared conversation task not found", 404);
46348
- }
46349
- res.json(readLocalTaskLogs(engineRegistry, task.id, query.after ?? 0, task.agent));
47670
+ await sendTaskLogsResponse(req, res, share.taskId);
46350
47671
  }));
46351
47672
  router.get("/conversations/:shareId/output", asyncHandler7(async (req, res) => {
46352
47673
  const { taskEngine } = req.app.locals.deps;
@@ -46441,7 +47762,7 @@ function createSharedRoutes() {
46441
47762
  }
46442
47763
 
46443
47764
  // ../../packages/api/src/routes/worker.ts
46444
- var import_express9 = __toESM(require_express2(), 1);
47765
+ var import_express10 = __toESM(require_express2(), 1);
46445
47766
  var WorkerMessageBody = external_exports.object({
46446
47767
  taskId: external_exports.string().min(1)
46447
47768
  }).and(SendMessageBody);
@@ -46452,7 +47773,7 @@ function asyncHandler8(fn) {
46452
47773
  return (req, res, next) => fn(req, res, next).catch(next);
46453
47774
  }
46454
47775
  function createWorkerRoutes() {
46455
- const router = (0, import_express9.Router)();
47776
+ const router = (0, import_express10.Router)();
46456
47777
  router.post("/execute", asyncHandler8(async (req, res) => {
46457
47778
  const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: rootLogger, workDir } = req.app.locals.deps;
46458
47779
  const log2 = rootLogger.child("worker/execute");
@@ -46470,6 +47791,21 @@ function createWorkerRoutes() {
46470
47791
  });
46471
47792
  res.json({ ok: true });
46472
47793
  }));
47794
+ router.post("/import-task", asyncHandler8(async (req, res) => {
47795
+ const { taskEngine, engineRegistry } = req.app.locals.deps;
47796
+ const body = WorkerImportTaskBody.parse(req.body);
47797
+ const { task } = body;
47798
+ let { logs } = body;
47799
+ if (logs.length === 0 && task.conversationKind === "nativeSession") {
47800
+ const sessionId = typeof task.payload?.sessionId === "string" ? task.payload.sessionId : "";
47801
+ if (sessionId && (task.agent === "codex" || task.agent === "claudecode")) {
47802
+ logs = loadNativeSessionHistory({ agent: task.agent, sessionId }).logs;
47803
+ }
47804
+ }
47805
+ taskEngine.importTasks([task]);
47806
+ recordLocalTaskLogs(engineRegistry, task, logs);
47807
+ res.status(201).json({ ok: true, task, logs });
47808
+ }));
46473
47809
  router.post("/message", asyncHandler8(async (req, res) => {
46474
47810
  const { engineRegistry, taskEngine, nodeRegistry, eventBus, logger: rootLogger } = req.app.locals.deps;
46475
47811
  const log2 = rootLogger.child("worker/message");
@@ -46651,129 +47987,12 @@ function normalizeNodeMessageResponse(value) {
46651
47987
  }
46652
47988
 
46653
47989
  // ../../packages/api/src/routes/system.ts
46654
- var import_express10 = __toESM(require_express2(), 1);
46655
-
46656
- // ../../packages/api/src/app/system-info.ts
46657
- var os5 = __toESM(require("os"), 1);
46658
- var import_node_child_process8 = require("child_process");
46659
- var RUNTIME_TOOLS = [
46660
- { id: "claude", label: "Claude Code", command: "claude" },
46661
- { id: "codex", label: "Codex", command: "codex" }
46662
- ];
46663
- function normalizeOutput(output) {
46664
- if (!output) {
46665
- return null;
46666
- }
46667
- const firstLine = output.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
46668
- return firstLine ?? null;
46669
- }
46670
- function resolveCommandPath(command) {
46671
- const lookupCommand = process.platform === "win32" ? "where" : "which";
46672
- const result = (0, import_node_child_process8.spawnSync)(lookupCommand, [command], {
46673
- encoding: "utf-8",
46674
- shell: false,
46675
- windowsHide: true,
46676
- timeout: 1500
46677
- });
46678
- if (result.status === 0) {
46679
- return { path: normalizeOutput(result.stdout) };
46680
- }
46681
- return {
46682
- path: null,
46683
- detail: normalizeOutput(result.stderr) ?? result.error?.message ?? null
46684
- };
46685
- }
46686
- function inspectTool(definition) {
46687
- const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
46688
- const resolved = resolveCommandPath(definition.command);
46689
- if (!resolved.path) {
46690
- return {
46691
- id: definition.id,
46692
- label: definition.label,
46693
- command: definition.command,
46694
- available: false,
46695
- path: null,
46696
- version: null,
46697
- checkedAt,
46698
- detail: resolved.detail ?? "Command not found on PATH"
46699
- };
46700
- }
46701
- const versionResult = (0, import_node_child_process8.spawnSync)(definition.command, ["--version"], {
46702
- encoding: "utf-8",
46703
- shell: process.platform === "win32",
46704
- windowsHide: true,
46705
- timeout: 2500
46706
- });
46707
- const version2 = normalizeOutput(versionResult.stdout) ?? normalizeOutput(versionResult.stderr);
46708
- const detail = versionResult.status === 0 ? null : normalizeOutput(versionResult.stderr) ?? versionResult.error?.message ?? "Version check failed";
46709
- return {
46710
- id: definition.id,
46711
- label: definition.label,
46712
- command: definition.command,
46713
- available: true,
46714
- path: resolved.path,
46715
- version: version2,
46716
- checkedAt,
46717
- detail
46718
- };
46719
- }
46720
- function inspectRuntimeTools() {
46721
- return RUNTIME_TOOLS.map(inspectTool);
46722
- }
46723
- function getOsSnapshot() {
46724
- const cpus2 = os5.cpus();
46725
- return {
46726
- platform: os5.platform(),
46727
- release: os5.release(),
46728
- arch: os5.arch(),
46729
- hostname: os5.hostname(),
46730
- cpuModel: cpus2[0]?.model ?? null,
46731
- cpuCount: cpus2.length,
46732
- totalMemoryBytes: os5.totalmem(),
46733
- freeMemoryBytes: os5.freemem()
46734
- };
46735
- }
46736
- function buildNodeSettingsSnapshot(options) {
46737
- const uptime = process.uptime();
46738
- const runtimeMetadata = options.runtimeMetadata;
46739
- const agents = (options.inspectRuntimeTools?.() ?? inspectRuntimeTools()).map((agent) => ({
46740
- ...agent,
46741
- metadataStatus: runtimeMetadata?.components?.[agent.id]?.status ?? null
46742
- }));
46743
- return {
46744
- collectedAt: Date.now(),
46745
- version: runtimeMetadata?.packageVersion ?? "0.1.0",
46746
- packageName: runtimeMetadata?.packageName ?? "meshy",
46747
- uptime,
46748
- auth: options.auth,
46749
- os: getOsSnapshot(),
46750
- runtime: {
46751
- nodeVersion: process.version,
46752
- pid: process.pid,
46753
- startedAt: Date.now() - Math.floor(uptime * 1e3),
46754
- cwd: process.cwd(),
46755
- workDir: options.workDir ?? null,
46756
- storagePath: options.storagePath ?? null,
46757
- localDashboardOrigin: options.localDashboardOrigin ?? null
46758
- },
46759
- agents,
46760
- startupRequirements: {
46761
- lastCheckedAt: runtimeMetadata?.startupRequirementsLastCheckedAt,
46762
- lastCheckedOn: runtimeMetadata?.startupRequirementsLastCheckedOn,
46763
- components: runtimeMetadata?.components ?? {}
46764
- },
46765
- components: runtimeMetadata?.components ?? {},
46766
- repository: runtimeMetadata?.repository ?? {},
46767
- packages: runtimeMetadata?.packages ?? {}
46768
- };
46769
- }
46770
-
46771
- // ../../packages/api/src/routes/system.ts
47990
+ var import_express11 = __toESM(require_express2(), 1);
46772
47991
  function asyncHandler9(fn) {
46773
47992
  return (req, res, next) => fn(req, res, next).catch(next);
46774
47993
  }
46775
47994
  function createSystemRoutes() {
46776
- const router = (0, import_express10.Router)();
47995
+ const router = (0, import_express11.Router)();
46777
47996
  router.get("/health", asyncHandler9(async (req, res) => {
46778
47997
  const { logger: rootLogger } = req.app.locals.deps;
46779
47998
  rootLogger.child("system/health").info("received system health API call", {
@@ -46834,8 +48053,8 @@ function createSystemRoutes() {
46834
48053
  return;
46835
48054
  }
46836
48055
  const { type } = req.body;
46837
- if (!type || !["direct", "devtunnel", "tailscale"].includes(type)) {
46838
- res.status(400).json({ error: "Invalid transport type. Must be: direct, devtunnel, or tailscale" });
48056
+ if (!type || !["direct", "devtunnel"].includes(type)) {
48057
+ res.status(400).json({ error: "Invalid transport type. Must be: direct or devtunnel" });
46839
48058
  return;
46840
48059
  }
46841
48060
  const newEndpoint = await switchTransport(type);
@@ -46879,7 +48098,7 @@ function createSystemRoutes() {
46879
48098
  }
46880
48099
 
46881
48100
  // ../../packages/api/src/routes/events.ts
46882
- var import_express11 = __toESM(require_express2(), 1);
48101
+ var import_express12 = __toESM(require_express2(), 1);
46883
48102
  var HEARTBEAT_INTERVAL_MS = 15e3;
46884
48103
  var CATEGORY_MAP = {
46885
48104
  tasks: "task.",
@@ -46915,9 +48134,10 @@ function shouldIncludeEvent(eventName, categories) {
46915
48134
  });
46916
48135
  }
46917
48136
  function createEventRoutes() {
46918
- const router = (0, import_express11.Router)();
48137
+ const router = (0, import_express12.Router)();
46919
48138
  router.get("/", (req, res) => {
46920
48139
  const { eventBus } = req.app.locals.deps;
48140
+ const stream = res;
46921
48141
  const categories = parseFilter(req.query.filter);
46922
48142
  res.writeHead(200, {
46923
48143
  "Content-Type": "text/event-stream",
@@ -46934,20 +48154,14 @@ data: ${JSON.stringify(data)}
46934
48154
 
46935
48155
  `;
46936
48156
  res.write(payload);
46937
- if (typeof res.flush === "function") {
46938
- ;
46939
- res.flush();
46940
- }
48157
+ stream.flush?.();
46941
48158
  };
46942
48159
  listeners.set(eventName, listener);
46943
48160
  eventBus.on(eventName, listener);
46944
48161
  }
46945
48162
  const heartbeatTimer = setInterval(() => {
46946
48163
  res.write(": heartbeat\n\n");
46947
- if (typeof res.flush === "function") {
46948
- ;
46949
- res.flush();
46950
- }
48164
+ stream.flush?.();
46951
48165
  }, HEARTBEAT_INTERVAL_MS);
46952
48166
  req.on("close", () => {
46953
48167
  clearInterval(heartbeatTimer);
@@ -47000,8 +48214,8 @@ function isAllowedSharePath(pathname) {
47000
48214
  function resolveRuntimeBaseDir() {
47001
48215
  const entryPath = process.argv[1];
47002
48216
  if (typeof entryPath === "string" && entryPath.length > 0) {
47003
- const resolved = fs17.realpathSync(path18.resolve(entryPath));
47004
- return path18.dirname(resolved);
48217
+ const resolved = fs18.realpathSync(path19.resolve(entryPath));
48218
+ return path19.dirname(resolved);
47005
48219
  }
47006
48220
  return process.cwd();
47007
48221
  }
@@ -47009,25 +48223,25 @@ function resolveStaticDir(baseDir) {
47009
48223
  const envStaticDir = process.env.MESHY_STATIC_DIR;
47010
48224
  const candidateDirs = [
47011
48225
  envStaticDir,
47012
- path18.resolve(baseDir, "dashboard"),
47013
- path18.resolve(baseDir, "../dashboard"),
47014
- path18.resolve(baseDir, "../../dashboard/dist"),
47015
- path18.resolve(baseDir, "../../../packages/dashboard/dist"),
47016
- path18.resolve(baseDir, "../public"),
47017
- path18.resolve(baseDir, "../../packages/api/public"),
47018
- path18.resolve(baseDir, "../../../packages/api/public"),
47019
- path18.resolve(process.cwd(), "packages/dashboard/dist"),
47020
- path18.resolve(process.cwd(), "packages/api/public")
48226
+ path19.resolve(baseDir, "dashboard"),
48227
+ path19.resolve(baseDir, "../dashboard"),
48228
+ path19.resolve(baseDir, "../../dashboard/dist"),
48229
+ path19.resolve(baseDir, "../../../packages/dashboard/dist"),
48230
+ path19.resolve(baseDir, "../public"),
48231
+ path19.resolve(baseDir, "../../packages/api/public"),
48232
+ path19.resolve(baseDir, "../../../packages/api/public"),
48233
+ path19.resolve(process.cwd(), "packages/dashboard/dist"),
48234
+ path19.resolve(process.cwd(), "packages/api/public")
47021
48235
  ].filter((value) => typeof value === "string" && value.length > 0);
47022
48236
  for (const candidate of candidateDirs) {
47023
- if (fs17.existsSync(candidate)) {
48237
+ if (fs18.existsSync(candidate)) {
47024
48238
  return candidate;
47025
48239
  }
47026
48240
  }
47027
48241
  return null;
47028
48242
  }
47029
48243
  function createServer2(deps) {
47030
- const app = (0, import_express12.default)();
48244
+ const app = (0, import_express13.default)();
47031
48245
  app.locals.deps = deps;
47032
48246
  if (typeof deps.heartbeat.setNodeMessageHandler === "function") {
47033
48247
  deps.heartbeat.setNodeMessageHandler((message) => handleNodeMessage(deps, message));
@@ -47068,7 +48282,7 @@ function createServer2(deps) {
47068
48282
  const runtimeBaseDir = resolveRuntimeBaseDir();
47069
48283
  const staticDir = resolveStaticDir(runtimeBaseDir);
47070
48284
  if (staticDir) {
47071
- const staticMiddleware = import_express12.default.static(staticDir);
48285
+ const staticMiddleware = import_express13.default.static(staticDir);
47072
48286
  app.use((req, res, next) => {
47073
48287
  if (isApiRequest(req)) {
47074
48288
  next();
@@ -47081,7 +48295,7 @@ function createServer2(deps) {
47081
48295
  staticMiddleware(req, res, next);
47082
48296
  });
47083
48297
  }
47084
- app.use(import_express12.default.json({ limit: JSON_BODY_LIMIT }));
48298
+ app.use(import_express13.default.json({ limit: JSON_BODY_LIMIT }));
47085
48299
  app.use(createAuthMiddleware(authConfig));
47086
48300
  app.use((req, res, next) => {
47087
48301
  void (async () => {
@@ -47103,7 +48317,7 @@ function createServer2(deps) {
47103
48317
  })().catch(next);
47104
48318
  });
47105
48319
  app.use(createRoutingMiddleware(deps.dataRouter));
47106
- const largeBodyParser = import_express12.default.json({ limit: JSON_BODY_LIMIT_LARGE });
48320
+ const largeBodyParser = import_express13.default.json({ limit: JSON_BODY_LIMIT_LARGE });
47107
48321
  app.use("/api/cluster", createClusterRoutes());
47108
48322
  app.use("/api/cluster-control", createClusterControlRoutes());
47109
48323
  app.use("/api/node", largeBodyParser, createNodeMessageRoutes());
@@ -47114,8 +48328,8 @@ function createServer2(deps) {
47114
48328
  app.use("/api/system", createSystemRoutes());
47115
48329
  app.use("/api/events", createEventRoutes());
47116
48330
  if (staticDir) {
47117
- const indexPath = path18.join(staticDir, "index.html");
47118
- if (fs17.existsSync(indexPath)) {
48331
+ const indexPath = path19.join(staticDir, "index.html");
48332
+ if (fs18.existsSync(indexPath)) {
47119
48333
  app.get("*", (req, res, next) => {
47120
48334
  if (isApiRequest(req)) {
47121
48335
  next();
@@ -47199,10 +48413,10 @@ var DirectTransport = class {
47199
48413
  };
47200
48414
 
47201
48415
  // ../../packages/transport/src/devtunnel.ts
47202
- var import_node_child_process9 = require("child_process");
48416
+ var import_node_child_process10 = require("child_process");
47203
48417
  function isInstalled(cmd) {
47204
48418
  try {
47205
- (0, import_node_child_process9.execSync)(process.platform === "win32" ? `where ${cmd}` : `command -v ${cmd}`, { stdio: "pipe" });
48419
+ (0, import_node_child_process10.execSync)(process.platform === "win32" ? `where ${cmd}` : `command -v ${cmd}`, { stdio: "pipe" });
47206
48420
  return true;
47207
48421
  } catch {
47208
48422
  return false;
@@ -47225,14 +48439,14 @@ var DevTunnelTransport = class {
47225
48439
  );
47226
48440
  }
47227
48441
  try {
47228
- (0, import_node_child_process9.execSync)("devtunnel user show", { stdio: "pipe" });
48442
+ (0, import_node_child_process10.execSync)("devtunnel user show", { stdio: "pipe" });
47229
48443
  } catch {
47230
48444
  throw new Error(
47231
48445
  "Not logged in to devtunnel. Run: devtunnel user login"
47232
48446
  );
47233
48447
  }
47234
48448
  const hostArgs = this.buildHostArgs(localPort);
47235
- const child = (0, import_node_child_process9.spawn)("devtunnel", hostArgs, {
48449
+ const child = (0, import_node_child_process10.spawn)("devtunnel", hostArgs, {
47236
48450
  stdio: ["pipe", "pipe", "pipe"]
47237
48451
  });
47238
48452
  this.process = child;
@@ -47337,7 +48551,7 @@ ${lines.join("")}`
47337
48551
  return;
47338
48552
  }
47339
48553
  try {
47340
- (0, import_node_child_process9.execFileSync)("devtunnel", ["access", "create", tunnelId, "--tenant"], { stdio: "pipe" });
48554
+ (0, import_node_child_process10.execFileSync)("devtunnel", ["access", "create", tunnelId, "--tenant"], { stdio: "pipe" });
47341
48555
  } catch (err) {
47342
48556
  if (isExistingTenantAccessError(err)) {
47343
48557
  return;
@@ -47353,7 +48567,7 @@ ${lines.join("")}`
47353
48567
  return void 0;
47354
48568
  }
47355
48569
  try {
47356
- (0, import_node_child_process9.execFileSync)("devtunnel", ["show", tunnelId], { stdio: "pipe" });
48570
+ (0, import_node_child_process10.execFileSync)("devtunnel", ["show", tunnelId], { stdio: "pipe" });
47357
48571
  return tunnelId;
47358
48572
  } catch {
47359
48573
  const createArgs = ["create", tunnelId];
@@ -47361,7 +48575,7 @@ ${lines.join("")}`
47361
48575
  createArgs.push("-a");
47362
48576
  }
47363
48577
  try {
47364
- (0, import_node_child_process9.execFileSync)("devtunnel", createArgs, { stdio: "pipe" });
48578
+ (0, import_node_child_process10.execFileSync)("devtunnel", createArgs, { stdio: "pipe" });
47365
48579
  return tunnelId;
47366
48580
  } catch (err) {
47367
48581
  throw new Error(
@@ -47373,13 +48587,13 @@ ${lines.join("")}`
47373
48587
  ensureTunnelPort(tunnelId, localPort) {
47374
48588
  const ports = this.listTunnelPorts(tunnelId);
47375
48589
  for (const stalePort of ports.filter((p) => p !== localPort)) {
47376
- (0, import_node_child_process9.execFileSync)("devtunnel", ["port", "delete", tunnelId, "-p", String(stalePort)], { stdio: "pipe" });
48590
+ (0, import_node_child_process10.execFileSync)("devtunnel", ["port", "delete", tunnelId, "-p", String(stalePort)], { stdio: "pipe" });
47377
48591
  }
47378
48592
  if (ports.includes(localPort)) {
47379
48593
  return;
47380
48594
  }
47381
48595
  try {
47382
- (0, import_node_child_process9.execFileSync)(
48596
+ (0, import_node_child_process10.execFileSync)(
47383
48597
  "devtunnel",
47384
48598
  ["port", "create", tunnelId, "-p", String(localPort), "--protocol", "http"],
47385
48599
  { stdio: "pipe" }
@@ -47395,7 +48609,7 @@ ${lines.join("")}`
47395
48609
  }
47396
48610
  listTunnelPorts(tunnelId) {
47397
48611
  try {
47398
- const output = (0, import_node_child_process9.execFileSync)("devtunnel", ["port", "list", tunnelId, "-j"], { stdio: "pipe" });
48612
+ const output = (0, import_node_child_process10.execFileSync)("devtunnel", ["port", "list", tunnelId, "-j"], { stdio: "pipe" });
47399
48613
  const parsed = JSON.parse(output.toString());
47400
48614
  const items = Array.isArray(parsed) ? parsed : parsed && typeof parsed === "object" && Array.isArray(parsed.ports) ? parsed.ports : parsed && typeof parsed === "object" && Array.isArray(parsed.value) ? parsed.value : [];
47401
48615
  return items.map((item) => getPortNumber(item)).filter((value) => value !== void 0);
@@ -47407,7 +48621,7 @@ ${lines.join("")}`
47407
48621
  }
47408
48622
  hasTunnelPort(tunnelId, localPort) {
47409
48623
  try {
47410
- (0, import_node_child_process9.execFileSync)(
48624
+ (0, import_node_child_process10.execFileSync)(
47411
48625
  "devtunnel",
47412
48626
  ["port", "show", tunnelId, "-p", String(localPort), "-j"],
47413
48627
  { stdio: "pipe" }
@@ -47484,16 +48698,42 @@ function createTransport(config) {
47484
48698
  }
47485
48699
  }
47486
48700
 
48701
+ // src/bootstrap/terminal-writer.ts
48702
+ function formatDetail(detail) {
48703
+ if (detail instanceof Error) {
48704
+ return detail.stack ?? detail.message;
48705
+ }
48706
+ if (typeof detail === "string") {
48707
+ return detail;
48708
+ }
48709
+ try {
48710
+ return JSON.stringify(detail);
48711
+ } catch {
48712
+ return String(detail);
48713
+ }
48714
+ }
48715
+ var terminalWriter = {
48716
+ error(message, ...details) {
48717
+ const suffix = details.length > 0 ? ` ${details.map(formatDetail).join(" ")}` : "";
48718
+ process.stderr.write(`${message}${suffix}
48719
+ `);
48720
+ },
48721
+ line(message = "") {
48722
+ process.stdout.write(`${message}
48723
+ `);
48724
+ }
48725
+ };
48726
+
47487
48727
  // src/startup.ts
47488
- var fs18 = __toESM(require("fs"), 1);
47489
- var path19 = __toESM(require("path"), 1);
48728
+ var fs19 = __toESM(require("fs"), 1);
48729
+ var path20 = __toESM(require("path"), 1);
47490
48730
  var readline = __toESM(require("readline/promises"), 1);
47491
- var import_node_child_process10 = require("child_process");
48731
+ var import_node_child_process11 = require("child_process");
47492
48732
  function getDefaultNodeName() {
47493
48733
  return getDeviceNodeName();
47494
48734
  }
47495
48735
  var DEFAULT_NODE_NAME = getDefaultNodeName();
47496
- var SUPPORTED_TRANSPORTS = ["direct", "devtunnel", "tailscale"];
48736
+ var SUPPORTED_TRANSPORTS = ["direct", "devtunnel"];
47497
48737
  var STARTUP_REQUIREMENTS = ["az", "devtunnel", "claude", "codex"];
47498
48738
  function createDefaultConfig(storagePath = resolveDefaultStoragePath(), nodeName = DEFAULT_NODE_NAME) {
47499
48739
  return {
@@ -47534,7 +48774,7 @@ function createPromptSession(prompt) {
47534
48774
  }
47535
48775
  function createDefaultCommandRunner(platform2) {
47536
48776
  return (command, args, interactive = false) => {
47537
- const result = (0, import_node_child_process10.spawnSync)(command, args, {
48777
+ const result = (0, import_node_child_process11.spawnSync)(command, args, {
47538
48778
  encoding: "utf-8",
47539
48779
  shell: platform2 === "win32",
47540
48780
  stdio: interactive ? "inherit" : "pipe"
@@ -47549,21 +48789,21 @@ function createDefaultCommandRunner(platform2) {
47549
48789
  };
47550
48790
  }
47551
48791
  function getNodeMetadataPath2(storagePath) {
47552
- return path19.join(storagePath, "metadata.json");
48792
+ return path20.join(storagePath, "metadata.json");
47553
48793
  }
47554
48794
  function readStartupMetadataFile(storagePath) {
47555
48795
  try {
47556
- const raw = JSON.parse(fs18.readFileSync(getNodeMetadataPath2(storagePath), "utf-8"));
48796
+ const raw = JSON.parse(fs19.readFileSync(getNodeMetadataPath2(storagePath), "utf-8"));
47557
48797
  return typeof raw === "object" && raw !== null ? raw : {};
47558
48798
  } catch {
47559
48799
  return {};
47560
48800
  }
47561
48801
  }
47562
48802
  function writeStartupMetadataFile(storagePath, metadata) {
47563
- fs18.mkdirSync(storagePath, { recursive: true });
47564
- fs18.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
48803
+ fs19.mkdirSync(storagePath, { recursive: true });
48804
+ fs19.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
47565
48805
  }
47566
- function formatLocalDate(now) {
48806
+ function formatLocalDate2(now) {
47567
48807
  const year = now.getFullYear();
47568
48808
  const month = String(now.getMonth() + 1).padStart(2, "0");
47569
48809
  const day = String(now.getDate()).padStart(2, "0");
@@ -47654,7 +48894,7 @@ function resolveStartupRequirementsMetadata(storagePath) {
47654
48894
  }
47655
48895
  function shouldSkipStartupRequirementsCheck(storagePath, now = /* @__PURE__ */ new Date()) {
47656
48896
  const metadata = resolveStartupRequirementsMetadata(storagePath);
47657
- if (metadata.lastCheckedOn !== formatLocalDate(now)) {
48897
+ if (metadata.lastCheckedOn !== formatLocalDate2(now)) {
47658
48898
  return false;
47659
48899
  }
47660
48900
  return STARTUP_REQUIREMENTS.every((requirement) => isRequirementSatisfied(requirement, metadata.components?.[requirement]));
@@ -47738,7 +48978,7 @@ async function ensureStartupRequirements(storagePath, options = {}) {
47738
48978
  await current.close();
47739
48979
  };
47740
48980
  const checkedAt = now.toISOString();
47741
- const checkedOn = formatLocalDate(now);
48981
+ const checkedOn = formatLocalDate2(now);
47742
48982
  const components = {};
47743
48983
  try {
47744
48984
  for (const requirement of STARTUP_REQUIREMENTS) {
@@ -47800,9 +49040,9 @@ async function ensureStartupRequirements(storagePath, options = {}) {
47800
49040
  metadata
47801
49041
  };
47802
49042
  }
47803
- function loadConfigFile(path21) {
49043
+ function loadConfigFile(path22) {
47804
49044
  try {
47805
- const raw = fs18.readFileSync(path21, "utf-8");
49045
+ const raw = fs19.readFileSync(path22, "utf-8");
47806
49046
  return JSON.parse(raw);
47807
49047
  } catch {
47808
49048
  return {};
@@ -47878,13 +49118,13 @@ async function promptStartOptions(args, fileConfig, defaults, prompt) {
47878
49118
  result.port = port;
47879
49119
  break;
47880
49120
  }
47881
- console.log("Invalid port. Enter a positive integer.");
49121
+ terminalWriter.line("Invalid port. Enter a positive integer.");
47882
49122
  }
47883
49123
  }
47884
49124
  if (result.transport === void 0) {
47885
49125
  while (true) {
47886
49126
  const input = normalizePromptValue(
47887
- await ask(formatPrompt("Transport (direct/devtunnel/tailscale)", merged.transport.type))
49127
+ await ask(formatPrompt("Transport (direct/devtunnel)", merged.transport.type))
47888
49128
  );
47889
49129
  if (!input) {
47890
49130
  result.transport = merged.transport.type;
@@ -47894,7 +49134,7 @@ async function promptStartOptions(args, fileConfig, defaults, prompt) {
47894
49134
  result.transport = input;
47895
49135
  break;
47896
49136
  }
47897
- console.log("Invalid transport. Use direct, devtunnel, or tailscale.");
49137
+ terminalWriter.line("Invalid transport. Use direct or devtunnel.");
47898
49138
  }
47899
49139
  }
47900
49140
  if (result.join === void 0) {
@@ -47980,26 +49220,26 @@ function formatLoadedStartMetadata(info, authEnabled) {
47980
49220
  }
47981
49221
 
47982
49222
  // src/runtime-metadata.ts
47983
- var fs19 = __toESM(require("fs"), 1);
47984
- var path20 = __toESM(require("path"), 1);
47985
- var import_node_child_process11 = require("child_process");
49223
+ var fs20 = __toESM(require("fs"), 1);
49224
+ var path21 = __toESM(require("path"), 1);
49225
+ var import_node_child_process12 = require("child_process");
47986
49226
  var runtimeDir = resolveRuntimeDir();
47987
49227
  var appRoot = resolveAppRoot(runtimeDir);
47988
- var repoRoot = path20.resolve(appRoot, "../..");
49228
+ var repoRoot = path21.resolve(appRoot, "../..");
47989
49229
  function resolveRuntimeDir() {
47990
49230
  const entryPath = process.argv[1];
47991
49231
  if (typeof entryPath === "string" && entryPath.length > 0) {
47992
49232
  try {
47993
- return path20.dirname(fs19.realpathSync(path20.resolve(entryPath)));
49233
+ return path21.dirname(fs20.realpathSync(path21.resolve(entryPath)));
47994
49234
  } catch {
47995
- return path20.dirname(path20.resolve(entryPath));
49235
+ return path21.dirname(path21.resolve(entryPath));
47996
49236
  }
47997
49237
  }
47998
49238
  return process.cwd();
47999
49239
  }
48000
49240
  function readJsonFile(filePath) {
48001
49241
  try {
48002
- return JSON.parse(fs19.readFileSync(filePath, "utf-8"));
49242
+ return JSON.parse(fs20.readFileSync(filePath, "utf-8"));
48003
49243
  } catch {
48004
49244
  return null;
48005
49245
  }
@@ -48009,9 +49249,9 @@ function readPackageManifest(filePath) {
48009
49249
  }
48010
49250
  function readEmbeddedRuntimeMetadata() {
48011
49251
  const candidates = [
48012
- path20.join(appRoot, "runtime-metadata.json"),
48013
- path20.join(runtimeDir, "runtime-metadata.json"),
48014
- path20.resolve(process.cwd(), "apps/node/dist/runtime-metadata.json")
49252
+ path21.join(appRoot, "runtime-metadata.json"),
49253
+ path21.join(runtimeDir, "runtime-metadata.json"),
49254
+ path21.resolve(process.cwd(), "apps/node/dist/runtime-metadata.json")
48015
49255
  ];
48016
49256
  for (const candidate of candidates) {
48017
49257
  const metadata = readJsonFile(candidate);
@@ -48024,23 +49264,23 @@ function readEmbeddedRuntimeMetadata() {
48024
49264
  function resolveAppRoot(baseDir) {
48025
49265
  const candidates = [
48026
49266
  baseDir,
48027
- path20.resolve(baseDir, ".."),
48028
- path20.resolve(process.cwd(), "apps/node/dist"),
48029
- path20.resolve(process.cwd(), "apps/node"),
49267
+ path21.resolve(baseDir, ".."),
49268
+ path21.resolve(process.cwd(), "apps/node/dist"),
49269
+ path21.resolve(process.cwd(), "apps/node"),
48030
49270
  process.cwd()
48031
49271
  ];
48032
49272
  for (const candidate of candidates) {
48033
- const manifest = readPackageManifest(path20.join(candidate, "package.json"));
49273
+ const manifest = readPackageManifest(path21.join(candidate, "package.json"));
48034
49274
  if (manifest?.name === "@meshy/node" || manifest?.name === "meshy-node") {
48035
49275
  return candidate;
48036
49276
  }
48037
49277
  }
48038
49278
  for (const candidate of candidates) {
48039
- if (fs19.existsSync(path20.join(candidate, "package.json"))) {
49279
+ if (fs20.existsSync(path21.join(candidate, "package.json"))) {
48040
49280
  return candidate;
48041
49281
  }
48042
49282
  }
48043
- return path20.resolve(baseDir, "..");
49283
+ return path21.resolve(baseDir, "..");
48044
49284
  }
48045
49285
  function toPackageInfo(filePath) {
48046
49286
  const manifest = readPackageManifest(filePath);
@@ -48078,7 +49318,7 @@ function readRepositoryUrlFromManifest(manifest) {
48078
49318
  }
48079
49319
  function readGitValue(args) {
48080
49320
  try {
48081
- const output = (0, import_node_child_process11.execFileSync)("git", args, {
49321
+ const output = (0, import_node_child_process12.execFileSync)("git", args, {
48082
49322
  cwd: repoRoot,
48083
49323
  encoding: "utf-8",
48084
49324
  stdio: ["ignore", "pipe", "ignore"],
@@ -48100,8 +49340,8 @@ function buildRuntimeMetadata(storagePath) {
48100
49340
  components: startupRequirements.components
48101
49341
  };
48102
49342
  }
48103
- const appPackage = toPackageInfo(path20.join(appRoot, "package.json"));
48104
- const workspaceManifest = readPackageManifest(path20.join(repoRoot, "package.json"));
49343
+ const appPackage = toPackageInfo(path21.join(appRoot, "package.json"));
49344
+ const workspaceManifest = readPackageManifest(path21.join(repoRoot, "package.json"));
48105
49345
  return {
48106
49346
  packageName: appPackage?.name ?? "meshy",
48107
49347
  packageVersion: appPackage?.version ?? "0.1.0",
@@ -48109,11 +49349,11 @@ function buildRuntimeMetadata(storagePath) {
48109
49349
  startupRequirementsLastCheckedOn: startupRequirements.lastCheckedOn,
48110
49350
  components: startupRequirements.components,
48111
49351
  packages: {
48112
- workspace: toPackageInfo(path20.join(repoRoot, "package.json")),
49352
+ workspace: toPackageInfo(path21.join(repoRoot, "package.json")),
48113
49353
  node: appPackage,
48114
- core: toPackageInfo(path20.join(repoRoot, "packages/core/package.json")),
48115
- dashboard: toPackageInfo(path20.join(repoRoot, "packages/dashboard/package.json")),
48116
- api: toPackageInfo(path20.join(repoRoot, "packages/api/package.json"))
49354
+ core: toPackageInfo(path21.join(repoRoot, "packages/core/package.json")),
49355
+ dashboard: toPackageInfo(path21.join(repoRoot, "packages/dashboard/package.json")),
49356
+ api: toPackageInfo(path21.join(repoRoot, "packages/api/package.json"))
48117
49357
  },
48118
49358
  repository: {
48119
49359
  url: normalizeRepositoryUrl(readGitValue(["config", "--get", "remote.upstream.url"])) ?? normalizeRepositoryUrl(readGitValue(["config", "--get", "remote.origin.url"])) ?? readRepositoryUrlFromManifest(workspaceManifest),
@@ -48127,11 +49367,7 @@ function buildRuntimeMetadata(storagePath) {
48127
49367
  function createSettingsSnapshotProvider(options) {
48128
49368
  let cachedSnapshot = null;
48129
49369
  let cachedSnapshotAt = 0;
48130
- return function getSettingsSnapshot() {
48131
- const now = Date.now();
48132
- if (cachedSnapshot && now - cachedSnapshotAt < 3e4) {
48133
- return structuredClone(cachedSnapshot);
48134
- }
49370
+ function buildSnapshot() {
48135
49371
  cachedSnapshot = buildNodeSettingsSnapshot({
48136
49372
  auth: options.authMetadata,
48137
49373
  localDashboardOrigin: options.localDashboardOrigin,
@@ -48139,8 +49375,23 @@ function createSettingsSnapshotProvider(options) {
48139
49375
  storagePath: options.storagePath,
48140
49376
  workDir: options.workDir
48141
49377
  });
48142
- cachedSnapshotAt = now;
49378
+ cachedSnapshotAt = Date.now();
48143
49379
  return structuredClone(cachedSnapshot);
49380
+ }
49381
+ function getSettingsSnapshot() {
49382
+ const now = Date.now();
49383
+ if (cachedSnapshot && now - cachedSnapshotAt < 3e4) {
49384
+ return structuredClone(cachedSnapshot);
49385
+ }
49386
+ return buildSnapshot();
49387
+ }
49388
+ return {
49389
+ getSettingsSnapshot,
49390
+ refreshSettingsSnapshot: () => {
49391
+ cachedSnapshot = null;
49392
+ cachedSnapshotAt = 0;
49393
+ return buildSnapshot();
49394
+ }
48144
49395
  };
48145
49396
  }
48146
49397
  async function resolveStartConfig(args) {
@@ -48427,13 +49678,13 @@ function registerShutdownHandlers(options) {
48427
49678
  let shuttingDown = false;
48428
49679
  async function shutdown() {
48429
49680
  if (shuttingDown) {
48430
- console.log("Force exit.");
49681
+ terminalWriter.line("Force exit.");
48431
49682
  process.exit(130);
48432
49683
  }
48433
49684
  shuttingDown = true;
48434
- console.log("\nShutting down...");
49685
+ terminalWriter.line("\nShutting down...");
48435
49686
  const forceExitTimer = setTimeout(() => {
48436
- console.log("Force exit.");
49687
+ terminalWriter.line("Force exit.");
48437
49688
  process.exit(0);
48438
49689
  }, 1e4);
48439
49690
  forceExitTimer.unref?.();
@@ -48443,10 +49694,10 @@ function registerShutdownHandlers(options) {
48443
49694
  await options.tunnelManager.stop();
48444
49695
  await options.meshyNode.stop();
48445
49696
  clearTimeout(forceExitTimer);
48446
- console.log("Goodbye!");
49697
+ terminalWriter.line("Goodbye!");
48447
49698
  process.exit(0);
48448
49699
  } catch (err) {
48449
- console.error("Error during shutdown:", err);
49700
+ terminalWriter.error("Error during shutdown:", err);
48450
49701
  process.exit(1);
48451
49702
  }
48452
49703
  }
@@ -48455,9 +49706,9 @@ function registerShutdownHandlers(options) {
48455
49706
  }
48456
49707
  async function startNode(args) {
48457
49708
  const { authMetadata, config, hydratedArgs, runtimeMetadata, storageRoot } = await resolveStartConfig(args);
48458
- console.log("Checking startup requirements (az, devtunnel, claude, codex)...");
49709
+ terminalWriter.line("Checking startup requirements (az, devtunnel, claude, codex)...");
48459
49710
  const startupRequirements = await ensureStartupRequirements(config.storage.path);
48460
- console.log(
49711
+ terminalWriter.line(
48461
49712
  startupRequirements.skipped ? "Startup requirements already verified today; skipping checks." : "Startup requirements check complete."
48462
49713
  );
48463
49714
  const localDashboardOrigin = `http://localhost:${config.node.port}`;
@@ -48471,9 +49722,9 @@ async function startNode(args) {
48471
49722
  settingsProvider: () => authMetadata
48472
49723
  });
48473
49724
  if (hydratedArgs.loaded) {
48474
- console.log("");
48475
- console.log(formatLoadedStartMetadata(hydratedArgs.loaded, authMetadata.enabled));
48476
- console.log("");
49725
+ terminalWriter.line("");
49726
+ terminalWriter.line(formatLoadedStartMetadata(hydratedArgs.loaded, authMetadata.enabled));
49727
+ terminalWriter.line("");
48477
49728
  }
48478
49729
  if (authMetadata.enabled) {
48479
49730
  await nodeAuth.warmup();
@@ -48481,13 +49732,14 @@ async function startNode(args) {
48481
49732
  } else {
48482
49733
  setRequestAuthHeadersProvider(null);
48483
49734
  }
48484
- const getSettingsSnapshot = createSettingsSnapshotProvider({
49735
+ const settingsSnapshotProvider = createSettingsSnapshotProvider({
48485
49736
  authMetadata,
48486
49737
  localDashboardOrigin,
48487
49738
  runtimeMetadata,
48488
49739
  storagePath: config.storage.path,
48489
49740
  workDir: nodePath2.resolve(config.node.workDir ?? process.cwd())
48490
49741
  });
49742
+ const { getSettingsSnapshot, refreshSettingsSnapshot } = settingsSnapshotProvider;
48491
49743
  const meshyNode = new MeshyNode(config, {
48492
49744
  logger: logger27,
48493
49745
  transportFactory: createTransport,
@@ -48570,6 +49822,8 @@ async function startNode(args) {
48570
49822
  },
48571
49823
  isDevTunnelEnabled: () => meshyNode.isDevTunnelEnabled(),
48572
49824
  localDashboardOrigin,
49825
+ upgradeRuntimeAgent,
49826
+ refreshSettingsSnapshot,
48573
49827
  dashboardOrigin: tunnelManager.getDashboardOrigin(),
48574
49828
  shareOrigin: tunnelManager.getShareOrigin(),
48575
49829
  ensureShareTunnel: () => tunnelManager.ensureShareTunnel(),
@@ -48597,9 +49851,9 @@ async function startNode(args) {
48597
49851
  port: config.node.port,
48598
49852
  dashboardOrigin: tunnelManager.getDashboardOrigin()
48599
49853
  });
48600
- console.log("");
48601
- console.log(banner);
48602
- console.log("");
49854
+ terminalWriter.line("");
49855
+ terminalWriter.line(banner);
49856
+ terminalWriter.line("");
48603
49857
  });
48604
49858
  registerShutdownHandlers({
48605
49859
  server,