@vibedeckx/darwin-arm64 0.1.23 → 0.1.25

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.
Files changed (40) hide show
  1. package/dist/bin.js +1492 -616
  2. package/dist/ui/404/index.html +1 -1
  3. package/dist/ui/404.html +1 -1
  4. package/dist/ui/__next.__PAGE__.txt +2 -2
  5. package/dist/ui/__next._full.txt +6 -6
  6. package/dist/ui/__next._head.txt +1 -1
  7. package/dist/ui/__next._index.txt +5 -5
  8. package/dist/ui/__next._tree.txt +2 -2
  9. package/dist/ui/_next/static/chunks/03d6fb3847124588.css +1 -0
  10. package/dist/ui/_next/static/chunks/{dae86e12c7741e6c.js → 3395a5b27133097f.js} +5 -5
  11. package/dist/ui/_next/static/chunks/e6d6cc1ae3068950.js +29 -0
  12. package/dist/ui/_not-found/__next._full.txt +5 -5
  13. package/dist/ui/_not-found/__next._head.txt +1 -1
  14. package/dist/ui/_not-found/__next._index.txt +5 -5
  15. package/dist/ui/_not-found/__next._not-found.__PAGE__.txt +1 -1
  16. package/dist/ui/_not-found/__next._not-found.txt +1 -1
  17. package/dist/ui/_not-found/__next._tree.txt +2 -2
  18. package/dist/ui/_not-found/index.html +1 -1
  19. package/dist/ui/_not-found/index.txt +5 -5
  20. package/dist/ui/index.html +1 -1
  21. package/dist/ui/index.txt +6 -6
  22. package/node_modules/better-sqlite3/package.json +3 -0
  23. package/node_modules/bindings/LICENSE.md +22 -0
  24. package/node_modules/bindings/README.md +98 -0
  25. package/node_modules/bindings/bindings.js +221 -0
  26. package/node_modules/bindings/package.json +28 -0
  27. package/node_modules/file-uri-to-path/History.md +21 -0
  28. package/node_modules/file-uri-to-path/LICENSE +20 -0
  29. package/node_modules/file-uri-to-path/README.md +74 -0
  30. package/node_modules/file-uri-to-path/index.d.ts +2 -0
  31. package/node_modules/file-uri-to-path/index.js +66 -0
  32. package/node_modules/file-uri-to-path/package.json +32 -0
  33. package/node_modules/file-uri-to-path/test/test.js +24 -0
  34. package/node_modules/file-uri-to-path/test/tests.json +13 -0
  35. package/package.json +1 -1
  36. package/dist/ui/_next/static/chunks/9393cbbff01bb58d.js +0 -29
  37. package/dist/ui/_next/static/chunks/e23d46e94edec1d3.css +0 -1
  38. /package/dist/ui/_next/static/{_oIkVA-8sboc_20lcPBrb → 3FlKmnMOaSdQhYCbw6R1U}/_buildManifest.js +0 -0
  39. /package/dist/ui/_next/static/{_oIkVA-8sboc_20lcPBrb → 3FlKmnMOaSdQhYCbw6R1U}/_clientMiddlewareManifest.json +0 -0
  40. /package/dist/ui/_next/static/{_oIkVA-8sboc_20lcPBrb → 3FlKmnMOaSdQhYCbw6R1U}/_ssgManifest.js +0 -0
package/dist/bin.js CHANGED
@@ -3740,8 +3740,8 @@ var require_req = __commonJS({
3740
3740
  if (req.originalUrl) {
3741
3741
  _req.url = req.originalUrl;
3742
3742
  } else {
3743
- const path11 = req.path;
3744
- _req.url = typeof path11 === "string" ? path11 : req.url ? req.url.path || req.url : void 0;
3743
+ const path12 = req.path;
3744
+ _req.url = typeof path12 === "string" ? path12 : req.url ? req.url.path || req.url : void 0;
3745
3745
  }
3746
3746
  if (req.query) {
3747
3747
  _req.query = req.query;
@@ -3906,14 +3906,14 @@ var require_redact = __commonJS({
3906
3906
  }
3907
3907
  return obj;
3908
3908
  }
3909
- function parsePath(path11) {
3909
+ function parsePath(path12) {
3910
3910
  const parts = [];
3911
3911
  let current = "";
3912
3912
  let inBrackets = false;
3913
3913
  let inQuotes = false;
3914
3914
  let quoteChar = "";
3915
- for (let i = 0; i < path11.length; i++) {
3916
- const char = path11[i];
3915
+ for (let i = 0; i < path12.length; i++) {
3916
+ const char = path12[i];
3917
3917
  if (!inBrackets && char === ".") {
3918
3918
  if (current) {
3919
3919
  parts.push(current);
@@ -4044,10 +4044,10 @@ var require_redact = __commonJS({
4044
4044
  return current;
4045
4045
  }
4046
4046
  function redactPaths(obj, paths, censor, remove = false) {
4047
- for (const path11 of paths) {
4048
- const parts = parsePath(path11);
4047
+ for (const path12 of paths) {
4048
+ const parts = parsePath(path12);
4049
4049
  if (parts.includes("*")) {
4050
- redactWildcardPath(obj, parts, censor, path11, remove);
4050
+ redactWildcardPath(obj, parts, censor, path12, remove);
4051
4051
  } else {
4052
4052
  if (remove) {
4053
4053
  removeKey(obj, parts);
@@ -4132,8 +4132,8 @@ var require_redact = __commonJS({
4132
4132
  }
4133
4133
  } else {
4134
4134
  if (afterWildcard.includes("*")) {
4135
- const wrappedCensor = typeof censor === "function" ? (value, path11) => {
4136
- const fullPath = [...pathArray.slice(0, pathLength), ...path11];
4135
+ const wrappedCensor = typeof censor === "function" ? (value, path12) => {
4136
+ const fullPath = [...pathArray.slice(0, pathLength), ...path12];
4137
4137
  return censor(value, fullPath);
4138
4138
  } : censor;
4139
4139
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -4168,8 +4168,8 @@ var require_redact = __commonJS({
4168
4168
  return null;
4169
4169
  }
4170
4170
  const pathStructure = /* @__PURE__ */ new Map();
4171
- for (const path11 of pathsToClone) {
4172
- const parts = parsePath(path11);
4171
+ for (const path12 of pathsToClone) {
4172
+ const parts = parsePath(path12);
4173
4173
  let current = pathStructure;
4174
4174
  for (let i = 0; i < parts.length; i++) {
4175
4175
  const part = parts[i];
@@ -4221,24 +4221,24 @@ var require_redact = __commonJS({
4221
4221
  }
4222
4222
  return cloneSelectively(obj, pathStructure);
4223
4223
  }
4224
- function validatePath(path11) {
4225
- if (typeof path11 !== "string") {
4224
+ function validatePath(path12) {
4225
+ if (typeof path12 !== "string") {
4226
4226
  throw new Error("Paths must be (non-empty) strings");
4227
4227
  }
4228
- if (path11 === "") {
4228
+ if (path12 === "") {
4229
4229
  throw new Error("Invalid redaction path ()");
4230
4230
  }
4231
- if (path11.includes("..")) {
4232
- throw new Error(`Invalid redaction path (${path11})`);
4231
+ if (path12.includes("..")) {
4232
+ throw new Error(`Invalid redaction path (${path12})`);
4233
4233
  }
4234
- if (path11.includes(",")) {
4235
- throw new Error(`Invalid redaction path (${path11})`);
4234
+ if (path12.includes(",")) {
4235
+ throw new Error(`Invalid redaction path (${path12})`);
4236
4236
  }
4237
4237
  let bracketCount = 0;
4238
4238
  let inQuotes = false;
4239
4239
  let quoteChar = "";
4240
- for (let i = 0; i < path11.length; i++) {
4241
- const char = path11[i];
4240
+ for (let i = 0; i < path12.length; i++) {
4241
+ const char = path12[i];
4242
4242
  if ((char === '"' || char === "'") && bracketCount > 0) {
4243
4243
  if (!inQuotes) {
4244
4244
  inQuotes = true;
@@ -4252,20 +4252,20 @@ var require_redact = __commonJS({
4252
4252
  } else if (char === "]" && !inQuotes) {
4253
4253
  bracketCount--;
4254
4254
  if (bracketCount < 0) {
4255
- throw new Error(`Invalid redaction path (${path11})`);
4255
+ throw new Error(`Invalid redaction path (${path12})`);
4256
4256
  }
4257
4257
  }
4258
4258
  }
4259
4259
  if (bracketCount !== 0) {
4260
- throw new Error(`Invalid redaction path (${path11})`);
4260
+ throw new Error(`Invalid redaction path (${path12})`);
4261
4261
  }
4262
4262
  }
4263
4263
  function validatePaths(paths) {
4264
4264
  if (!Array.isArray(paths)) {
4265
4265
  throw new TypeError("paths must be an array");
4266
4266
  }
4267
- for (const path11 of paths) {
4268
- validatePath(path11);
4267
+ for (const path12 of paths) {
4268
+ validatePath(path12);
4269
4269
  }
4270
4270
  }
4271
4271
  function slowRedact(options = {}) {
@@ -4433,8 +4433,8 @@ var require_redaction = __commonJS({
4433
4433
  if (shape[k] === null) {
4434
4434
  o[k] = (value) => topCensor(value, [k]);
4435
4435
  } else {
4436
- const wrappedCensor = typeof censor === "function" ? (value, path11) => {
4437
- return censor(value, [k, ...path11]);
4436
+ const wrappedCensor = typeof censor === "function" ? (value, path12) => {
4437
+ return censor(value, [k, ...path12]);
4438
4438
  } : censor;
4439
4439
  o[k] = Redact({
4440
4440
  paths: shape[k],
@@ -4655,7 +4655,7 @@ var require_sonic_boom = __commonJS({
4655
4655
  var fs7 = __require("fs");
4656
4656
  var EventEmitter3 = __require("events");
4657
4657
  var inherits = __require("util").inherits;
4658
- var path11 = __require("path");
4658
+ var path12 = __require("path");
4659
4659
  var sleep2 = require_atomic_sleep();
4660
4660
  var assert2 = __require("assert");
4661
4661
  var BUSY_WRITE_TIMEOUT = 100;
@@ -4709,7 +4709,7 @@ var require_sonic_boom = __commonJS({
4709
4709
  const mode = sonic.mode;
4710
4710
  if (sonic.sync) {
4711
4711
  try {
4712
- if (sonic.mkdir) fs7.mkdirSync(path11.dirname(file2), { recursive: true });
4712
+ if (sonic.mkdir) fs7.mkdirSync(path12.dirname(file2), { recursive: true });
4713
4713
  const fd = fs7.openSync(file2, flags, mode);
4714
4714
  fileOpened(null, fd);
4715
4715
  } catch (err) {
@@ -4717,7 +4717,7 @@ var require_sonic_boom = __commonJS({
4717
4717
  throw err;
4718
4718
  }
4719
4719
  } else if (sonic.mkdir) {
4720
- fs7.mkdir(path11.dirname(file2), { recursive: true }, (err) => {
4720
+ fs7.mkdir(path12.dirname(file2), { recursive: true }, (err) => {
4721
4721
  if (err) return fileOpened(err);
4722
4722
  fs7.open(file2, flags, mode, fileOpened);
4723
4723
  });
@@ -15279,8 +15279,8 @@ var require_utils = __commonJS({
15279
15279
  }
15280
15280
  return ind;
15281
15281
  }
15282
- function removeDotSegments(path11) {
15283
- let input = path11;
15282
+ function removeDotSegments(path12) {
15283
+ let input = path12;
15284
15284
  const output = [];
15285
15285
  let nextSlash = -1;
15286
15286
  let len = 0;
@@ -15479,8 +15479,8 @@ var require_schemes = __commonJS({
15479
15479
  wsComponent.secure = void 0;
15480
15480
  }
15481
15481
  if (wsComponent.resourceName) {
15482
- const [path11, query] = wsComponent.resourceName.split("?");
15483
- wsComponent.path = path11 && path11 !== "/" ? path11 : void 0;
15482
+ const [path12, query] = wsComponent.resourceName.split("?");
15483
+ wsComponent.path = path12 && path12 !== "/" ? path12 : void 0;
15484
15484
  wsComponent.query = query;
15485
15485
  wsComponent.resourceName = void 0;
15486
15486
  }
@@ -25216,12 +25216,12 @@ var require_range = __commonJS({
25216
25216
  debug("replaceGTE0", comp, options);
25217
25217
  return comp.trim().replace(re2[options.includePrerelease ? t.GTE0PRE : t.GTE0], "");
25218
25218
  };
25219
- var hyphenReplace = (incPr) => ($0, from, fM, fm, fp24, fpr, fb, to, tM, tm, tp, tpr) => {
25219
+ var hyphenReplace = (incPr) => ($0, from, fM, fm, fp25, fpr, fb, to, tM, tm, tp, tpr) => {
25220
25220
  if (isX(fM)) {
25221
25221
  from = "";
25222
25222
  } else if (isX(fm)) {
25223
25223
  from = `>=${fM}.0.0${incPr ? "-0" : ""}`;
25224
- } else if (isX(fp24)) {
25224
+ } else if (isX(fp25)) {
25225
25225
  from = `>=${fM}.${fm}.0${incPr ? "-0" : ""}`;
25226
25226
  } else if (fpr) {
25227
25227
  from = `>=${from}`;
@@ -27802,8 +27802,8 @@ var require_pretty_print = __commonJS({
27802
27802
  serializedRoute += serializeMetaData(route.metaData);
27803
27803
  return serializedRoute;
27804
27804
  }
27805
- function mergeSimilarRoutes(routes23) {
27806
- return routes23.reduce((mergedRoutes, route) => {
27805
+ function mergeSimilarRoutes(routes24) {
27806
+ return routes24.reduce((mergedRoutes, route) => {
27807
27807
  for (const nodeRoute of mergedRoutes) {
27808
27808
  if (deepEqual(route.opts.constraints, nodeRoute.opts.constraints) && deepEqual(route.metaData, nodeRoute.metaData)) {
27809
27809
  nodeRoute.method += ", " + route.method;
@@ -27815,18 +27815,18 @@ var require_pretty_print = __commonJS({
27815
27815
  }, []);
27816
27816
  }
27817
27817
  function serializeNode(node, prefix, options) {
27818
- let routes23 = node.routes;
27818
+ let routes24 = node.routes;
27819
27819
  if (options.method === void 0) {
27820
- routes23 = routes23.map(normalizeRoute);
27820
+ routes24 = routes24.map(normalizeRoute);
27821
27821
  }
27822
- routes23 = routes23.map((route) => {
27822
+ routes24 = routes24.map((route) => {
27823
27823
  route.metaData = getRouteMetaData(route, options);
27824
27824
  return route;
27825
27825
  });
27826
27826
  if (options.method === void 0) {
27827
- routes23 = mergeSimilarRoutes(routes23);
27827
+ routes24 = mergeSimilarRoutes(routes24);
27828
27828
  }
27829
- return routes23.map(serializeRoute).join(`
27829
+ return routes24.map(serializeRoute).join(`
27830
27830
  ${prefix}`);
27831
27831
  }
27832
27832
  function buildObjectTree(node, tree, prefix, options) {
@@ -28051,40 +28051,40 @@ var require_node = __commonJS({
28051
28051
  super();
28052
28052
  this.staticChildren = {};
28053
28053
  }
28054
- findStaticMatchingChild(path11, pathIndex) {
28055
- const staticChild = this.staticChildren[path11.charAt(pathIndex)];
28056
- if (staticChild === void 0 || !staticChild.matchPrefix(path11, pathIndex)) {
28054
+ findStaticMatchingChild(path12, pathIndex) {
28055
+ const staticChild = this.staticChildren[path12.charAt(pathIndex)];
28056
+ if (staticChild === void 0 || !staticChild.matchPrefix(path12, pathIndex)) {
28057
28057
  return null;
28058
28058
  }
28059
28059
  return staticChild;
28060
28060
  }
28061
- getStaticChild(path11, pathIndex = 0) {
28062
- if (path11.length === pathIndex) {
28061
+ getStaticChild(path12, pathIndex = 0) {
28062
+ if (path12.length === pathIndex) {
28063
28063
  return this;
28064
28064
  }
28065
- const staticChild = this.findStaticMatchingChild(path11, pathIndex);
28065
+ const staticChild = this.findStaticMatchingChild(path12, pathIndex);
28066
28066
  if (staticChild) {
28067
- return staticChild.getStaticChild(path11, pathIndex + staticChild.prefix.length);
28067
+ return staticChild.getStaticChild(path12, pathIndex + staticChild.prefix.length);
28068
28068
  }
28069
28069
  return null;
28070
28070
  }
28071
- createStaticChild(path11) {
28072
- if (path11.length === 0) {
28071
+ createStaticChild(path12) {
28072
+ if (path12.length === 0) {
28073
28073
  return this;
28074
28074
  }
28075
- let staticChild = this.staticChildren[path11.charAt(0)];
28075
+ let staticChild = this.staticChildren[path12.charAt(0)];
28076
28076
  if (staticChild) {
28077
28077
  let i = 1;
28078
28078
  for (; i < staticChild.prefix.length; i++) {
28079
- if (path11.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
28079
+ if (path12.charCodeAt(i) !== staticChild.prefix.charCodeAt(i)) {
28080
28080
  staticChild = staticChild.split(this, i);
28081
28081
  break;
28082
28082
  }
28083
28083
  }
28084
- return staticChild.createStaticChild(path11.slice(i));
28084
+ return staticChild.createStaticChild(path12.slice(i));
28085
28085
  }
28086
- const label = path11.charAt(0);
28087
- this.staticChildren[label] = new StaticNode(path11);
28086
+ const label = path12.charAt(0);
28087
+ this.staticChildren[label] = new StaticNode(path12);
28088
28088
  return this.staticChildren[label];
28089
28089
  }
28090
28090
  };
@@ -28144,8 +28144,8 @@ var require_node = __commonJS({
28144
28144
  parentNode.staticChildren[parentPrefix.charAt(0)] = staticNode;
28145
28145
  return staticNode;
28146
28146
  }
28147
- getNextNode(path11, pathIndex, nodeStack, paramsCount) {
28148
- let node = this.findStaticMatchingChild(path11, pathIndex);
28147
+ getNextNode(path12, pathIndex, nodeStack, paramsCount) {
28148
+ let node = this.findStaticMatchingChild(path12, pathIndex);
28149
28149
  let parametricBrotherNodeIndex = 0;
28150
28150
  if (node === null) {
28151
28151
  if (this.parametricChildren.length === 0) {
@@ -28192,8 +28192,8 @@ var require_node = __commonJS({
28192
28192
  this.kind = NODE_TYPES.PARAMETRIC;
28193
28193
  this.nodePaths = /* @__PURE__ */ new Set([nodePath]);
28194
28194
  }
28195
- getNextNode(path11, pathIndex) {
28196
- return this.findStaticMatchingChild(path11, pathIndex);
28195
+ getNextNode(path12, pathIndex) {
28196
+ return this.findStaticMatchingChild(path12, pathIndex);
28197
28197
  }
28198
28198
  };
28199
28199
  var WildcardNode = class extends Node {
@@ -28529,33 +28529,33 @@ var require_url_sanitizer = __commonJS({
28529
28529
  }
28530
28530
  return null;
28531
28531
  }
28532
- function safeDecodeURI(path11, useSemicolonDelimiter) {
28532
+ function safeDecodeURI(path12, useSemicolonDelimiter) {
28533
28533
  let shouldDecode = false;
28534
28534
  let shouldDecodeParam = false;
28535
28535
  let querystring = "";
28536
- for (let i = 1; i < path11.length; i++) {
28537
- const charCode = path11.charCodeAt(i);
28536
+ for (let i = 1; i < path12.length; i++) {
28537
+ const charCode = path12.charCodeAt(i);
28538
28538
  if (charCode === 37) {
28539
- const highCharCode = path11.charCodeAt(i + 1);
28540
- const lowCharCode = path11.charCodeAt(i + 2);
28539
+ const highCharCode = path12.charCodeAt(i + 1);
28540
+ const lowCharCode = path12.charCodeAt(i + 2);
28541
28541
  if (decodeComponentChar(highCharCode, lowCharCode) === null) {
28542
28542
  shouldDecode = true;
28543
28543
  } else {
28544
28544
  shouldDecodeParam = true;
28545
28545
  if (highCharCode === 50 && lowCharCode === 53) {
28546
28546
  shouldDecode = true;
28547
- path11 = path11.slice(0, i + 1) + "25" + path11.slice(i + 1);
28547
+ path12 = path12.slice(0, i + 1) + "25" + path12.slice(i + 1);
28548
28548
  i += 2;
28549
28549
  }
28550
28550
  i += 2;
28551
28551
  }
28552
28552
  } else if (charCode === 63 || charCode === 35 || charCode === 59 && useSemicolonDelimiter) {
28553
- querystring = path11.slice(i + 1);
28554
- path11 = path11.slice(0, i);
28553
+ querystring = path12.slice(i + 1);
28554
+ path12 = path12.slice(0, i);
28555
28555
  break;
28556
28556
  }
28557
28557
  }
28558
- const decodedPath = shouldDecode ? decodeURI(path11) : path11;
28558
+ const decodedPath = shouldDecode ? decodeURI(path12) : path12;
28559
28559
  return { path: decodedPath, querystring, shouldDecodeParam };
28560
28560
  }
28561
28561
  function safeDecodeURIComponent(uriComponent) {
@@ -28648,7 +28648,7 @@ var require_find_my_way = __commonJS({
28648
28648
  this.routes = [];
28649
28649
  this.trees = {};
28650
28650
  }
28651
- Router.prototype.on = function on(method, path11, opts, handler, store) {
28651
+ Router.prototype.on = function on(method, path12, opts, handler, store) {
28652
28652
  if (typeof opts === "function") {
28653
28653
  if (handler !== void 0) {
28654
28654
  store = handler;
@@ -28656,34 +28656,34 @@ var require_find_my_way = __commonJS({
28656
28656
  handler = opts;
28657
28657
  opts = {};
28658
28658
  }
28659
- assert2(typeof path11 === "string", "Path should be a string");
28660
- assert2(path11.length > 0, "The path could not be empty");
28661
- assert2(path11[0] === "/" || path11[0] === "*", "The first character of a path should be `/` or `*`");
28659
+ assert2(typeof path12 === "string", "Path should be a string");
28660
+ assert2(path12.length > 0, "The path could not be empty");
28661
+ assert2(path12[0] === "/" || path12[0] === "*", "The first character of a path should be `/` or `*`");
28662
28662
  assert2(typeof handler === "function", "Handler should be a function");
28663
- const optionalParamMatch = path11.match(OPTIONAL_PARAM_REGEXP);
28663
+ const optionalParamMatch = path12.match(OPTIONAL_PARAM_REGEXP);
28664
28664
  if (optionalParamMatch) {
28665
- assert2(path11.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
28666
- const pathFull = path11.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
28667
- const pathOptional = path11.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
28665
+ assert2(path12.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
28666
+ const pathFull = path12.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
28667
+ const pathOptional = path12.replace(OPTIONAL_PARAM_REGEXP, "$2") || "/";
28668
28668
  this.on(method, pathFull, opts, handler, store);
28669
28669
  this.on(method, pathOptional, opts, handler, store);
28670
28670
  return;
28671
28671
  }
28672
- const route = path11;
28672
+ const route = path12;
28673
28673
  if (this.ignoreDuplicateSlashes) {
28674
- path11 = removeDuplicateSlashes(path11);
28674
+ path12 = removeDuplicateSlashes(path12);
28675
28675
  }
28676
28676
  if (this.ignoreTrailingSlash) {
28677
- path11 = trimLastSlash(path11);
28677
+ path12 = trimLastSlash(path12);
28678
28678
  }
28679
28679
  const methods = Array.isArray(method) ? method : [method];
28680
28680
  for (const method2 of methods) {
28681
28681
  assert2(typeof method2 === "string", "Method should be a string");
28682
28682
  assert2(httpMethods.includes(method2), `Method '${method2}' is not an http method.`);
28683
- this._on(method2, path11, opts, handler, store, route);
28683
+ this._on(method2, path12, opts, handler, store, route);
28684
28684
  }
28685
28685
  };
28686
- Router.prototype._on = function _on(method, path11, opts, handler, store) {
28686
+ Router.prototype._on = function _on(method, path12, opts, handler, store) {
28687
28687
  let constraints = {};
28688
28688
  if (opts.constraints !== void 0) {
28689
28689
  assert2(typeof opts.constraints === "object" && opts.constraints !== null, "Constraints should be an object");
@@ -28696,7 +28696,7 @@ var require_find_my_way = __commonJS({
28696
28696
  if (this.trees[method] === void 0) {
28697
28697
  this.trees[method] = new StaticNode("/");
28698
28698
  }
28699
- let pattern = path11;
28699
+ let pattern = path12;
28700
28700
  if (pattern === "*" && this.trees[method].prefix.length !== 0) {
28701
28701
  const currentRoot = this.trees[method];
28702
28702
  this.trees[method] = new StaticNode("");
@@ -28799,19 +28799,19 @@ var require_find_my_way = __commonJS({
28799
28799
  throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`);
28800
28800
  }
28801
28801
  }
28802
- const route = { method, path: path11, pattern, params, opts, handler, store };
28802
+ const route = { method, path: path12, pattern, params, opts, handler, store };
28803
28803
  this.routes.push(route);
28804
28804
  currentNode.addRoute(route, this.constrainer);
28805
28805
  };
28806
- Router.prototype.hasRoute = function hasRoute(method, path11, constraints) {
28807
- const route = this.findRoute(method, path11, constraints);
28806
+ Router.prototype.hasRoute = function hasRoute(method, path12, constraints) {
28807
+ const route = this.findRoute(method, path12, constraints);
28808
28808
  return route !== null;
28809
28809
  };
28810
- Router.prototype.findRoute = function findNode(method, path11, constraints = {}) {
28810
+ Router.prototype.findRoute = function findNode(method, path12, constraints = {}) {
28811
28811
  if (this.trees[method] === void 0) {
28812
28812
  return null;
28813
28813
  }
28814
- let pattern = path11;
28814
+ let pattern = path12;
28815
28815
  let currentNode = this.trees[method];
28816
28816
  let parentNodePathIndex = currentNode.prefix.length;
28817
28817
  const params = [];
@@ -28929,39 +28929,39 @@ var require_find_my_way = __commonJS({
28929
28929
  this.trees = {};
28930
28930
  this.routes = [];
28931
28931
  };
28932
- Router.prototype.off = function off(method, path11, constraints) {
28933
- assert2(typeof path11 === "string", "Path should be a string");
28934
- assert2(path11.length > 0, "The path could not be empty");
28935
- assert2(path11[0] === "/" || path11[0] === "*", "The first character of a path should be `/` or `*`");
28932
+ Router.prototype.off = function off(method, path12, constraints) {
28933
+ assert2(typeof path12 === "string", "Path should be a string");
28934
+ assert2(path12.length > 0, "The path could not be empty");
28935
+ assert2(path12[0] === "/" || path12[0] === "*", "The first character of a path should be `/` or `*`");
28936
28936
  assert2(
28937
28937
  typeof constraints === "undefined" || typeof constraints === "object" && !Array.isArray(constraints) && constraints !== null,
28938
28938
  "Constraints should be an object or undefined."
28939
28939
  );
28940
- const optionalParamMatch = path11.match(OPTIONAL_PARAM_REGEXP);
28940
+ const optionalParamMatch = path12.match(OPTIONAL_PARAM_REGEXP);
28941
28941
  if (optionalParamMatch) {
28942
- assert2(path11.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
28943
- const pathFull = path11.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
28944
- const pathOptional = path11.replace(OPTIONAL_PARAM_REGEXP, "$2");
28942
+ assert2(path12.length === optionalParamMatch.index + optionalParamMatch[0].length, "Optional Parameter needs to be the last parameter of the path");
28943
+ const pathFull = path12.replace(OPTIONAL_PARAM_REGEXP, "$1$2");
28944
+ const pathOptional = path12.replace(OPTIONAL_PARAM_REGEXP, "$2");
28945
28945
  this.off(method, pathFull, constraints);
28946
28946
  this.off(method, pathOptional, constraints);
28947
28947
  return;
28948
28948
  }
28949
28949
  if (this.ignoreDuplicateSlashes) {
28950
- path11 = removeDuplicateSlashes(path11);
28950
+ path12 = removeDuplicateSlashes(path12);
28951
28951
  }
28952
28952
  if (this.ignoreTrailingSlash) {
28953
- path11 = trimLastSlash(path11);
28953
+ path12 = trimLastSlash(path12);
28954
28954
  }
28955
28955
  const methods = Array.isArray(method) ? method : [method];
28956
28956
  for (const method2 of methods) {
28957
- this._off(method2, path11, constraints);
28957
+ this._off(method2, path12, constraints);
28958
28958
  }
28959
28959
  };
28960
- Router.prototype._off = function _off(method, path11, constraints) {
28960
+ Router.prototype._off = function _off(method, path12, constraints) {
28961
28961
  assert2(typeof method === "string", "Method should be a string");
28962
28962
  assert2(httpMethods.includes(method), `Method '${method}' is not an http method.`);
28963
28963
  function matcherWithoutConstraints(route) {
28964
- return method !== route.method || path11 !== route.path;
28964
+ return method !== route.method || path12 !== route.path;
28965
28965
  }
28966
28966
  function matcherWithConstraints(route) {
28967
28967
  return matcherWithoutConstraints(route) || !deepEqual(constraints, route.opts.constraints || {});
@@ -28998,37 +28998,37 @@ var require_find_my_way = __commonJS({
28998
28998
  if (handle === null) return this._defaultRoute(req, res, ctx);
28999
28999
  return ctx === void 0 ? handle.handler(req, res, handle.params, handle.store, handle.searchParams) : handle.handler.call(ctx, req, res, handle.params, handle.store, handle.searchParams);
29000
29000
  };
29001
- Router.prototype.find = function find(method, path11, derivedConstraints) {
29001
+ Router.prototype.find = function find(method, path12, derivedConstraints) {
29002
29002
  let currentNode = this.trees[method];
29003
29003
  if (currentNode === void 0) return null;
29004
- if (path11.charCodeAt(0) !== 47) {
29005
- path11 = path11.replace(FULL_PATH_REGEXP, "/");
29004
+ if (path12.charCodeAt(0) !== 47) {
29005
+ path12 = path12.replace(FULL_PATH_REGEXP, "/");
29006
29006
  }
29007
29007
  if (this.ignoreDuplicateSlashes) {
29008
- path11 = removeDuplicateSlashes(path11);
29008
+ path12 = removeDuplicateSlashes(path12);
29009
29009
  }
29010
29010
  let sanitizedUrl;
29011
29011
  let querystring2;
29012
29012
  let shouldDecodeParam;
29013
29013
  try {
29014
- sanitizedUrl = safeDecodeURI(path11, this.useSemicolonDelimiter);
29015
- path11 = sanitizedUrl.path;
29014
+ sanitizedUrl = safeDecodeURI(path12, this.useSemicolonDelimiter);
29015
+ path12 = sanitizedUrl.path;
29016
29016
  querystring2 = sanitizedUrl.querystring;
29017
29017
  shouldDecodeParam = sanitizedUrl.shouldDecodeParam;
29018
29018
  } catch (error48) {
29019
- return this._onBadUrl(path11);
29019
+ return this._onBadUrl(path12);
29020
29020
  }
29021
29021
  if (this.ignoreTrailingSlash) {
29022
- path11 = trimLastSlash(path11);
29022
+ path12 = trimLastSlash(path12);
29023
29023
  }
29024
- const originPath = path11;
29024
+ const originPath = path12;
29025
29025
  if (this.caseSensitive === false) {
29026
- path11 = path11.toLowerCase();
29026
+ path12 = path12.toLowerCase();
29027
29027
  }
29028
29028
  const maxParamLength = this.maxParamLength;
29029
29029
  let pathIndex = currentNode.prefix.length;
29030
29030
  const params = [];
29031
- const pathLen = path11.length;
29031
+ const pathLen = path12.length;
29032
29032
  const brothersNodesStack = [];
29033
29033
  while (true) {
29034
29034
  if (pathIndex === pathLen && currentNode.isLeafNode) {
@@ -29042,7 +29042,7 @@ var require_find_my_way = __commonJS({
29042
29042
  };
29043
29043
  }
29044
29044
  }
29045
- let node = currentNode.getNextNode(path11, pathIndex, brothersNodesStack, params.length);
29045
+ let node = currentNode.getNextNode(path12, pathIndex, brothersNodesStack, params.length);
29046
29046
  if (node === null) {
29047
29047
  if (brothersNodesStack.length === 0) {
29048
29048
  return null;
@@ -29093,11 +29093,11 @@ var require_find_my_way = __commonJS({
29093
29093
  pathIndex = paramEndIndex;
29094
29094
  }
29095
29095
  };
29096
- Router.prototype._rebuild = function(routes23) {
29096
+ Router.prototype._rebuild = function(routes24) {
29097
29097
  this.reset();
29098
- for (const route of routes23) {
29099
- const { method, path: path11, opts, handler, store } = route;
29100
- this._on(method, path11, opts, handler, store);
29098
+ for (const route of routes24) {
29099
+ const { method, path: path12, opts, handler, store } = route;
29100
+ this._on(method, path12, opts, handler, store);
29101
29101
  }
29102
29102
  };
29103
29103
  Router.prototype._defaultRoute = function(req, res, ctx) {
@@ -29108,13 +29108,13 @@ var require_find_my_way = __commonJS({
29108
29108
  res.end();
29109
29109
  }
29110
29110
  };
29111
- Router.prototype._onBadUrl = function(path11) {
29111
+ Router.prototype._onBadUrl = function(path12) {
29112
29112
  if (this.onBadUrl === null) {
29113
29113
  return null;
29114
29114
  }
29115
29115
  const onBadUrl = this.onBadUrl;
29116
29116
  return {
29117
- handler: (req, res, ctx) => onBadUrl(path11, req, res),
29117
+ handler: (req, res, ctx) => onBadUrl(path12, req, res),
29118
29118
  params: {},
29119
29119
  store: null
29120
29120
  };
@@ -29146,12 +29146,12 @@ var require_find_my_way = __commonJS({
29146
29146
  if (!httpMethods.hasOwnProperty(i)) continue;
29147
29147
  const m = httpMethods[i];
29148
29148
  const methodName = m.toLowerCase();
29149
- Router.prototype[methodName] = function(path11, handler, store) {
29150
- return this.on(m, path11, handler, store);
29149
+ Router.prototype[methodName] = function(path12, handler, store) {
29150
+ return this.on(m, path12, handler, store);
29151
29151
  };
29152
29152
  }
29153
- Router.prototype.all = function(path11, handler, store) {
29154
- this.on(httpMethods, path11, handler, store);
29153
+ Router.prototype.all = function(path12, handler, store) {
29154
+ this.on(httpMethods, path12, handler, store);
29155
29155
  };
29156
29156
  Router.sanitizeUrlPath = function sanitizeUrlPath(url2, useSemicolonDelimiter) {
29157
29157
  const decoded = safeDecodeURI(url2, useSemicolonDelimiter);
@@ -29164,14 +29164,14 @@ var require_find_my_way = __commonJS({
29164
29164
  function escapeRegExp(string4) {
29165
29165
  return string4.replace(ESCAPE_REGEXP, "\\$&");
29166
29166
  }
29167
- function removeDuplicateSlashes(path11) {
29168
- return path11.indexOf("//") !== -1 ? path11.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, "/") : path11;
29167
+ function removeDuplicateSlashes(path12) {
29168
+ return path12.indexOf("//") !== -1 ? path12.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, "/") : path12;
29169
29169
  }
29170
- function trimLastSlash(path11) {
29171
- if (path11.length > 1 && path11.charCodeAt(path11.length - 1) === 47) {
29172
- return path11.slice(0, -1);
29170
+ function trimLastSlash(path12) {
29171
+ if (path12.length > 1 && path12.charCodeAt(path12.length - 1) === 47) {
29172
+ return path12.slice(0, -1);
29173
29173
  }
29174
- return path11;
29174
+ return path12;
29175
29175
  }
29176
29176
  function trimRegExpStartAndEnd(regexString) {
29177
29177
  if (regexString.charCodeAt(1) === 94) {
@@ -29182,22 +29182,22 @@ var require_find_my_way = __commonJS({
29182
29182
  }
29183
29183
  return regexString;
29184
29184
  }
29185
- function getClosingParenthensePosition(path11, idx) {
29185
+ function getClosingParenthensePosition(path12, idx) {
29186
29186
  let parentheses = 1;
29187
- while (idx < path11.length) {
29187
+ while (idx < path12.length) {
29188
29188
  idx++;
29189
- if (path11.charCodeAt(idx) === 92) {
29189
+ if (path12.charCodeAt(idx) === 92) {
29190
29190
  idx++;
29191
29191
  continue;
29192
29192
  }
29193
- if (path11.charCodeAt(idx) === 41) {
29193
+ if (path12.charCodeAt(idx) === 41) {
29194
29194
  parentheses--;
29195
- } else if (path11.charCodeAt(idx) === 40) {
29195
+ } else if (path12.charCodeAt(idx) === 40) {
29196
29196
  parentheses++;
29197
29197
  }
29198
29198
  if (!parentheses) return idx;
29199
29199
  }
29200
- throw new TypeError('Invalid regexp expression in "' + path11 + '"');
29200
+ throw new TypeError('Invalid regexp expression in "' + path12 + '"');
29201
29201
  }
29202
29202
  function defaultBuildPrettyMeta(route) {
29203
29203
  if (!route) return {};
@@ -29429,12 +29429,12 @@ var require_route = __commonJS({
29429
29429
  function route({ options: options2, isFastify }) {
29430
29430
  throwIfAlreadyStarted("Cannot add route!");
29431
29431
  const opts = { ...options2 };
29432
- const path11 = opts.url || opts.path || "";
29432
+ const path12 = opts.url || opts.path || "";
29433
29433
  if (!opts.handler) {
29434
- throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method, path11);
29434
+ throw new FST_ERR_ROUTE_MISSING_HANDLER(opts.method, path12);
29435
29435
  }
29436
29436
  if (opts.errorHandler !== void 0 && typeof opts.errorHandler !== "function") {
29437
- throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method, path11);
29437
+ throw new FST_ERR_ROUTE_HANDLER_NOT_FN(opts.method, path12);
29438
29438
  }
29439
29439
  validateBodyLimitOption(opts.bodyLimit);
29440
29440
  const shouldExposeHead = opts.exposeHeadRoute ?? globalExposeHeadRoutes;
@@ -29443,22 +29443,22 @@ var require_route = __commonJS({
29443
29443
  if (Array.isArray(opts.method)) {
29444
29444
  for (let i = 0; i < opts.method.length; ++i) {
29445
29445
  opts.method[i] = normalizeAndValidateMethod.call(this, opts.method[i]);
29446
- validateSchemaBodyOption.call(this, opts.method[i], path11, opts.schema);
29446
+ validateSchemaBodyOption.call(this, opts.method[i], path12, opts.schema);
29447
29447
  isGetRoute = opts.method.includes("GET");
29448
29448
  isHeadRoute = opts.method.includes("HEAD");
29449
29449
  }
29450
29450
  } else {
29451
29451
  opts.method = normalizeAndValidateMethod.call(this, opts.method);
29452
- validateSchemaBodyOption.call(this, opts.method, path11, opts.schema);
29452
+ validateSchemaBodyOption.call(this, opts.method, path12, opts.schema);
29453
29453
  isGetRoute = opts.method === "GET";
29454
29454
  isHeadRoute = opts.method === "HEAD";
29455
29455
  }
29456
29456
  const headOpts = shouldExposeHead && isGetRoute ? { ...options2 } : null;
29457
29457
  const prefix = this[kRoutePrefix];
29458
- if (path11 === "/" && prefix.length > 0 && opts.method !== "HEAD") {
29458
+ if (path12 === "/" && prefix.length > 0 && opts.method !== "HEAD") {
29459
29459
  switch (opts.prefixTrailingSlash) {
29460
29460
  case "slash":
29461
- addNewRoute.call(this, { path: path11, isFastify });
29461
+ addNewRoute.call(this, { path: path12, isFastify });
29462
29462
  break;
29463
29463
  case "no-slash":
29464
29464
  addNewRoute.call(this, { path: "", isFastify });
@@ -29467,20 +29467,20 @@ var require_route = __commonJS({
29467
29467
  default:
29468
29468
  addNewRoute.call(this, { path: "", isFastify });
29469
29469
  if (ignoreTrailingSlash !== true && (ignoreDuplicateSlashes !== true || !prefix.endsWith("/"))) {
29470
- addNewRoute.call(this, { path: path11, prefixing: true, isFastify });
29470
+ addNewRoute.call(this, { path: path12, prefixing: true, isFastify });
29471
29471
  }
29472
29472
  }
29473
- } else if (path11[0] === "/" && prefix.endsWith("/")) {
29474
- addNewRoute.call(this, { path: path11.slice(1), isFastify });
29473
+ } else if (path12[0] === "/" && prefix.endsWith("/")) {
29474
+ addNewRoute.call(this, { path: path12.slice(1), isFastify });
29475
29475
  } else {
29476
- addNewRoute.call(this, { path: path11, isFastify });
29476
+ addNewRoute.call(this, { path: path12, isFastify });
29477
29477
  }
29478
29478
  return this;
29479
- function addNewRoute({ path: path12, prefixing = false, isFastify: isFastify2 = false }) {
29480
- const url2 = prefix + path12;
29479
+ function addNewRoute({ path: path13, prefixing = false, isFastify: isFastify2 = false }) {
29480
+ const url2 = prefix + path13;
29481
29481
  opts.url = url2;
29482
29482
  opts.path = url2;
29483
- opts.routePath = path12;
29483
+ opts.routePath = path13;
29484
29484
  opts.prefix = prefix;
29485
29485
  opts.logLevel = opts.logLevel || this[kLogLevel];
29486
29486
  if (this[kLogSerializers] || opts.logSerializers) {
@@ -29609,7 +29609,7 @@ var require_route = __commonJS({
29609
29609
  });
29610
29610
  if (shouldExposeHead && isGetRoute && !isHeadRoute && !hasHEADHandler) {
29611
29611
  const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend);
29612
- prepareRoute.call(this, { method: "HEAD", url: path12, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true });
29612
+ prepareRoute.call(this, { method: "HEAD", url: path13, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true });
29613
29613
  }
29614
29614
  }
29615
29615
  }
@@ -29712,9 +29712,9 @@ var require_route = __commonJS({
29712
29712
  }
29713
29713
  return method;
29714
29714
  }
29715
- function validateSchemaBodyOption(method, path11, schema) {
29715
+ function validateSchemaBodyOption(method, path12, schema) {
29716
29716
  if (this[kSupportedHTTPMethods].bodyless.has(method) && schema?.body) {
29717
- throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method, path11);
29717
+ throw new FST_ERR_ROUTE_BODY_VALIDATION_SCHEMA_NOT_SUPPORTED(method, path12);
29718
29718
  }
29719
29719
  }
29720
29720
  function validateBodyLimitOption(bodyLimit) {
@@ -29807,7 +29807,7 @@ var require_four_oh_four = __commonJS({
29807
29807
  });
29808
29808
  }
29809
29809
  function createOnBadUrl() {
29810
- return function onBadUrl(path11, req, res) {
29810
+ return function onBadUrl(path12, req, res) {
29811
29811
  const fourOhFourContext = this[kFourOhFourLevelInstance][kFourOhFourContext];
29812
29812
  const id = getGenReqId(fourOhFourContext.server, req);
29813
29813
  const childLogger = createChildLogger(fourOhFourContext, logger, req, id);
@@ -31496,7 +31496,7 @@ var require_parse_url = __commonJS({
31496
31496
  var require_form_data = __commonJS({
31497
31497
  "../../node_modules/.pnpm/light-my-request@6.6.0/node_modules/light-my-request/lib/form-data.js"(exports, module) {
31498
31498
  "use strict";
31499
- var { randomUUID: randomUUID13 } = __require("node:crypto");
31499
+ var { randomUUID: randomUUID14 } = __require("node:crypto");
31500
31500
  var { Readable: Readable4 } = __require("node:stream");
31501
31501
  var textEncoder;
31502
31502
  function isFormDataLike(payload) {
@@ -31504,7 +31504,7 @@ var require_form_data = __commonJS({
31504
31504
  }
31505
31505
  function formDataToStream(formdata) {
31506
31506
  textEncoder = textEncoder ?? new TextEncoder();
31507
- const boundary = `----formdata-${randomUUID13()}`;
31507
+ const boundary = `----formdata-${randomUUID14()}`;
31508
31508
  const prefix = `--${boundary}\r
31509
31509
  Content-Disposition: form-data`;
31510
31510
  const escape2 = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22");
@@ -33638,7 +33638,7 @@ var require_fastify = __commonJS({
33638
33638
  }
33639
33639
  fourOhFour.router.lookup(req, res);
33640
33640
  }
33641
- function onBadUrl(path11, req, res) {
33641
+ function onBadUrl(path12, req, res) {
33642
33642
  if (options.frameworkErrors) {
33643
33643
  const id = getGenReqId(onBadUrlContext.server, req);
33644
33644
  const childLogger = createChildLogger(onBadUrlContext, options.logger, req, id);
@@ -33648,12 +33648,12 @@ var require_fastify = __commonJS({
33648
33648
  if (resolvedDisableRequestLogging === false) {
33649
33649
  childLogger.info({ req: request }, "incoming request");
33650
33650
  }
33651
- return options.frameworkErrors(new FST_ERR_BAD_URL(path11), request, reply);
33651
+ return options.frameworkErrors(new FST_ERR_BAD_URL(path12), request, reply);
33652
33652
  }
33653
33653
  const body = JSON.stringify({
33654
33654
  error: "Bad Request",
33655
33655
  code: "FST_ERR_BAD_URL",
33656
- message: `'${path11}' is not a valid url component`,
33656
+ message: `'${path12}' is not a valid url component`,
33657
33657
  statusCode: 400
33658
33658
  });
33659
33659
  res.writeHead(400, {
@@ -34855,11 +34855,11 @@ var require_commonjs3 = __commonJS({
34855
34855
  return (f) => f.length === len && f !== "." && f !== "..";
34856
34856
  };
34857
34857
  var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
34858
- var path11 = {
34858
+ var path12 = {
34859
34859
  win32: { sep: "\\" },
34860
34860
  posix: { sep: "/" }
34861
34861
  };
34862
- exports.sep = defaultPlatform === "win32" ? path11.win32.sep : path11.posix.sep;
34862
+ exports.sep = defaultPlatform === "win32" ? path12.win32.sep : path12.posix.sep;
34863
34863
  exports.minimatch.sep = exports.sep;
34864
34864
  exports.GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
34865
34865
  exports.minimatch.GLOBSTAR = exports.GLOBSTAR;
@@ -38176,12 +38176,12 @@ var require_commonjs6 = __commonJS({
38176
38176
  /**
38177
38177
  * Get the Path object referenced by the string path, resolved from this Path
38178
38178
  */
38179
- resolve(path11) {
38180
- if (!path11) {
38179
+ resolve(path12) {
38180
+ if (!path12) {
38181
38181
  return this;
38182
38182
  }
38183
- const rootPath = this.getRootString(path11);
38184
- const dir = path11.substring(rootPath.length);
38183
+ const rootPath = this.getRootString(path12);
38184
+ const dir = path12.substring(rootPath.length);
38185
38185
  const dirParts = dir.split(this.splitSep);
38186
38186
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
38187
38187
  return result;
@@ -38303,8 +38303,8 @@ var require_commonjs6 = __commonJS({
38303
38303
  return this.#fullpath = this.name;
38304
38304
  }
38305
38305
  const pv = p.fullpath();
38306
- const fp24 = pv + (!p.parent ? "" : this.sep) + name25;
38307
- return this.#fullpath = fp24;
38306
+ const fp25 = pv + (!p.parent ? "" : this.sep) + name25;
38307
+ return this.#fullpath = fp25;
38308
38308
  }
38309
38309
  /**
38310
38310
  * On platforms other than windows, this is identical to fullpath.
@@ -38934,8 +38934,8 @@ var require_commonjs6 = __commonJS({
38934
38934
  /**
38935
38935
  * @internal
38936
38936
  */
38937
- getRootString(path11) {
38938
- return node_path_1.win32.parse(path11).root;
38937
+ getRootString(path12) {
38938
+ return node_path_1.win32.parse(path12).root;
38939
38939
  }
38940
38940
  /**
38941
38941
  * @internal
@@ -38982,8 +38982,8 @@ var require_commonjs6 = __commonJS({
38982
38982
  /**
38983
38983
  * @internal
38984
38984
  */
38985
- getRootString(path11) {
38986
- return path11.startsWith("/") ? "/" : "";
38985
+ getRootString(path12) {
38986
+ return path12.startsWith("/") ? "/" : "";
38987
38987
  }
38988
38988
  /**
38989
38989
  * @internal
@@ -39073,11 +39073,11 @@ var require_commonjs6 = __commonJS({
39073
39073
  /**
39074
39074
  * Get the depth of a provided path, string, or the cwd
39075
39075
  */
39076
- depth(path11 = this.cwd) {
39077
- if (typeof path11 === "string") {
39078
- path11 = this.cwd.resolve(path11);
39076
+ depth(path12 = this.cwd) {
39077
+ if (typeof path12 === "string") {
39078
+ path12 = this.cwd.resolve(path12);
39079
39079
  }
39080
- return path11.depth();
39080
+ return path12.depth();
39081
39081
  }
39082
39082
  /**
39083
39083
  * Return the cache of child entries. Exposed so subclasses can create
@@ -39564,9 +39564,9 @@ var require_commonjs6 = __commonJS({
39564
39564
  process9();
39565
39565
  return results;
39566
39566
  }
39567
- chdir(path11 = this.cwd) {
39567
+ chdir(path12 = this.cwd) {
39568
39568
  const oldCwd = this.cwd;
39569
- this.cwd = typeof path11 === "string" ? this.cwd.resolve(path11) : path11;
39569
+ this.cwd = typeof path12 === "string" ? this.cwd.resolve(path12) : path12;
39570
39570
  this.cwd[setAsCwd](oldCwd);
39571
39571
  }
39572
39572
  };
@@ -39954,8 +39954,8 @@ var require_processor = __commonJS({
39954
39954
  }
39955
39955
  // match, absolute, ifdir
39956
39956
  entries() {
39957
- return [...this.store.entries()].map(([path11, n]) => [
39958
- path11,
39957
+ return [...this.store.entries()].map(([path12, n]) => [
39958
+ path12,
39959
39959
  !!(n & 2),
39960
39960
  !!(n & 1)
39961
39961
  ]);
@@ -40173,9 +40173,9 @@ var require_walker = __commonJS({
40173
40173
  signal;
40174
40174
  maxDepth;
40175
40175
  includeChildMatches;
40176
- constructor(patterns, path11, opts) {
40176
+ constructor(patterns, path12, opts) {
40177
40177
  this.patterns = patterns;
40178
- this.path = path11;
40178
+ this.path = path12;
40179
40179
  this.opts = opts;
40180
40180
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
40181
40181
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -40194,11 +40194,11 @@ var require_walker = __commonJS({
40194
40194
  });
40195
40195
  }
40196
40196
  }
40197
- #ignored(path11) {
40198
- return this.seen.has(path11) || !!this.#ignore?.ignored?.(path11);
40197
+ #ignored(path12) {
40198
+ return this.seen.has(path12) || !!this.#ignore?.ignored?.(path12);
40199
40199
  }
40200
- #childrenIgnored(path11) {
40201
- return !!this.#ignore?.childrenIgnored?.(path11);
40200
+ #childrenIgnored(path12) {
40201
+ return !!this.#ignore?.childrenIgnored?.(path12);
40202
40202
  }
40203
40203
  // backpressure mechanism
40204
40204
  pause() {
@@ -40414,8 +40414,8 @@ var require_walker = __commonJS({
40414
40414
  exports.GlobUtil = GlobUtil;
40415
40415
  var GlobWalker = class extends GlobUtil {
40416
40416
  matches = /* @__PURE__ */ new Set();
40417
- constructor(patterns, path11, opts) {
40418
- super(patterns, path11, opts);
40417
+ constructor(patterns, path12, opts) {
40418
+ super(patterns, path12, opts);
40419
40419
  }
40420
40420
  matchEmit(e) {
40421
40421
  this.matches.add(e);
@@ -40453,8 +40453,8 @@ var require_walker = __commonJS({
40453
40453
  exports.GlobWalker = GlobWalker;
40454
40454
  var GlobStream = class extends GlobUtil {
40455
40455
  results;
40456
- constructor(patterns, path11, opts) {
40457
- super(patterns, path11, opts);
40456
+ constructor(patterns, path12, opts) {
40457
+ super(patterns, path12, opts);
40458
40458
  this.results = new minipass_1.Minipass({
40459
40459
  signal: this.signal,
40460
40460
  objectMode: true
@@ -40946,11 +40946,11 @@ var require_Mime = __commonJS({
40946
40946
  }
40947
40947
  }
40948
40948
  };
40949
- Mime.prototype.getType = function(path11) {
40950
- path11 = String(path11);
40951
- let last = path11.replace(/^.*[/\\]/, "").toLowerCase();
40949
+ Mime.prototype.getType = function(path12) {
40950
+ path12 = String(path12);
40951
+ let last = path12.replace(/^.*[/\\]/, "").toLowerCase();
40952
40952
  let ext = last.replace(/^.*\./, "").toLowerCase();
40953
- let hasPath = last.length < path11.length;
40953
+ let hasPath = last.length < path12.length;
40954
40954
  let hasDot = ext.length < last.length - 1;
40955
40955
  return (hasDot || !hasPath) && this._types[ext] || null;
40956
40956
  };
@@ -41980,7 +41980,7 @@ var require_send = __commonJS({
41980
41980
  "../../node_modules/.pnpm/@fastify+send@4.1.0/node_modules/@fastify/send/lib/send.js"(exports, module) {
41981
41981
  "use strict";
41982
41982
  var fs7 = __require("node:fs");
41983
- var path11 = __require("node:path");
41983
+ var path12 = __require("node:path");
41984
41984
  var stream = __require("node:stream");
41985
41985
  var debug = __require("node:util").debuglog("send");
41986
41986
  var decode3 = require_fast_decode_uri_component();
@@ -41996,11 +41996,11 @@ var require_send = __commonJS({
41996
41996
  var { parseBytesRange } = require_parseBytesRange();
41997
41997
  var { parseTokenList } = require_parseTokenList();
41998
41998
  var { createHttpError } = require_createHttpError();
41999
- var extname = path11.extname;
42000
- var join = path11.join;
42001
- var normalize = path11.normalize;
42002
- var resolve2 = path11.resolve;
42003
- var sep = path11.sep;
41999
+ var extname = path12.extname;
42000
+ var join = path12.join;
42001
+ var normalize = path12.normalize;
42002
+ var resolve2 = path12.resolve;
42003
+ var sep = path12.sep;
42004
42004
  var Readable4 = stream.Readable;
42005
42005
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
42006
42006
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
@@ -42067,36 +42067,36 @@ var require_send = __commonJS({
42067
42067
  };
42068
42068
  }
42069
42069
  function normalizePath(_path, root) {
42070
- let path12 = decode3(_path);
42071
- if (path12 == null) {
42070
+ let path13 = decode3(_path);
42071
+ if (path13 == null) {
42072
42072
  return { statusCode: 400 };
42073
42073
  }
42074
- if (~path12.indexOf("\0")) {
42074
+ if (~path13.indexOf("\0")) {
42075
42075
  return { statusCode: 400 };
42076
42076
  }
42077
42077
  let parts;
42078
42078
  if (root !== null) {
42079
- if (path12) {
42080
- path12 = normalize("." + sep + path12);
42079
+ if (path13) {
42080
+ path13 = normalize("." + sep + path13);
42081
42081
  }
42082
- if (UP_PATH_REGEXP.test(path12)) {
42083
- debug('malicious path "%s"', path12);
42082
+ if (UP_PATH_REGEXP.test(path13)) {
42083
+ debug('malicious path "%s"', path13);
42084
42084
  return { statusCode: 403 };
42085
42085
  }
42086
- parts = path12.split(sep);
42087
- path12 = normalize(join(root, path12));
42086
+ parts = path13.split(sep);
42087
+ path13 = normalize(join(root, path13));
42088
42088
  } else {
42089
- if (UP_PATH_REGEXP.test(path12)) {
42090
- debug('malicious path "%s"', path12);
42089
+ if (UP_PATH_REGEXP.test(path13)) {
42090
+ debug('malicious path "%s"', path13);
42091
42091
  return { statusCode: 403 };
42092
42092
  }
42093
- parts = normalize(path12).split(sep);
42094
- path12 = resolve2(path12);
42093
+ parts = normalize(path13).split(sep);
42094
+ path13 = resolve2(path13);
42095
42095
  }
42096
- return { path: path12, parts };
42096
+ return { path: path13, parts };
42097
42097
  }
42098
- function hasTrailingSlash2(path12) {
42099
- return path12[path12.length - 1] === "/";
42098
+ function hasTrailingSlash2(path13) {
42099
+ return path13[path13.length - 1] === "/";
42100
42100
  }
42101
42101
  function isConditionalGET(request) {
42102
42102
  return request.headers["if-match"] || request.headers["if-unmodified-since"] || request.headers["if-none-match"] || request.headers["if-modified-since"];
@@ -42186,9 +42186,9 @@ var require_send = __commonJS({
42186
42186
  lastModified <= ifRangeTimestamp
42187
42187
  );
42188
42188
  }
42189
- function tryStat(path12) {
42189
+ function tryStat(path13) {
42190
42190
  return new Promise((resolve3) => {
42191
- fs7.stat(path12, function onstat(error48, stat) {
42191
+ fs7.stat(path13, function onstat(error48, stat) {
42192
42192
  resolve3({ error: error48, stat });
42193
42193
  });
42194
42194
  });
@@ -42224,7 +42224,7 @@ var require_send = __commonJS({
42224
42224
  return sendError(500, err);
42225
42225
  }
42226
42226
  }
42227
- function sendNotModified(headers, path12, stat) {
42227
+ function sendNotModified(headers, path13, stat) {
42228
42228
  debug("not modified");
42229
42229
  delete headers["Content-Encoding"];
42230
42230
  delete headers["Content-Language"];
@@ -42237,15 +42237,15 @@ var require_send = __commonJS({
42237
42237
  stream: Readable4.from(""),
42238
42238
  // metadata
42239
42239
  type: "file",
42240
- metadata: { path: path12, stat }
42240
+ metadata: { path: path13, stat }
42241
42241
  };
42242
42242
  }
42243
- function sendFileDirectly(request, path12, stat, options) {
42243
+ function sendFileDirectly(request, path13, stat, options) {
42244
42244
  let len = stat.size;
42245
42245
  let offset = options.start ?? 0;
42246
42246
  let statusCode = 200;
42247
42247
  const headers = {};
42248
- debug('send "%s"', path12);
42248
+ debug('send "%s"', path13);
42249
42249
  if (options.acceptRanges) {
42250
42250
  debug("accept ranges");
42251
42251
  headers["Accept-Ranges"] = "bytes";
@@ -42269,7 +42269,7 @@ var require_send = __commonJS({
42269
42269
  headers.ETag = etag;
42270
42270
  }
42271
42271
  if (options.contentType) {
42272
- let type = mime.getType(path12) || mime.default_type;
42272
+ let type = mime.getType(path13) || mime.default_type;
42273
42273
  debug("content-type %s", type);
42274
42274
  if (type && isUtf8MimeType(type)) {
42275
42275
  type += "; charset=utf-8";
@@ -42283,7 +42283,7 @@ var require_send = __commonJS({
42283
42283
  return sendError(412);
42284
42284
  }
42285
42285
  if (isNotModifiedFailure(request, headers)) {
42286
- return sendNotModified(headers, path12, stat);
42286
+ return sendNotModified(headers, path13, stat);
42287
42287
  }
42288
42288
  }
42289
42289
  len = Math.max(0, len - offset);
@@ -42325,10 +42325,10 @@ var require_send = __commonJS({
42325
42325
  stream: Readable4.from(""),
42326
42326
  // metadata
42327
42327
  type: "file",
42328
- metadata: { path: path12, stat }
42328
+ metadata: { path: path13, stat }
42329
42329
  };
42330
42330
  }
42331
- const stream2 = fs7.createReadStream(path12, {
42331
+ const stream2 = fs7.createReadStream(path13, {
42332
42332
  highWaterMark: options.highWaterMark,
42333
42333
  start: offset,
42334
42334
  end: Math.max(offset, offset + len - 1)
@@ -42339,10 +42339,10 @@ var require_send = __commonJS({
42339
42339
  stream: stream2,
42340
42340
  // metadata
42341
42341
  type: "file",
42342
- metadata: { path: path12, stat }
42342
+ metadata: { path: path13, stat }
42343
42343
  };
42344
42344
  }
42345
- function sendRedirect(path12, options) {
42345
+ function sendRedirect(path13, options) {
42346
42346
  if (hasTrailingSlash2(options.path)) {
42347
42347
  return sendError(403);
42348
42348
  }
@@ -42360,14 +42360,14 @@ var require_send = __commonJS({
42360
42360
  stream: Readable4.from(doc[0]),
42361
42361
  // metadata
42362
42362
  type: "directory",
42363
- metadata: { requestPath: options.path, path: path12 }
42363
+ metadata: { requestPath: options.path, path: path13 }
42364
42364
  };
42365
42365
  }
42366
- async function sendIndex(request, path12, options) {
42366
+ async function sendIndex(request, path13, options) {
42367
42367
  let err;
42368
42368
  for (let i = 0; i < options.index.length; i++) {
42369
42369
  const index = options.index[i];
42370
- const p = join(path12, index);
42370
+ const p = join(path13, index);
42371
42371
  const { error: error48, stat } = await tryStat(p);
42372
42372
  if (error48) {
42373
42373
  err = error48;
@@ -42381,13 +42381,13 @@ var require_send = __commonJS({
42381
42381
  }
42382
42382
  return sendError(404);
42383
42383
  }
42384
- async function sendFile(request, path12, options) {
42385
- const { error: error48, stat } = await tryStat(path12);
42386
- if (error48 && error48.code === "ENOENT" && !extname(path12) && path12[path12.length - 1] !== sep) {
42384
+ async function sendFile(request, path13, options) {
42385
+ const { error: error48, stat } = await tryStat(path13);
42386
+ if (error48 && error48.code === "ENOENT" && !extname(path13) && path13[path13.length - 1] !== sep) {
42387
42387
  let err = error48;
42388
42388
  for (let i = 0; i < options.extensions.length; i++) {
42389
42389
  const extension = options.extensions[i];
42390
- const p = path12 + "." + extension;
42390
+ const p = path13 + "." + extension;
42391
42391
  const { error: error49, stat: stat2 } = await tryStat(p);
42392
42392
  if (error49) {
42393
42393
  err = error49;
@@ -42405,14 +42405,14 @@ var require_send = __commonJS({
42405
42405
  return sendError(404);
42406
42406
  }
42407
42407
  if (error48) return sendStatError(error48);
42408
- if (stat.isDirectory()) return sendRedirect(path12, options);
42409
- return sendFileDirectly(request, path12, stat, options);
42408
+ if (stat.isDirectory()) return sendRedirect(path13, options);
42409
+ return sendFileDirectly(request, path13, stat, options);
42410
42410
  }
42411
42411
  async function send(request, _path, options) {
42412
42412
  const opts = normalizeOptions(options);
42413
42413
  opts.path = _path;
42414
42414
  const parsed = normalizePath(_path, opts.root);
42415
- const { path: path12, parts } = parsed;
42415
+ const { path: path13, parts } = parsed;
42416
42416
  if (parsed.statusCode !== void 0) {
42417
42417
  return sendError(parsed.statusCode);
42418
42418
  }
@@ -42422,23 +42422,23 @@ var require_send = __commonJS({
42422
42422
  /* c8 ignore start */
42423
42423
  /* unreachable, because NODE_DEBUG can not be set after process is running */
42424
42424
  case 0:
42425
- debug('allow dotfile "%s"', path12);
42425
+ debug('allow dotfile "%s"', path13);
42426
42426
  break;
42427
42427
  /* c8 ignore stop */
42428
42428
  case 2:
42429
- debug('deny dotfile "%s"', path12);
42429
+ debug('deny dotfile "%s"', path13);
42430
42430
  return sendError(403);
42431
42431
  case 1:
42432
42432
  // 'ignore'
42433
42433
  default:
42434
- debug('ignore dotfile "%s"', path12);
42434
+ debug('ignore dotfile "%s"', path13);
42435
42435
  return sendError(404);
42436
42436
  }
42437
42437
  }
42438
42438
  if (opts.index.length && hasTrailingSlash2(_path)) {
42439
- return sendIndex(request, path12, opts);
42439
+ return sendIndex(request, path13, opts);
42440
42440
  }
42441
- return sendFile(request, path12, opts);
42441
+ return sendFile(request, path13, opts);
42442
42442
  }
42443
42443
  module.exports.send = send;
42444
42444
  }
@@ -42825,16 +42825,16 @@ var require_dirList = __commonJS({
42825
42825
  "../../node_modules/.pnpm/@fastify+static@8.3.0/node_modules/@fastify/static/lib/dirList.js"(exports, module) {
42826
42826
  "use strict";
42827
42827
  var os2 = __require("node:os");
42828
- var path11 = __require("node:path");
42828
+ var path12 = __require("node:path");
42829
42829
  var fs7 = __require("node:fs/promises");
42830
42830
  var fastq = require_queue();
42831
42831
  var fastqConcurrency = Math.max(1, os2.cpus().length - 1);
42832
42832
  var dirList = {
42833
42833
  _getExtendedInfo: async function(dir, info) {
42834
- const depth = dir.split(path11.sep).length;
42834
+ const depth = dir.split(path12.sep).length;
42835
42835
  const files = await fs7.readdir(dir);
42836
42836
  const worker = async (filename) => {
42837
- const filePath = path11.join(dir, filename);
42837
+ const filePath = path12.join(dir, filename);
42838
42838
  let stats;
42839
42839
  try {
42840
42840
  stats = await fs7.stat(filePath);
@@ -42843,12 +42843,12 @@ var require_dirList = __commonJS({
42843
42843
  }
42844
42844
  if (stats.isDirectory()) {
42845
42845
  info.totalFolderCount++;
42846
- filePath.split(path11.sep).length === depth + 1 && info.folderCount++;
42846
+ filePath.split(path12.sep).length === depth + 1 && info.folderCount++;
42847
42847
  await dirList._getExtendedInfo(filePath, info);
42848
42848
  } else {
42849
42849
  info.totalSize += stats.size;
42850
42850
  info.totalFileCount++;
42851
- filePath.split(path11.sep).length === depth + 1 && info.fileCount++;
42851
+ filePath.split(path12.sep).length === depth + 1 && info.fileCount++;
42852
42852
  info.lastModified = Math.max(info.lastModified, stats.mtimeMs);
42853
42853
  }
42854
42854
  };
@@ -42891,14 +42891,14 @@ var require_dirList = __commonJS({
42891
42891
  const worker = async (filename) => {
42892
42892
  let stats;
42893
42893
  try {
42894
- stats = await fs7.stat(path11.join(dir, filename));
42894
+ stats = await fs7.stat(path12.join(dir, filename));
42895
42895
  } catch {
42896
42896
  return;
42897
42897
  }
42898
42898
  const entry = { name: filename, stats };
42899
42899
  if (stats.isDirectory()) {
42900
42900
  if (options.extendedFolderInfo) {
42901
- entry.extendedInfo = await dirList.getExtendedInfo(path11.join(dir, filename));
42901
+ entry.extendedInfo = await dirList.getExtendedInfo(path12.join(dir, filename));
42902
42902
  }
42903
42903
  entries.dirs.push(entry);
42904
42904
  } else {
@@ -42954,11 +42954,11 @@ var require_dirList = __commonJS({
42954
42954
  * @return {ListFile}
42955
42955
  */
42956
42956
  htmlInfo: function(entry, route, prefix, options) {
42957
- if (options.names?.includes(path11.basename(route))) {
42958
- route = path11.normalize(path11.join(route, ".."));
42957
+ if (options.names?.includes(path12.basename(route))) {
42958
+ route = path12.normalize(path12.join(route, ".."));
42959
42959
  }
42960
42960
  return {
42961
- href: encodeURI(path11.join(prefix, route, entry.name).replace(/\\/gu, "/")),
42961
+ href: encodeURI(path12.join(prefix, route, entry.name).replace(/\\/gu, "/")),
42962
42962
  name: entry.name,
42963
42963
  stats: entry.stats,
42964
42964
  extendedInfo: entry.extendedInfo
@@ -42971,7 +42971,7 @@ var require_dirList = __commonJS({
42971
42971
  * @return {boolean}
42972
42972
  */
42973
42973
  handle: function(route, options) {
42974
- return options.names?.includes(path11.basename(route)) || // match trailing slash
42974
+ return options.names?.includes(path12.basename(route)) || // match trailing slash
42975
42975
  ((options.names?.includes("/") && route[route.length - 1] === "/") ?? false);
42976
42976
  },
42977
42977
  /**
@@ -42981,7 +42981,7 @@ var require_dirList = __commonJS({
42981
42981
  */
42982
42982
  path: function(root, route) {
42983
42983
  const _route = route[route.length - 1] === "/" ? route + "none" : route;
42984
- return path11.dirname(path11.join(root, _route));
42984
+ return path12.dirname(path12.join(root, _route));
42985
42985
  },
42986
42986
  /**
42987
42987
  * validate options
@@ -43016,11 +43016,11 @@ var require_dirList = __commonJS({
43016
43016
  var require_static = __commonJS({
43017
43017
  "../../node_modules/.pnpm/@fastify+static@8.3.0/node_modules/@fastify/static/index.js"(exports, module) {
43018
43018
  "use strict";
43019
- var path11 = __require("node:path");
43019
+ var path12 = __require("node:path");
43020
43020
  var { fileURLToPath: fileURLToPath3 } = __require("node:url");
43021
43021
  var { statSync: statSync2 } = __require("node:fs");
43022
43022
  var { glob } = require_commonjs7();
43023
- var fp24 = require_plugin2();
43023
+ var fp25 = require_plugin2();
43024
43024
  var send = require_send2();
43025
43025
  var encodingNegotiator = require_accept_negotiator();
43026
43026
  var contentDisposition = require_content_disposition();
@@ -43124,10 +43124,10 @@ var require_static = __commonJS({
43124
43124
  } else {
43125
43125
  const indexes = new Set(opts.index === void 0 ? ["index.html"] : [].concat(opts.index));
43126
43126
  const indexDirs = /* @__PURE__ */ new Map();
43127
- const routes23 = /* @__PURE__ */ new Set();
43127
+ const routes24 = /* @__PURE__ */ new Set();
43128
43128
  const roots = Array.isArray(sendOptions.root) ? sendOptions.root : [sendOptions.root];
43129
43129
  for (let rootPath of roots) {
43130
- rootPath = rootPath.split(path11.win32.sep).join(path11.posix.sep);
43130
+ rootPath = rootPath.split(path12.win32.sep).join(path12.posix.sep);
43131
43131
  !rootPath.endsWith("/") && (rootPath += "/");
43132
43132
  const files = await glob("**/**", {
43133
43133
  cwd: rootPath,
@@ -43138,16 +43138,16 @@ var require_static = __commonJS({
43138
43138
  ignore: opts.globIgnore
43139
43139
  });
43140
43140
  for (let file2 of files) {
43141
- file2 = file2.split(path11.win32.sep).join(path11.posix.sep);
43141
+ file2 = file2.split(path12.win32.sep).join(path12.posix.sep);
43142
43142
  const route = prefix + file2;
43143
- if (routes23.has(route)) {
43143
+ if (routes24.has(route)) {
43144
43144
  continue;
43145
43145
  }
43146
- routes23.add(route);
43146
+ routes24.add(route);
43147
43147
  setUpHeadAndGet(routeOpts, route, `/${file2}`, rootPath);
43148
- const key = path11.posix.basename(route);
43148
+ const key = path12.posix.basename(route);
43149
43149
  if (indexes.has(key) && !indexDirs.has(key)) {
43150
- indexDirs.set(path11.posix.dirname(route), rootPath);
43150
+ indexDirs.set(path12.posix.dirname(route), rootPath);
43151
43151
  }
43152
43152
  }
43153
43153
  }
@@ -43171,7 +43171,7 @@ var require_static = __commonJS({
43171
43171
  } else {
43172
43172
  options.root = rootPath;
43173
43173
  }
43174
- } else if (path11.isAbsolute(pathname) === false) {
43174
+ } else if (path12.isAbsolute(pathname) === false) {
43175
43175
  return reply.callNotFound();
43176
43176
  }
43177
43177
  if (allowedPath && !allowedPath(pathname, options.root, request)) {
@@ -43203,11 +43203,11 @@ var require_static = __commonJS({
43203
43203
  } = await send(request.raw, encodeURI(pathnameForSend), options);
43204
43204
  switch (type) {
43205
43205
  case "directory": {
43206
- const path12 = metadata.path;
43206
+ const path13 = metadata.path;
43207
43207
  if (opts.list) {
43208
43208
  await dirList.send({
43209
43209
  reply,
43210
- dir: path12,
43210
+ dir: path13,
43211
43211
  options: opts.list,
43212
43212
  route: pathname,
43213
43213
  prefix,
@@ -43364,7 +43364,7 @@ var require_static = __commonJS({
43364
43364
  '"root" option array contains one or more duplicate paths'
43365
43365
  );
43366
43366
  }
43367
- rootPath.map((path12) => checkPath(fastify2, path12));
43367
+ rootPath.map((path13) => checkPath(fastify2, path13));
43368
43368
  return;
43369
43369
  }
43370
43370
  if (typeof rootPath === "string") {
@@ -43376,7 +43376,7 @@ var require_static = __commonJS({
43376
43376
  if (typeof rootPath !== "string") {
43377
43377
  throw new TypeError('"root" option must be a string');
43378
43378
  }
43379
- if (path11.isAbsolute(rootPath) === false) {
43379
+ if (path12.isAbsolute(rootPath) === false) {
43380
43380
  throw new Error('"root" option must be an absolute path');
43381
43381
  }
43382
43382
  let pathStat;
@@ -43393,8 +43393,8 @@ var require_static = __commonJS({
43393
43393
  throw new Error('"root" option must point to a directory');
43394
43394
  }
43395
43395
  }
43396
- function getContentType(path12) {
43397
- const type = send.mime.getType(path12) || send.mime.default_type;
43396
+ function getContentType(path13) {
43397
+ const type = send.mime.getType(path13) || send.mime.default_type;
43398
43398
  if (!send.isUtf8MimeType(type)) {
43399
43399
  return type;
43400
43400
  }
@@ -43403,7 +43403,7 @@ var require_static = __commonJS({
43403
43403
  function findIndexFile(pathname, root, indexFiles = ["index.html"]) {
43404
43404
  if (Array.isArray(indexFiles)) {
43405
43405
  return indexFiles.find((filename) => {
43406
- const p = path11.join(root, pathname, filename);
43406
+ const p = path12.join(root, pathname, filename);
43407
43407
  try {
43408
43408
  const stats = statSync2(p);
43409
43409
  return !stats.isDirectory();
@@ -43438,7 +43438,7 @@ var require_static = __commonJS({
43438
43438
  throw err;
43439
43439
  }
43440
43440
  }
43441
- module.exports = fp24(fastifyStatic2, {
43441
+ module.exports = fp25(fastifyStatic2, {
43442
43442
  fastify: "5.x",
43443
43443
  name: "@fastify/static"
43444
43444
  });
@@ -50081,7 +50081,7 @@ var require_websocket2 = __commonJS({
50081
50081
  var { ServerResponse } = __require("node:http");
50082
50082
  var { PassThrough } = __require("node:stream");
50083
50083
  var { randomBytes } = __require("node:crypto");
50084
- var fp24 = require_plugin2();
50084
+ var fp25 = require_plugin2();
50085
50085
  var WebSocket2 = require_ws();
50086
50086
  var Duplexify = require_duplexify();
50087
50087
  var kWs = /* @__PURE__ */ Symbol("ws-socket");
@@ -50114,7 +50114,7 @@ var require_websocket2 = __commonJS({
50114
50114
  delete wssOptions.server;
50115
50115
  const wss = new WebSocket2.Server(wssOptions);
50116
50116
  fastify2.decorate("websocketServer", wss);
50117
- async function injectWS(path11 = "/", upgradeContext = {}, options = {}) {
50117
+ async function injectWS(path12 = "/", upgradeContext = {}, options = {}) {
50118
50118
  const server2Client = new PassThrough();
50119
50119
  const client2Server = new PassThrough();
50120
50120
  const serverStream = new Duplexify(server2Client, client2Server);
@@ -50154,7 +50154,7 @@ var require_websocket2 = __commonJS({
50154
50154
  "sec-websocket-key": randomBytes(16).toString("base64")
50155
50155
  },
50156
50156
  httpVersion: "1.1",
50157
- url: path11,
50157
+ url: path12,
50158
50158
  [kWs]: serverStream,
50159
50159
  [kWsHead]: head
50160
50160
  };
@@ -50267,7 +50267,7 @@ var require_websocket2 = __commonJS({
50267
50267
  }
50268
50268
  next();
50269
50269
  }
50270
- module.exports = fp24(fastifyWebsocket2, {
50270
+ module.exports = fp25(fastifyWebsocket2, {
50271
50271
  fastify: "5.x",
50272
50272
  name: "@fastify/websocket"
50273
50273
  });
@@ -50390,19 +50390,19 @@ var require_token_io = __commonJS({
50390
50390
  getUserDataDir: () => getUserDataDir
50391
50391
  });
50392
50392
  module.exports = __toCommonJS(token_io_exports);
50393
- var import_path9 = __toESM3(__require("path"));
50394
- var import_fs4 = __toESM3(__require("fs"));
50393
+ var import_path10 = __toESM3(__require("path"));
50394
+ var import_fs5 = __toESM3(__require("fs"));
50395
50395
  var import_os3 = __toESM3(__require("os"));
50396
50396
  var import_token_error = require_token_error();
50397
50397
  function findRootDir() {
50398
50398
  try {
50399
50399
  let dir = process.cwd();
50400
- while (dir !== import_path9.default.dirname(dir)) {
50401
- const pkgPath = import_path9.default.join(dir, ".vercel");
50402
- if (import_fs4.default.existsSync(pkgPath)) {
50400
+ while (dir !== import_path10.default.dirname(dir)) {
50401
+ const pkgPath = import_path10.default.join(dir, ".vercel");
50402
+ if (import_fs5.default.existsSync(pkgPath)) {
50403
50403
  return dir;
50404
50404
  }
50405
- dir = import_path9.default.dirname(dir);
50405
+ dir = import_path10.default.dirname(dir);
50406
50406
  }
50407
50407
  } catch (e) {
50408
50408
  throw new import_token_error.VercelOidcTokenError(
@@ -50417,9 +50417,9 @@ var require_token_io = __commonJS({
50417
50417
  }
50418
50418
  switch (import_os3.default.platform()) {
50419
50419
  case "darwin":
50420
- return import_path9.default.join(import_os3.default.homedir(), "Library/Application Support");
50420
+ return import_path10.default.join(import_os3.default.homedir(), "Library/Application Support");
50421
50421
  case "linux":
50422
- return import_path9.default.join(import_os3.default.homedir(), ".local/share");
50422
+ return import_path10.default.join(import_os3.default.homedir(), ".local/share");
50423
50423
  case "win32":
50424
50424
  if (process.env.LOCALAPPDATA) {
50425
50425
  return process.env.LOCALAPPDATA;
@@ -50471,7 +50471,7 @@ var require_auth_config = __commonJS({
50471
50471
  });
50472
50472
  module.exports = __toCommonJS(auth_config_exports);
50473
50473
  var fs7 = __toESM3(__require("fs"));
50474
- var path11 = __toESM3(__require("path"));
50474
+ var path12 = __toESM3(__require("path"));
50475
50475
  var import_token_util = require_token_util();
50476
50476
  function getAuthConfigPath() {
50477
50477
  const dataDir = (0, import_token_util.getVercelDataDir)();
@@ -50480,7 +50480,7 @@ var require_auth_config = __commonJS({
50480
50480
  `Unable to find Vercel CLI data directory. Your platform: ${process.platform}. Supported: darwin, linux, win32.`
50481
50481
  );
50482
50482
  }
50483
- return path11.join(dataDir, "auth.json");
50483
+ return path12.join(dataDir, "auth.json");
50484
50484
  }
50485
50485
  function readAuthConfig() {
50486
50486
  try {
@@ -50499,7 +50499,7 @@ var require_auth_config = __commonJS({
50499
50499
  }
50500
50500
  function writeAuthConfig(config2) {
50501
50501
  const authPath = getAuthConfigPath();
50502
- const authDir = path11.dirname(authPath);
50502
+ const authDir = path12.dirname(authPath);
50503
50503
  if (!fs7.existsSync(authDir)) {
50504
50504
  fs7.mkdirSync(authDir, { mode: 504, recursive: true });
50505
50505
  }
@@ -50649,7 +50649,7 @@ var require_token_util = __commonJS({
50649
50649
  saveToken: () => saveToken
50650
50650
  });
50651
50651
  module.exports = __toCommonJS(token_util_exports);
50652
- var path11 = __toESM3(__require("path"));
50652
+ var path12 = __toESM3(__require("path"));
50653
50653
  var fs7 = __toESM3(__require("fs"));
50654
50654
  var import_token_error = require_token_error();
50655
50655
  var import_token_io = require_token_io();
@@ -50661,7 +50661,7 @@ var require_token_util = __commonJS({
50661
50661
  if (!dataDir) {
50662
50662
  return null;
50663
50663
  }
50664
- return path11.join(dataDir, vercelFolder);
50664
+ return path12.join(dataDir, vercelFolder);
50665
50665
  }
50666
50666
  async function getVercelCliToken() {
50667
50667
  const authConfig = (0, import_auth_config.readAuthConfig)();
@@ -50734,7 +50734,7 @@ var require_token_util = __commonJS({
50734
50734
  "Unable to find project root directory. Have you linked your project with `vc link?`"
50735
50735
  );
50736
50736
  }
50737
- const prjPath = path11.join(dir, ".vercel", "project.json");
50737
+ const prjPath = path12.join(dir, ".vercel", "project.json");
50738
50738
  if (!fs7.existsSync(prjPath)) {
50739
50739
  throw new import_token_error.VercelOidcTokenError(
50740
50740
  "project.json not found, have you linked your project with `vc link?`"
@@ -50755,9 +50755,9 @@ var require_token_util = __commonJS({
50755
50755
  "Unable to find user data directory. Please reach out to Vercel support."
50756
50756
  );
50757
50757
  }
50758
- const tokenPath = path11.join(dir, "com.vercel.token", `${projectId}.json`);
50758
+ const tokenPath = path12.join(dir, "com.vercel.token", `${projectId}.json`);
50759
50759
  const tokenJson = JSON.stringify(token);
50760
- fs7.mkdirSync(path11.dirname(tokenPath), { mode: 504, recursive: true });
50760
+ fs7.mkdirSync(path12.dirname(tokenPath), { mode: 504, recursive: true });
50761
50761
  fs7.writeFileSync(tokenPath, tokenJson);
50762
50762
  fs7.chmodSync(tokenPath, 432);
50763
50763
  return;
@@ -50769,7 +50769,7 @@ var require_token_util = __commonJS({
50769
50769
  "Unable to find user data directory. Please reach out to Vercel support."
50770
50770
  );
50771
50771
  }
50772
- const tokenPath = path11.join(dir, "com.vercel.token", `${projectId}.json`);
50772
+ const tokenPath = path12.join(dir, "com.vercel.token", `${projectId}.json`);
50773
50773
  if (!fs7.existsSync(tokenPath)) {
50774
50774
  return null;
50775
50775
  }
@@ -52142,14 +52142,14 @@ var require_util3 = __commonJS({
52142
52142
  }
52143
52143
  const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
52144
52144
  let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
52145
- let path11 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
52145
+ let path12 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
52146
52146
  if (origin[origin.length - 1] === "/") {
52147
52147
  origin = origin.slice(0, origin.length - 1);
52148
52148
  }
52149
- if (path11 && path11[0] !== "/") {
52150
- path11 = `/${path11}`;
52149
+ if (path12 && path12[0] !== "/") {
52150
+ path12 = `/${path12}`;
52151
52151
  }
52152
- return new URL(`${origin}${path11}`);
52152
+ return new URL(`${origin}${path12}`);
52153
52153
  }
52154
52154
  if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
52155
52155
  throw new InvalidArgumentError4("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -52954,9 +52954,9 @@ var require_diagnostics = __commonJS({
52954
52954
  "undici:client:sendHeaders",
52955
52955
  (evt) => {
52956
52956
  const {
52957
- request: { method, path: path11, origin }
52957
+ request: { method, path: path12, origin }
52958
52958
  } = evt;
52959
- debugLog("sending request to %s %s%s", method, origin, path11);
52959
+ debugLog("sending request to %s %s%s", method, origin, path12);
52960
52960
  }
52961
52961
  );
52962
52962
  }
@@ -52974,14 +52974,14 @@ var require_diagnostics = __commonJS({
52974
52974
  "undici:request:headers",
52975
52975
  (evt) => {
52976
52976
  const {
52977
- request: { method, path: path11, origin },
52977
+ request: { method, path: path12, origin },
52978
52978
  response: { statusCode }
52979
52979
  } = evt;
52980
52980
  debugLog(
52981
52981
  "received response to %s %s%s - HTTP %d",
52982
52982
  method,
52983
52983
  origin,
52984
- path11,
52984
+ path12,
52985
52985
  statusCode
52986
52986
  );
52987
52987
  }
@@ -52990,23 +52990,23 @@ var require_diagnostics = __commonJS({
52990
52990
  "undici:request:trailers",
52991
52991
  (evt) => {
52992
52992
  const {
52993
- request: { method, path: path11, origin }
52993
+ request: { method, path: path12, origin }
52994
52994
  } = evt;
52995
- debugLog("trailers received from %s %s%s", method, origin, path11);
52995
+ debugLog("trailers received from %s %s%s", method, origin, path12);
52996
52996
  }
52997
52997
  );
52998
52998
  diagnosticsChannel.subscribe(
52999
52999
  "undici:request:error",
53000
53000
  (evt) => {
53001
53001
  const {
53002
- request: { method, path: path11, origin },
53002
+ request: { method, path: path12, origin },
53003
53003
  error: error48
53004
53004
  } = evt;
53005
53005
  debugLog(
53006
53006
  "request to %s %s%s errored - %s",
53007
53007
  method,
53008
53008
  origin,
53009
- path11,
53009
+ path12,
53010
53010
  error48.message
53011
53011
  );
53012
53012
  }
@@ -53106,7 +53106,7 @@ var require_request3 = __commonJS({
53106
53106
  var kHandler = /* @__PURE__ */ Symbol("handler");
53107
53107
  var Request2 = class {
53108
53108
  constructor(origin, {
53109
- path: path11,
53109
+ path: path12,
53110
53110
  method,
53111
53111
  body,
53112
53112
  headers,
@@ -53122,11 +53122,11 @@ var require_request3 = __commonJS({
53122
53122
  throwOnError,
53123
53123
  maxRedirections
53124
53124
  }, handler) {
53125
- if (typeof path11 !== "string") {
53125
+ if (typeof path12 !== "string") {
53126
53126
  throw new InvalidArgumentError4("path must be a string");
53127
- } else if (path11[0] !== "/" && !(path11.startsWith("http://") || path11.startsWith("https://")) && method !== "CONNECT") {
53127
+ } else if (path12[0] !== "/" && !(path12.startsWith("http://") || path12.startsWith("https://")) && method !== "CONNECT") {
53128
53128
  throw new InvalidArgumentError4("path must be an absolute URL or start with a slash");
53129
- } else if (invalidPathRegex.test(path11)) {
53129
+ } else if (invalidPathRegex.test(path12)) {
53130
53130
  throw new InvalidArgumentError4("invalid request path");
53131
53131
  }
53132
53132
  if (typeof method !== "string") {
@@ -53194,7 +53194,7 @@ var require_request3 = __commonJS({
53194
53194
  this.completed = false;
53195
53195
  this.aborted = false;
53196
53196
  this.upgrade = upgrade || null;
53197
- this.path = query ? serializePathWithQuery(path11, query) : path11;
53197
+ this.path = query ? serializePathWithQuery(path12, query) : path12;
53198
53198
  this.origin = origin;
53199
53199
  this.protocol = getProtocolFromUrlString(origin);
53200
53200
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -58211,7 +58211,7 @@ var require_client_h1 = __commonJS({
58211
58211
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
58212
58212
  }
58213
58213
  function writeH1(client, request) {
58214
- const { method, path: path11, host, upgrade, blocking, reset } = request;
58214
+ const { method, path: path12, host, upgrade, blocking, reset } = request;
58215
58215
  let { body, headers, contentLength } = request;
58216
58216
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
58217
58217
  if (util2.isFormDataLike(body)) {
@@ -58277,7 +58277,7 @@ var require_client_h1 = __commonJS({
58277
58277
  if (blocking) {
58278
58278
  socket[kBlocking] = true;
58279
58279
  }
58280
- let header = `${method} ${path11} HTTP/1.1\r
58280
+ let header = `${method} ${path12} HTTP/1.1\r
58281
58281
  `;
58282
58282
  if (typeof host === "string") {
58283
58283
  header += `host: ${host}\r
@@ -58930,7 +58930,7 @@ var require_client_h2 = __commonJS({
58930
58930
  function writeH2(client, request) {
58931
58931
  const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
58932
58932
  const session = client[kHTTP2Session];
58933
- const { method, path: path11, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
58933
+ const { method, path: path12, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
58934
58934
  let { body } = request;
58935
58935
  if (upgrade != null && upgrade !== "websocket") {
58936
58936
  util2.errorRequest(client, request, new InvalidArgumentError4(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -58998,7 +58998,7 @@ var require_client_h2 = __commonJS({
58998
58998
  }
58999
58999
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
59000
59000
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
59001
- headers[HTTP2_HEADER_PATH] = path11;
59001
+ headers[HTTP2_HEADER_PATH] = path12;
59002
59002
  if (protocol === "ws:" || protocol === "wss:") {
59003
59003
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
59004
59004
  } else {
@@ -59039,7 +59039,7 @@ var require_client_h2 = __commonJS({
59039
59039
  stream.setTimeout(requestTimeout);
59040
59040
  return true;
59041
59041
  }
59042
- headers[HTTP2_HEADER_PATH] = path11;
59042
+ headers[HTTP2_HEADER_PATH] = path12;
59043
59043
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
59044
59044
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
59045
59045
  if (body && typeof body.read === "function") {
@@ -60663,10 +60663,10 @@ var require_proxy_agent = __commonJS({
60663
60663
  };
60664
60664
  const {
60665
60665
  origin,
60666
- path: path11 = "/",
60666
+ path: path12 = "/",
60667
60667
  headers = {}
60668
60668
  } = opts;
60669
- opts.path = origin + path11;
60669
+ opts.path = origin + path12;
60670
60670
  if (!("host" in headers) && !("Host" in headers)) {
60671
60671
  const { host } = new URL(origin);
60672
60672
  headers.host = host;
@@ -62707,20 +62707,20 @@ var require_mock_utils = __commonJS({
62707
62707
  }
62708
62708
  return normalizedQp;
62709
62709
  }
62710
- function safeUrl(path11) {
62711
- if (typeof path11 !== "string") {
62712
- return path11;
62710
+ function safeUrl(path12) {
62711
+ if (typeof path12 !== "string") {
62712
+ return path12;
62713
62713
  }
62714
- const pathSegments = path11.split("?", 3);
62714
+ const pathSegments = path12.split("?", 3);
62715
62715
  if (pathSegments.length !== 2) {
62716
- return path11;
62716
+ return path12;
62717
62717
  }
62718
62718
  const qp = new URLSearchParams(pathSegments.pop());
62719
62719
  qp.sort();
62720
62720
  return [...pathSegments, qp.toString()].join("?");
62721
62721
  }
62722
- function matchKey(mockDispatch2, { path: path11, method, body, headers }) {
62723
- const pathMatch = matchValue(mockDispatch2.path, path11);
62722
+ function matchKey(mockDispatch2, { path: path12, method, body, headers }) {
62723
+ const pathMatch = matchValue(mockDispatch2.path, path12);
62724
62724
  const methodMatch = matchValue(mockDispatch2.method, method);
62725
62725
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
62726
62726
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -62745,8 +62745,8 @@ var require_mock_utils = __commonJS({
62745
62745
  const basePath33 = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
62746
62746
  const resolvedPath = typeof basePath33 === "string" ? safeUrl(basePath33) : basePath33;
62747
62747
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
62748
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path11, ignoreTrailingSlash }) => {
62749
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path11)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path11), resolvedPath);
62748
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path12, ignoreTrailingSlash }) => {
62749
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path12)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path12), resolvedPath);
62750
62750
  });
62751
62751
  if (matchedMockDispatches.length === 0) {
62752
62752
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -62784,19 +62784,19 @@ var require_mock_utils = __commonJS({
62784
62784
  mockDispatches.splice(index, 1);
62785
62785
  }
62786
62786
  }
62787
- function removeTrailingSlash(path11) {
62788
- while (path11.endsWith("/")) {
62789
- path11 = path11.slice(0, -1);
62787
+ function removeTrailingSlash(path12) {
62788
+ while (path12.endsWith("/")) {
62789
+ path12 = path12.slice(0, -1);
62790
62790
  }
62791
- if (path11.length === 0) {
62792
- path11 = "/";
62791
+ if (path12.length === 0) {
62792
+ path12 = "/";
62793
62793
  }
62794
- return path11;
62794
+ return path12;
62795
62795
  }
62796
62796
  function buildKey(opts) {
62797
- const { path: path11, method, body, headers, query } = opts;
62797
+ const { path: path12, method, body, headers, query } = opts;
62798
62798
  return {
62799
- path: path11,
62799
+ path: path12,
62800
62800
  method,
62801
62801
  body,
62802
62802
  headers,
@@ -63483,10 +63483,10 @@ var require_pending_interceptors_formatter = __commonJS({
63483
63483
  }
63484
63484
  format(pendingInterceptors) {
63485
63485
  const withPrettyHeaders = pendingInterceptors.map(
63486
- ({ method, path: path11, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
63486
+ ({ method, path: path12, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
63487
63487
  Method: method,
63488
63488
  Origin: origin,
63489
- Path: path11,
63489
+ Path: path12,
63490
63490
  "Status code": statusCode,
63491
63491
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
63492
63492
  Invocations: timesInvoked,
@@ -63568,9 +63568,9 @@ var require_mock_agent = __commonJS({
63568
63568
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
63569
63569
  const dispatchOpts = { ...opts };
63570
63570
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
63571
- const [path11, searchParams] = dispatchOpts.path.split("?");
63571
+ const [path12, searchParams] = dispatchOpts.path.split("?");
63572
63572
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
63573
- dispatchOpts.path = `${path11}?${normalizedSearchParams}`;
63573
+ dispatchOpts.path = `${path12}?${normalizedSearchParams}`;
63574
63574
  }
63575
63575
  return this[kAgent].dispatch(dispatchOpts, handler);
63576
63576
  }
@@ -63971,12 +63971,12 @@ var require_snapshot_recorder = __commonJS({
63971
63971
  * @return {Promise<void>} - Resolves when snapshots are loaded
63972
63972
  */
63973
63973
  async loadSnapshots(filePath) {
63974
- const path11 = filePath || this.#snapshotPath;
63975
- if (!path11) {
63974
+ const path12 = filePath || this.#snapshotPath;
63975
+ if (!path12) {
63976
63976
  throw new InvalidArgumentError4("Snapshot path is required");
63977
63977
  }
63978
63978
  try {
63979
- const data = await readFile(resolve2(path11), "utf8");
63979
+ const data = await readFile(resolve2(path12), "utf8");
63980
63980
  const parsed = JSON.parse(data);
63981
63981
  if (Array.isArray(parsed)) {
63982
63982
  this.#snapshots.clear();
@@ -63990,7 +63990,7 @@ var require_snapshot_recorder = __commonJS({
63990
63990
  if (error48.code === "ENOENT") {
63991
63991
  this.#snapshots.clear();
63992
63992
  } else {
63993
- throw new UndiciError(`Failed to load snapshots from ${path11}`, { cause: error48 });
63993
+ throw new UndiciError(`Failed to load snapshots from ${path12}`, { cause: error48 });
63994
63994
  }
63995
63995
  }
63996
63996
  }
@@ -64001,11 +64001,11 @@ var require_snapshot_recorder = __commonJS({
64001
64001
  * @returns {Promise<void>} - Resolves when snapshots are saved
64002
64002
  */
64003
64003
  async saveSnapshots(filePath) {
64004
- const path11 = filePath || this.#snapshotPath;
64005
- if (!path11) {
64004
+ const path12 = filePath || this.#snapshotPath;
64005
+ if (!path12) {
64006
64006
  throw new InvalidArgumentError4("Snapshot path is required");
64007
64007
  }
64008
- const resolvedPath = resolve2(path11);
64008
+ const resolvedPath = resolve2(path12);
64009
64009
  await mkdir3(dirname(resolvedPath), { recursive: true });
64010
64010
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
64011
64011
  hash: hash2,
@@ -64630,15 +64630,15 @@ var require_redirect_handler = __commonJS({
64630
64630
  return;
64631
64631
  }
64632
64632
  const { origin, pathname, search } = util2.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
64633
- const path11 = search ? `${pathname}${search}` : pathname;
64634
- const redirectUrlString = `${origin}${path11}`;
64633
+ const path12 = search ? `${pathname}${search}` : pathname;
64634
+ const redirectUrlString = `${origin}${path12}`;
64635
64635
  for (const historyUrl of this.history) {
64636
64636
  if (historyUrl.toString() === redirectUrlString) {
64637
64637
  throw new InvalidArgumentError4(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
64638
64638
  }
64639
64639
  }
64640
64640
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
64641
- this.opts.path = path11;
64641
+ this.opts.path = path12;
64642
64642
  this.opts.origin = origin;
64643
64643
  this.opts.query = null;
64644
64644
  }
@@ -71515,9 +71515,9 @@ var require_util6 = __commonJS({
71515
71515
  }
71516
71516
  }
71517
71517
  }
71518
- function validateCookiePath(path11) {
71519
- for (let i = 0; i < path11.length; ++i) {
71520
- const code = path11.charCodeAt(i);
71518
+ function validateCookiePath(path12) {
71519
+ for (let i = 0; i < path12.length; ++i) {
71520
+ const code = path12.charCodeAt(i);
71521
71521
  if (code < 32 || // exclude CTLs (0-31)
71522
71522
  code === 127 || // DEL
71523
71523
  code === 59) {
@@ -74628,11 +74628,11 @@ var require_undici = __commonJS({
74628
74628
  if (typeof opts.path !== "string") {
74629
74629
  throw new InvalidArgumentError4("invalid opts.path");
74630
74630
  }
74631
- let path11 = opts.path;
74631
+ let path12 = opts.path;
74632
74632
  if (!opts.path.startsWith("/")) {
74633
- path11 = `/${path11}`;
74633
+ path12 = `/${path12}`;
74634
74634
  }
74635
- url2 = new URL(util2.parseOrigin(url2).origin + path11);
74635
+ url2 = new URL(util2.parseOrigin(url2).origin + path12);
74636
74636
  } else {
74637
74637
  if (!opts) {
74638
74638
  opts = typeof url2 === "object" ? url2 : {};
@@ -82017,12 +82017,12 @@ function buildRequest(options) {
82017
82017
  userAgent = USER_AGENT,
82018
82018
  skipApiVersionInUrl = false
82019
82019
  } = options;
82020
- const { path: path11, method, queryParams, headerParams, bodyParams, formData, options: opts } = requestOptions;
82020
+ const { path: path12, method, queryParams, headerParams, bodyParams, formData, options: opts } = requestOptions;
82021
82021
  const { deepSnakecaseBodyParamKeys = false } = opts || {};
82022
82022
  if (requireSecretKey) {
82023
82023
  assertValidSecretKey(secretKey);
82024
82024
  }
82025
- const url2 = skipApiVersionInUrl ? joinPaths(apiUrl, path11) : joinPaths(apiUrl, apiVersion, path11);
82025
+ const url2 = skipApiVersionInUrl ? joinPaths(apiUrl, path12) : joinPaths(apiUrl, apiVersion, path12);
82026
82026
  const finalUrl = new URL(url2);
82027
82027
  if (queryParams) {
82028
82028
  const snakecasedQueryParams = snakecase_keys_default({ ...queryParams });
@@ -84431,10 +84431,10 @@ var init_chunk_JW73PKED = __esm({
84431
84431
  */
84432
84432
  async getToken(sessionId, template, expiresInSeconds) {
84433
84433
  this.requireId(sessionId);
84434
- const path11 = template ? joinPaths(basePath25, sessionId, "tokens", template) : joinPaths(basePath25, sessionId, "tokens");
84434
+ const path12 = template ? joinPaths(basePath25, sessionId, "tokens", template) : joinPaths(basePath25, sessionId, "tokens");
84435
84435
  const requestOptions = {
84436
84436
  method: "POST",
84437
- path: path11
84437
+ path: path12
84438
84438
  };
84439
84439
  if (expiresInSeconds !== void 0) {
84440
84440
  requestOptions.bodyParams = { expires_in_seconds: expiresInSeconds };
@@ -89546,11 +89546,11 @@ function buildCommand(builderArgs) {
89546
89546
  }
89547
89547
  };
89548
89548
  }
89549
- function* generateRouteMapHelpLines(routes23, docs, args) {
89549
+ function* generateRouteMapHelpLines(routes24, docs, args) {
89550
89550
  const { brief, fullDescription, hideRoute } = docs;
89551
89551
  const { headers } = args.text;
89552
89552
  yield args.ansiColor ? `\x1B[1m${headers.usage}\x1B[22m` : headers.usage;
89553
- for (const [name25, route] of Object.entries(routes23)) {
89553
+ for (const [name25, route] of Object.entries(routes24)) {
89554
89554
  if (!hideRoute || !hideRoute[name25] || args.includeHidden) {
89555
89555
  const externalRouteName = args.config.caseStyle === "convert-camel-to-kebab" ? convertCamelCaseToKebabCase(name25) : name25;
89556
89556
  yield ` ${route.formatUsageLine({
@@ -89580,7 +89580,7 @@ function* generateRouteMapHelpLines(routes23, docs, args) {
89580
89580
  }
89581
89581
  yield "";
89582
89582
  yield args.ansiColor ? `\x1B[1m${headers.commands}\x1B[22m` : headers.commands;
89583
- const visibleRoutes = Object.entries(routes23).filter(
89583
+ const visibleRoutes = Object.entries(routes24).filter(
89584
89584
  ([name25]) => !hideRoute || !hideRoute[name25] || args.includeHidden
89585
89585
  );
89586
89586
  const rows = visibleRoutes.map(([internalRouteName, route]) => {
@@ -89608,24 +89608,24 @@ function* generateRouteMapHelpLines(routes23, docs, args) {
89608
89608
  }
89609
89609
  }
89610
89610
  function buildRouteMap({
89611
- routes: routes23,
89611
+ routes: routes24,
89612
89612
  defaultCommand: defaultCommandRoute,
89613
89613
  docs,
89614
89614
  aliases
89615
89615
  }) {
89616
- if (Object.entries(routes23).length === 0) {
89616
+ if (Object.entries(routes24).length === 0) {
89617
89617
  throw new InternalError("Route map must contain at least one route");
89618
89618
  }
89619
89619
  const activeAliases = aliases ?? {};
89620
89620
  const aliasesByRoute = /* @__PURE__ */ new Map();
89621
89621
  for (const [alias, routeName] of Object.entries(activeAliases)) {
89622
- if (alias in routes23) {
89622
+ if (alias in routes24) {
89623
89623
  throw new InternalError(`Cannot use "${alias}" as an alias when a route with that name already exists`);
89624
89624
  }
89625
89625
  const routeAliases = aliasesByRoute.get(routeName) ?? [];
89626
89626
  aliasesByRoute.set(routeName, [...routeAliases, alias]);
89627
89627
  }
89628
- const defaultCommand = defaultCommandRoute ? routes23[defaultCommandRoute] : void 0;
89628
+ const defaultCommand = defaultCommandRoute ? routes24[defaultCommandRoute] : void 0;
89629
89629
  if (defaultCommand && defaultCommand.kind === RouteMapSymbol) {
89630
89630
  throw new InternalError(
89631
89631
  `Cannot use "${defaultCommandRoute}" as the default command because it is not a Command`
@@ -89634,7 +89634,7 @@ function buildRouteMap({
89634
89634
  const resolveRouteName = (input) => {
89635
89635
  if (input in activeAliases) {
89636
89636
  return activeAliases[input];
89637
- } else if (input in routes23) {
89637
+ } else if (input in routes24) {
89638
89638
  return input;
89639
89639
  }
89640
89640
  };
@@ -89652,7 +89652,7 @@ function buildRouteMap({
89652
89652
  return `${args.prefix.join(" ")} ${routeNames.join("|")} ...`;
89653
89653
  },
89654
89654
  formatHelp: (config2) => {
89655
- const lines = [...generateRouteMapHelpLines(routes23, docs, config2)];
89655
+ const lines = [...generateRouteMapHelpLines(routes24, docs, config2)];
89656
89656
  const text2 = lines.join("\n");
89657
89657
  return text2 + "\n";
89658
89658
  },
@@ -89695,11 +89695,11 @@ function buildRouteMap({
89695
89695
  },
89696
89696
  getRoutingTargetForInput: (input) => {
89697
89697
  const routeName = input in activeAliases ? activeAliases[input] : input;
89698
- return routes23[routeName];
89698
+ return routes24[routeName];
89699
89699
  },
89700
89700
  getAllEntries() {
89701
89701
  const hiddenRoutes = docs.hideRoute;
89702
- return Object.entries(routes23).map(([originalRouteName, target]) => {
89702
+ return Object.entries(routes24).map(([originalRouteName, target]) => {
89703
89703
  return {
89704
89704
  name: {
89705
89705
  original: originalRouteName,
@@ -89719,7 +89719,7 @@ async function run(app, inputs, context2) {
89719
89719
  }
89720
89720
 
89721
89721
  // src/command.ts
89722
- import path10 from "node:path";
89722
+ import path11 from "node:path";
89723
89723
 
89724
89724
  // src/storage/sqlite.ts
89725
89725
  import Database from "better-sqlite3";
@@ -89781,6 +89781,18 @@ var createDatabase = (dbPath) => {
89781
89781
  FOREIGN KEY (executor_id) REFERENCES executors(id) ON DELETE CASCADE
89782
89782
  );
89783
89783
 
89784
+ CREATE TABLE IF NOT EXISTS remote_executor_processes (
89785
+ local_process_id TEXT PRIMARY KEY,
89786
+ remote_server_id TEXT NOT NULL,
89787
+ remote_url TEXT NOT NULL,
89788
+ remote_api_key TEXT NOT NULL,
89789
+ remote_process_id TEXT NOT NULL,
89790
+ executor_id TEXT NOT NULL,
89791
+ project_id TEXT,
89792
+ branch TEXT,
89793
+ started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
89794
+ );
89795
+
89784
89796
  CREATE TABLE IF NOT EXISTS agent_sessions (
89785
89797
  id TEXT PRIMARY KEY,
89786
89798
  project_id TEXT NOT NULL,
@@ -89804,6 +89816,19 @@ var createDatabase = (dbPath) => {
89804
89816
  FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
89805
89817
  );
89806
89818
 
89819
+ CREATE TABLE IF NOT EXISTS rules (
89820
+ id TEXT PRIMARY KEY,
89821
+ project_id TEXT NOT NULL,
89822
+ branch TEXT,
89823
+ name TEXT NOT NULL,
89824
+ content TEXT NOT NULL,
89825
+ enabled INTEGER NOT NULL DEFAULT 1,
89826
+ position INTEGER NOT NULL DEFAULT 0,
89827
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
89828
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
89829
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
89830
+ );
89831
+
89807
89832
  CREATE TABLE IF NOT EXISTS global_settings (
89808
89833
  key TEXT PRIMARY KEY,
89809
89834
  value TEXT NOT NULL
@@ -90585,6 +90610,30 @@ var createSqliteStorage = async (dbPath) => {
90585
90610
  ).run({ id, pid });
90586
90611
  }
90587
90612
  },
90613
+ remoteExecutorProcesses: {
90614
+ insert: (localProcessId, info) => {
90615
+ db.prepare(
90616
+ `INSERT OR REPLACE INTO remote_executor_processes (local_process_id, remote_server_id, remote_url, remote_api_key, remote_process_id, executor_id, project_id, branch) VALUES (@local_process_id, @remote_server_id, @remote_url, @remote_api_key, @remote_process_id, @executor_id, @project_id, @branch)`
90617
+ ).run({
90618
+ local_process_id: localProcessId,
90619
+ remote_server_id: info.remoteServerId,
90620
+ remote_url: info.remoteUrl,
90621
+ remote_api_key: info.remoteApiKey,
90622
+ remote_process_id: info.remoteProcessId,
90623
+ executor_id: info.executorId,
90624
+ project_id: info.projectId ?? null,
90625
+ branch: info.branch ?? null
90626
+ });
90627
+ },
90628
+ delete: (localProcessId) => {
90629
+ db.prepare(`DELETE FROM remote_executor_processes WHERE local_process_id = @id`).run({ id: localProcessId });
90630
+ },
90631
+ getAll: () => {
90632
+ return db.prepare(
90633
+ `SELECT * FROM remote_executor_processes`
90634
+ ).all({});
90635
+ }
90636
+ },
90588
90637
  agentSessions: {
90589
90638
  create: ({ id, project_id, branch, permission_mode, agent_type }) => {
90590
90639
  db.prepare(
@@ -90730,6 +90779,74 @@ var createSqliteStorage = async (dbPath) => {
90730
90779
  transaction();
90731
90780
  }
90732
90781
  },
90782
+ rules: {
90783
+ create: ({ id, project_id, branch, name: name25, content, enabled }) => {
90784
+ const maxPos = db.prepare(
90785
+ `SELECT MAX(position) as max_pos FROM rules WHERE project_id = @project_id AND (branch IS @branch OR (branch IS NULL AND @branch IS NULL))`
90786
+ ).get({ project_id, branch: branch ?? null });
90787
+ const position = (maxPos?.max_pos ?? -1) + 1;
90788
+ db.prepare(
90789
+ `INSERT INTO rules (id, project_id, branch, name, content, enabled, position)
90790
+ VALUES (@id, @project_id, @branch, @name, @content, @enabled, @position)`
90791
+ ).run({
90792
+ id,
90793
+ project_id,
90794
+ branch: branch ?? null,
90795
+ name: name25,
90796
+ content,
90797
+ enabled: enabled === false ? 0 : 1,
90798
+ position
90799
+ });
90800
+ return db.prepare(`SELECT * FROM rules WHERE id = @id`).get({ id });
90801
+ },
90802
+ getByWorkspace: (projectId, branch) => {
90803
+ return db.prepare(
90804
+ `SELECT * FROM rules WHERE project_id = @project_id AND (branch IS @branch OR (branch IS NULL AND @branch IS NULL)) ORDER BY position ASC`
90805
+ ).all({ project_id: projectId, branch: branch ?? null });
90806
+ },
90807
+ getById: (id) => {
90808
+ return db.prepare(`SELECT * FROM rules WHERE id = @id`).get({ id });
90809
+ },
90810
+ update: (id, opts) => {
90811
+ const updates = [];
90812
+ const params = { id };
90813
+ if (opts.name !== void 0) {
90814
+ updates.push("name = @name");
90815
+ params.name = opts.name;
90816
+ }
90817
+ if (opts.content !== void 0) {
90818
+ updates.push("content = @content");
90819
+ params.content = opts.content;
90820
+ }
90821
+ if (opts.enabled !== void 0) {
90822
+ updates.push("enabled = @enabled");
90823
+ params.enabled = opts.enabled ? 1 : 0;
90824
+ }
90825
+ if (opts.position !== void 0) {
90826
+ updates.push("position = @position");
90827
+ params.position = opts.position;
90828
+ }
90829
+ if (updates.length === 0) {
90830
+ return db.prepare(`SELECT * FROM rules WHERE id = @id`).get({ id });
90831
+ }
90832
+ updates.push("updated_at = datetime('now')");
90833
+ db.prepare(`UPDATE rules SET ${updates.join(", ")} WHERE id = @id`).run(params);
90834
+ return db.prepare(`SELECT * FROM rules WHERE id = @id`).get({ id });
90835
+ },
90836
+ delete: (id) => {
90837
+ db.prepare(`DELETE FROM rules WHERE id = @id`).run({ id });
90838
+ },
90839
+ reorder: (projectId, branch, orderedIds) => {
90840
+ const transaction = db.transaction(() => {
90841
+ for (let i = 0; i < orderedIds.length; i++) {
90842
+ db.prepare(
90843
+ `UPDATE rules SET position = @position, updated_at = datetime('now') WHERE id = @id AND project_id = @project_id`
90844
+ ).run({ id: orderedIds[i], project_id: projectId, position: i });
90845
+ }
90846
+ });
90847
+ transaction();
90848
+ }
90849
+ },
90733
90850
  close: () => {
90734
90851
  db.close();
90735
90852
  }
@@ -90740,7 +90857,7 @@ var createSqliteStorage = async (dbPath) => {
90740
90857
  var import_fastify = __toESM(require_fastify(), 1);
90741
90858
  var import_static = __toESM(require_static(), 1);
90742
90859
  var import_websocket2 = __toESM(require_websocket2(), 1);
90743
- import path7 from "path";
90860
+ import path8 from "path";
90744
90861
  import { fileURLToPath } from "url";
90745
90862
 
90746
90863
  // src/plugins/shared-services.ts
@@ -90796,10 +90913,10 @@ var ProcessManager = class {
90796
90913
  encoding: "utf-8",
90797
90914
  stdio: ["pipe", "pipe", "ignore"]
90798
90915
  }).trim();
90799
- const path11 = result || null;
90800
- this.binaryCache.set(name25, path11);
90916
+ const path12 = result || null;
90917
+ this.binaryCache.set(name25, path12);
90801
90918
  console.log(`[ProcessManager] ${name25} binary found: ${result}`);
90802
- return path11;
90919
+ return path12;
90803
90920
  } catch {
90804
90921
  this.binaryCache.set(name25, null);
90805
90922
  console.log(`[ProcessManager] ${name25} binary not found, will use npx`);
@@ -91021,6 +91138,20 @@ var ProcessManager = class {
91021
91138
  };
91022
91139
  this.processes.set(processId, runningProcess);
91023
91140
  console.log(`[ProcessManager] PTY process ${processId} added to map, PID: ${ptyProcess.pid}`);
91141
+ let exitPending = null;
91142
+ let drainHandle = null;
91143
+ const emitStopped = () => {
91144
+ if (!exitPending) return;
91145
+ const { code } = exitPending;
91146
+ exitPending = null;
91147
+ drainHandle = null;
91148
+ const tailOutput = this.snapshotTailOutput(runningProcess.logs);
91149
+ this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: code, target: "local", tailOutput });
91150
+ };
91151
+ const scheduleDrain = () => {
91152
+ if (drainHandle) clearImmediate(drainHandle);
91153
+ drainHandle = setImmediate(emitStopped);
91154
+ };
91024
91155
  ptyProcess.onData((data) => {
91025
91156
  const msg = { type: "pty", data };
91026
91157
  runningProcess.logs.push(msg);
@@ -91028,6 +91159,9 @@ var ProcessManager = class {
91028
91159
  runningProcess.logs = runningProcess.logs.slice(-TERMINAL_MAX_LOG_ENTRIES);
91029
91160
  }
91030
91161
  this.broadcast(processId, msg);
91162
+ if (exitPending) {
91163
+ scheduleDrain();
91164
+ }
91031
91165
  });
91032
91166
  ptyProcess.onExit(({ exitCode }) => {
91033
91167
  const code = exitCode ?? 0;
@@ -91039,7 +91173,8 @@ var ProcessManager = class {
91039
91173
  const msg = { type: "finished", exitCode: code };
91040
91174
  runningProcess.logs.push(msg);
91041
91175
  this.broadcast(processId, msg);
91042
- this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: code, target: "local" });
91176
+ exitPending = { code };
91177
+ scheduleDrain();
91043
91178
  setTimeout(() => {
91044
91179
  console.log(`[ProcessManager] Cleaning up process ${processId}`);
91045
91180
  this.processes.delete(processId);
@@ -91098,7 +91233,7 @@ var ProcessManager = class {
91098
91233
  const msg = { type: "finished", exitCode };
91099
91234
  runningProcess.logs.push(msg);
91100
91235
  this.broadcast(processId, msg);
91101
- this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode, target: "local" });
91236
+ this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode, target: "local", tailOutput: this.snapshotTailOutput(runningProcess.logs) });
91102
91237
  setTimeout(() => {
91103
91238
  console.log(`[ProcessManager] Cleaning up process ${processId}`);
91104
91239
  this.processes.delete(processId);
@@ -91114,7 +91249,7 @@ var ProcessManager = class {
91114
91249
  const finishMsg = { type: "finished", exitCode: 1 };
91115
91250
  runningProcess.logs.push(finishMsg);
91116
91251
  this.broadcast(processId, finishMsg);
91117
- this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: 1, target: "local" });
91252
+ this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: 1, target: "local", tailOutput: this.snapshotTailOutput(runningProcess.logs) });
91118
91253
  });
91119
91254
  }
91120
91255
  /**
@@ -91267,7 +91402,7 @@ ${GREEN}Done${info}${RESET}
91267
91402
  const msg = { type: "finished", exitCode };
91268
91403
  runningProcess.logs.push(msg);
91269
91404
  this.broadcast(processId, msg);
91270
- this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode, target: "local" });
91405
+ this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode, target: "local", tailOutput: this.snapshotTailOutput(runningProcess.logs) });
91271
91406
  setTimeout(() => {
91272
91407
  console.log(`[ProcessManager] Cleaning up process ${processId}`);
91273
91408
  this.processes.delete(processId);
@@ -91283,7 +91418,7 @@ ${GREEN}Done${info}${RESET}
91283
91418
  const finishMsg = { type: "finished", exitCode: 1 };
91284
91419
  runningProcess.logs.push(finishMsg);
91285
91420
  this.broadcast(processId, finishMsg);
91286
- this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: 1, target: "local" });
91421
+ this.eventBus?.emit({ type: "executor:stopped", projectId: runningProcess.projectId, executorId: runningProcess.executorId, processId, exitCode: 1, target: "local", tailOutput: this.snapshotTailOutput(runningProcess.logs) });
91287
91422
  });
91288
91423
  }
91289
91424
  /**
@@ -91451,6 +91586,19 @@ ${GREEN}Done${info}${RESET}
91451
91586
  const runningProcess = this.processes.get(processId);
91452
91587
  return runningProcess?.logs ?? [];
91453
91588
  }
91589
+ /**
91590
+ * Snapshot the tail output from a process's logs, stripping ANSI codes.
91591
+ * Used to include output in executor:stopped events.
91592
+ */
91593
+ snapshotTailOutput(logs) {
91594
+ const outputLogs = logs.filter(
91595
+ (l) => l.type === "pty" || l.type === "stdout" || l.type === "stderr"
91596
+ );
91597
+ const tail = outputLogs.slice(-100);
91598
+ let raw = tail.map((l) => l.data).join("");
91599
+ raw = raw.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
91600
+ return raw.length > 1e4 ? raw.slice(-1e4) : raw;
91601
+ }
91454
91602
  /**
91455
91603
  * Check if a process is still running
91456
91604
  */
@@ -92542,6 +92690,7 @@ var AgentSessionManager = class {
92542
92690
  }, true);
92543
92691
  }
92544
92692
  if (event.subtype === "success") {
92693
+ console.log(`[AgentSession] taskCompleted: sessionId=${sessionId}, eventBus=${!!this.eventBus}, projectId=${session.projectId}, branch=${session.branch}`);
92545
92694
  this.broadcastRaw(sessionId, {
92546
92695
  taskCompleted: {
92547
92696
  duration_ms: event.duration_ms,
@@ -92550,6 +92699,16 @@ var AgentSessionManager = class {
92550
92699
  output_tokens: event.output_tokens
92551
92700
  }
92552
92701
  });
92702
+ this.eventBus?.emit({
92703
+ type: "session:taskCompleted",
92704
+ projectId: session.projectId,
92705
+ branch: session.branch,
92706
+ sessionId,
92707
+ duration_ms: event.duration_ms,
92708
+ cost_usd: event.cost_usd,
92709
+ input_tokens: event.input_tokens,
92710
+ output_tokens: event.output_tokens
92711
+ });
92553
92712
  const tasks = this.storage.tasks.getByProjectId(session.projectId);
92554
92713
  const branchKey = session.branch ?? "";
92555
92714
  const assignedTask = tasks.find((t) => t.assigned_branch === branchKey);
@@ -94211,10 +94370,10 @@ function mergeDefs(...defs) {
94211
94370
  function cloneDef(schema) {
94212
94371
  return mergeDefs(schema._zod.def);
94213
94372
  }
94214
- function getElementAtPath(obj, path11) {
94215
- if (!path11)
94373
+ function getElementAtPath(obj, path12) {
94374
+ if (!path12)
94216
94375
  return obj;
94217
- return path11.reduce((acc, key) => acc?.[key], obj);
94376
+ return path12.reduce((acc, key) => acc?.[key], obj);
94218
94377
  }
94219
94378
  function promiseAllObject(promisesObj) {
94220
94379
  const keys = Object.keys(promisesObj);
@@ -94597,11 +94756,11 @@ function aborted(x, startIndex = 0) {
94597
94756
  }
94598
94757
  return false;
94599
94758
  }
94600
- function prefixIssues(path11, issues) {
94759
+ function prefixIssues(path12, issues) {
94601
94760
  return issues.map((iss) => {
94602
94761
  var _a25;
94603
94762
  (_a25 = iss).path ?? (_a25.path = []);
94604
- iss.path.unshift(path11);
94763
+ iss.path.unshift(path12);
94605
94764
  return iss;
94606
94765
  });
94607
94766
  }
@@ -94784,7 +94943,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
94784
94943
  }
94785
94944
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
94786
94945
  const result = { errors: [] };
94787
- const processError = (error49, path11 = []) => {
94946
+ const processError = (error49, path12 = []) => {
94788
94947
  var _a25, _b17;
94789
94948
  for (const issue2 of error49.issues) {
94790
94949
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -94794,7 +94953,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
94794
94953
  } else if (issue2.code === "invalid_element") {
94795
94954
  processError({ issues: issue2.issues }, issue2.path);
94796
94955
  } else {
94797
- const fullpath = [...path11, ...issue2.path];
94956
+ const fullpath = [...path12, ...issue2.path];
94798
94957
  if (fullpath.length === 0) {
94799
94958
  result.errors.push(mapper(issue2));
94800
94959
  continue;
@@ -94826,8 +94985,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
94826
94985
  }
94827
94986
  function toDotPath(_path) {
94828
94987
  const segs = [];
94829
- const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
94830
- for (const seg of path11) {
94988
+ const path12 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
94989
+ for (const seg of path12) {
94831
94990
  if (typeof seg === "number")
94832
94991
  segs.push(`[${seg}]`);
94833
94992
  else if (typeof seg === "symbol")
@@ -106804,13 +106963,13 @@ function resolveRef(ref, ctx) {
106804
106963
  if (!ref.startsWith("#")) {
106805
106964
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
106806
106965
  }
106807
- const path11 = ref.slice(1).split("/").filter(Boolean);
106808
- if (path11.length === 0) {
106966
+ const path12 = ref.slice(1).split("/").filter(Boolean);
106967
+ if (path12.length === 0) {
106809
106968
  return ctx.rootSchema;
106810
106969
  }
106811
106970
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
106812
- if (path11[0] === defsKey) {
106813
- const key = path11[1];
106971
+ if (path12[0] === defsKey) {
106972
+ const key = path12[1];
106814
106973
  if (!key || !ctx.defs[key]) {
106815
106974
  throw new Error(`Reference not found: ${ref}`);
106816
106975
  }
@@ -107571,8 +107730,8 @@ function getErrorMap2() {
107571
107730
 
107572
107731
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/parseUtil.js
107573
107732
  var makeIssue = (params) => {
107574
- const { data, path: path11, errorMaps, issueData } = params;
107575
- const fullPath = [...path11, ...issueData.path || []];
107733
+ const { data, path: path12, errorMaps, issueData } = params;
107734
+ const fullPath = [...path12, ...issueData.path || []];
107576
107735
  const fullIssue = {
107577
107736
  ...issueData,
107578
107737
  path: fullPath
@@ -107687,11 +107846,11 @@ var errorUtil;
107687
107846
 
107688
107847
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/types.js
107689
107848
  var ParseInputLazyPath = class {
107690
- constructor(parent, value, path11, key) {
107849
+ constructor(parent, value, path12, key) {
107691
107850
  this._cachedPath = [];
107692
107851
  this.parent = parent;
107693
107852
  this.data = value;
107694
- this._path = path11;
107853
+ this._path = path12;
107695
107854
  this._key = key;
107696
107855
  }
107697
107856
  get path() {
@@ -123595,7 +123754,7 @@ function createDeepSeek(options = {}) {
123595
123754
  const createLanguageModel = (modelId) => {
123596
123755
  return new DeepSeekChatLanguageModel(modelId, {
123597
123756
  provider: `deepseek.chat`,
123598
- url: ({ path: path11 }) => `${baseURL}${path11}`,
123757
+ url: ({ path: path12 }) => `${baseURL}${path12}`,
123599
123758
  headers: getHeaders,
123600
123759
  fetch: options.fetch
123601
123760
  });
@@ -125340,7 +125499,7 @@ function createOpenRouter(options = {}) {
125340
125499
  }, options.headers);
125341
125500
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
125342
125501
  provider: "openrouter.chat",
125343
- url: ({ path: path11 }) => `${baseURL}${path11}`,
125502
+ url: ({ path: path12 }) => `${baseURL}${path12}`,
125344
125503
  headers: getHeaders,
125345
125504
  compatibility,
125346
125505
  fetch: options.fetch,
@@ -125348,7 +125507,7 @@ function createOpenRouter(options = {}) {
125348
125507
  });
125349
125508
  const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
125350
125509
  provider: "openrouter.completion",
125351
- url: ({ path: path11 }) => `${baseURL}${path11}`,
125510
+ url: ({ path: path12 }) => `${baseURL}${path12}`,
125352
125511
  headers: getHeaders,
125353
125512
  compatibility,
125354
125513
  fetch: options.fetch,
@@ -125621,6 +125780,8 @@ var ChatSessionManager = class {
125621
125780
  sessionIndex = /* @__PURE__ */ new Map();
125622
125781
  /** terminalId → watcher state for active terminal output watchers */
125623
125782
  terminalWatchers = /* @__PURE__ */ new Map();
125783
+ /** processId → cleanup function for remote executor monitors */
125784
+ remoteExecutorMonitors = /* @__PURE__ */ new Map();
125624
125785
  /** sessionId → queued messages waiting to be sent after current stream finishes */
125625
125786
  messageQueue = /* @__PURE__ */ new Map();
125626
125787
  storage;
@@ -125663,29 +125824,87 @@ var ChatSessionManager = class {
125663
125824
  this.eventBus.subscribe((event) => {
125664
125825
  if (event.type === "executor:stopped") {
125665
125826
  this.handleExecutorFinished(event);
125827
+ } else if (event.type === "session:taskCompleted") {
125828
+ console.log(`[ChatSession] EventBus received session:taskCompleted for project=${event.projectId} branch=${event.branch}`);
125829
+ this.handleSessionTaskCompleted(event);
125666
125830
  }
125667
125831
  });
125668
125832
  }
125833
+ handleSessionTaskCompleted(event) {
125834
+ try {
125835
+ const key = `${event.projectId}:${event.branch ?? ""}`;
125836
+ console.log(`[ChatSession] handleSessionTaskCompleted: key=${key}, sessionIndex keys=[${[...this.sessionIndex.keys()].join(", ")}]`);
125837
+ const sessionId = this.sessionIndex.get(key);
125838
+ if (!sessionId) {
125839
+ console.log(`[ChatSession] handleSessionTaskCompleted: no chat session found for key=${key}`);
125840
+ return;
125841
+ }
125842
+ const session = this.sessions.get(sessionId);
125843
+ if (!session) {
125844
+ console.log(`[ChatSession] handleSessionTaskCompleted: session object not found for id=${sessionId}`);
125845
+ return;
125846
+ }
125847
+ if (!session.eventListeningEnabled) {
125848
+ console.log(`[ChatSession] handleSessionTaskCompleted: eventListening disabled for session ${sessionId}`);
125849
+ return;
125850
+ }
125851
+ const stats = [];
125852
+ if (event.duration_ms !== void 0) {
125853
+ const seconds = (event.duration_ms / 1e3).toFixed(1);
125854
+ stats.push(`Duration: ${seconds}s`);
125855
+ }
125856
+ if (event.cost_usd !== void 0) {
125857
+ stats.push(`Cost: $${event.cost_usd.toFixed(4)}`);
125858
+ }
125859
+ if (event.input_tokens !== void 0) {
125860
+ stats.push(`Input tokens: ${event.input_tokens.toLocaleString()}`);
125861
+ }
125862
+ if (event.output_tokens !== void 0) {
125863
+ stats.push(`Output tokens: ${event.output_tokens.toLocaleString()}`);
125864
+ }
125865
+ const message = [
125866
+ `[Agent Event: Task Completed]`,
125867
+ `Branch: ${event.branch ?? "main"}`,
125868
+ stats.length > 0 ? stats.join(" | ") : "",
125869
+ ``,
125870
+ `Summarize in 1-2 sentences what the coding agent accomplished.`
125871
+ ].filter(Boolean).join("\n");
125872
+ this.enqueueOrSend(sessionId, message);
125873
+ } catch (error48) {
125874
+ console.error(`[ChatSession] handleSessionTaskCompleted error:`, error48);
125875
+ }
125876
+ }
125669
125877
  handleExecutorFinished(event) {
125670
125878
  try {
125879
+ console.log(`[ChatSession] handleExecutorFinished: executorId=${event.executorId}, projectId=${event.projectId}, exitCode=${event.exitCode}`);
125671
125880
  const executor = this.storage.executors.getById(event.executorId);
125672
- if (!executor) return;
125881
+ if (!executor) {
125882
+ console.log(`[ChatSession] handleExecutorFinished: executor not found`);
125883
+ return;
125884
+ }
125673
125885
  const group2 = this.storage.executorGroups.getById(executor.group_id);
125674
- if (!group2) return;
125886
+ if (!group2) {
125887
+ console.log(`[ChatSession] handleExecutorFinished: group not found for executor.group_id=${executor.group_id}`);
125888
+ return;
125889
+ }
125675
125890
  const branch = group2.branch || null;
125676
125891
  const key = `${event.projectId}:${branch ?? ""}`;
125677
125892
  const sessionId = this.sessionIndex.get(key);
125678
- if (!sessionId) return;
125893
+ if (!sessionId) {
125894
+ console.log(`[ChatSession] handleExecutorFinished: no session for key="${key}", sessionIndex keys=[${[...this.sessionIndex.keys()].join(", ")}]`);
125895
+ return;
125896
+ }
125679
125897
  const session = this.sessions.get(sessionId);
125680
- if (!session || !session.eventListeningEnabled) return;
125681
- const logs = this.processManager.getLogs(event.processId);
125682
- const outputLogs = logs.filter(
125683
- (l) => l.type === "pty" || l.type === "stdout" || l.type === "stderr"
125684
- );
125685
- const tail = outputLogs.slice(-100);
125686
- let raw = tail.map((l) => l.data).join("");
125687
- raw = raw.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
125688
- const tailOutput = raw.length > 1e4 ? raw.slice(-1e4) : raw;
125898
+ if (!session) {
125899
+ console.log(`[ChatSession] handleExecutorFinished: session object not found for id=${sessionId}`);
125900
+ return;
125901
+ }
125902
+ if (!session.eventListeningEnabled) {
125903
+ console.log(`[ChatSession] handleExecutorFinished: eventListening disabled for session ${sessionId}`);
125904
+ return;
125905
+ }
125906
+ console.log(`[ChatSession] handleExecutorFinished: processing event, session=${sessionId}, subscribers=${session.subscribers.size}`);
125907
+ const tailOutput = event.tailOutput ?? "";
125689
125908
  const exitStatus = event.exitCode === 0 ? "success" : "failed";
125690
125909
  const message = [
125691
125910
  `[Executor Event: Process Finished]`,
@@ -125698,7 +125917,7 @@ var ChatSessionManager = class {
125698
125917
  tailOutput || "(no output captured)",
125699
125918
  `---`,
125700
125919
  ``,
125701
- `Summarize in 1-2 sentences.`
125920
+ `Check your Workspace Rules for any rules that apply to this event, then respond.`
125702
125921
  ].join("\n");
125703
125922
  this.enqueueOrSend(sessionId, message);
125704
125923
  } catch (error48) {
@@ -126034,6 +126253,85 @@ var ChatSessionManager = class {
126034
126253
  });
126035
126254
  console.log(`[ChatSession] Started remote terminal watcher for terminal=${terminalId} session=${sessionId}`);
126036
126255
  }
126256
+ /**
126257
+ * Open a lightweight server-side WebSocket to a remote executor's log stream
126258
+ * to detect when it finishes. Without this, `executor:stopped` is only emitted
126259
+ * when a frontend client connects the log proxy — which may not happen until
126260
+ * the user switches browser tabs.
126261
+ */
126262
+ monitorRemoteExecutor(localProcessId, remoteInfo) {
126263
+ if (this.remoteExecutorMonitors.has(localProcessId)) return;
126264
+ let remoteWs;
126265
+ const useVirtual = this.reverseConnectManager?.isConnected(remoteInfo.remoteServerId);
126266
+ if (useVirtual && this.reverseConnectManager) {
126267
+ const channelId = randomUUID3();
126268
+ const wsPath = `/api/executor-processes/${remoteInfo.remoteProcessId}/logs`;
126269
+ const wsQuery = `apiKey=${encodeURIComponent(remoteInfo.remoteApiKey)}`;
126270
+ const adapter = new VirtualWsAdapter(
126271
+ (data) => this.reverseConnectManager.sendChannelData(remoteInfo.remoteServerId, channelId, data),
126272
+ () => this.reverseConnectManager.closeChannel(remoteInfo.remoteServerId, channelId)
126273
+ );
126274
+ this.reverseConnectManager.setChannelAdapter(remoteInfo.remoteServerId, channelId, adapter);
126275
+ this.reverseConnectManager.openVirtualChannel(remoteInfo.remoteServerId, channelId, wsPath, wsQuery);
126276
+ remoteWs = adapter;
126277
+ setTimeout(() => adapter.emit("open"), 0);
126278
+ } else {
126279
+ if (!remoteInfo.remoteUrl) {
126280
+ console.log(`[ChatSession] monitorRemoteExecutor: no direct URL for ${localProcessId}, skipping`);
126281
+ return;
126282
+ }
126283
+ const cleanRemoteUrl = remoteInfo.remoteUrl.replace(/\/+$/, "");
126284
+ const wsProtocol = cleanRemoteUrl.startsWith("https") ? "wss" : "ws";
126285
+ const wsUrl = cleanRemoteUrl.replace(/^https?/, wsProtocol);
126286
+ const remoteWsUrl = `${wsUrl}/api/executor-processes/${remoteInfo.remoteProcessId}/logs?apiKey=${encodeURIComponent(remoteInfo.remoteApiKey)}`;
126287
+ remoteWs = new wrapper_default(remoteWsUrl);
126288
+ }
126289
+ const cleanup = () => {
126290
+ this.remoteExecutorMonitors.delete(localProcessId);
126291
+ try {
126292
+ remoteWs.close();
126293
+ } catch {
126294
+ }
126295
+ };
126296
+ const outputChunks = [];
126297
+ remoteWs.on("message", (data) => {
126298
+ try {
126299
+ const parsed = JSON.parse(data.toString());
126300
+ if ((parsed.type === "pty" || parsed.type === "stdout" || parsed.type === "stderr") && parsed.data) {
126301
+ outputChunks.push(parsed.data);
126302
+ }
126303
+ if (parsed.type === "finished") {
126304
+ const info = this.remoteExecutorMap.get(localProcessId);
126305
+ if (info && !info.stoppedEmitted) {
126306
+ info.stoppedEmitted = true;
126307
+ let raw = outputChunks.join("");
126308
+ raw = raw.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
126309
+ const tailOutput = raw.length > 1e4 ? raw.slice(-1e4) : raw;
126310
+ this.eventBus?.emit({
126311
+ type: "executor:stopped",
126312
+ projectId: info.projectId ?? "",
126313
+ executorId: info.executorId,
126314
+ processId: localProcessId,
126315
+ exitCode: parsed.exitCode ?? 0,
126316
+ target: info.remoteServerId,
126317
+ tailOutput
126318
+ });
126319
+ }
126320
+ cleanup();
126321
+ }
126322
+ } catch {
126323
+ }
126324
+ });
126325
+ remoteWs.on("close", () => {
126326
+ cleanup();
126327
+ });
126328
+ remoteWs.on("error", (error48) => {
126329
+ console.error(`[ChatSession] monitorRemoteExecutor error for ${localProcessId}:`, error48);
126330
+ cleanup();
126331
+ });
126332
+ this.remoteExecutorMonitors.set(localProcessId, cleanup);
126333
+ console.log(`[ChatSession] Started remote executor monitor for ${localProcessId}`);
126334
+ }
126037
126335
  // ---- Session lifecycle ----
126038
126336
  getOrCreateSession(projectId, branch) {
126039
126337
  const key = `${projectId}:${branch ?? ""}`;
@@ -126090,15 +126388,40 @@ var ChatSessionManager = class {
126090
126388
  }
126091
126389
  // ---- Tools & system prompt ----
126092
126390
  getSystemPrompt(projectId, branch) {
126093
- return [
126391
+ const lines = [
126094
126392
  "You are a helpful assistant for a software development workspace.",
126095
126393
  "You can check the status of running executors (dev servers, build processes, etc.) using the getExecutorStatus tool.",
126096
126394
  "You can start executors using the runExecutor tool and stop them using the stopExecutor tool.",
126097
126395
  "When the user asks about running processes, errors, build status, or dev server status, use the getExecutorStatus tool.",
126098
126396
  "When the user asks to start, run, or launch a process, use runExecutor. When they ask to stop or kill a process, use stopExecutor.",
126397
+ ...(() => {
126398
+ const project = this.storage.projects.getById(projectId);
126399
+ const remotes = this.storage.projectRemotes.getByProject(projectId);
126400
+ if (remotes.length === 0) return [];
126401
+ const remoteNames = remotes.map((r) => {
126402
+ const server = this.storage.remoteServers.getById(r.remote_server_id);
126403
+ return server?.name ?? r.remote_server_id;
126404
+ });
126405
+ const lines2 = [
126406
+ `This project has ${remotes.length} remote server(s): ${remoteNames.join(", ")}.`
126407
+ ];
126408
+ if (!project?.path) {
126409
+ lines2.push("This project has no local path \u2014 executors must run on a remote server.");
126410
+ }
126411
+ if (remotes.length === 1) {
126412
+ lines2.push(
126413
+ `When the user asks to run or stop an executor without specifying a remote, use "${remoteNames[0]}" automatically.`
126414
+ );
126415
+ } else {
126416
+ lines2.push(
126417
+ "When the user asks to run or stop an executor without specifying which remote, ask them to choose a remote before calling the tool. Available remotes: " + remoteNames.join(", ") + "."
126418
+ );
126419
+ }
126420
+ return lines2;
126421
+ })(),
126099
126422
  "You can view the coding agent's conversation history using the getAgentConversation tool.",
126100
126423
  "When the user asks about what the agent is doing, has done, or references agent activities, use this tool.",
126101
- "When you receive an [Executor Event] message, respond in 1-2 sentences only. State what finished, whether it succeeded or failed, and the key detail (e.g. error message) if it failed. Do not repeat the output logs.",
126424
+ "When you receive an [Executor Event] message, first check if any Workspace Rules apply to this event. If a rule matches, follow it (e.g. run another executor, send a command, etc.) AND briefly state what finished. IMPORTANT: If a rule says to run an executor, you MUST call the runExecutor tool every time \u2014 even if that same executor was already run earlier in this session. Never skip the tool call or claim you started an executor without actually calling runExecutor. Each rule match requires a new tool invocation. If no rule applies, respond in 1-2 sentences only stating what finished, whether it succeeded or failed, and the key detail (e.g. error message) if it failed. Do not repeat the output logs.",
126102
126425
  "You can list active terminal sessions using the listTerminals tool.",
126103
126426
  "You can send commands to a terminal using the runInTerminal tool. The command runs visibly in the user's terminal and returns immediately.",
126104
126427
  "After sending a command, terminal output will arrive as a [Terminal Event] message once the command finishes. Wait for it before commenting on results.",
@@ -126109,7 +126432,18 @@ var ChatSessionManager = class {
126109
126432
  "You can inspect pages: screenshot (returns base64 image), getPageContent (returns text/HTML), waitForElement.",
126110
126433
  "When you receive a [Browser Event] message, respond in 1-2 sentences. State what error occurred and suggest a fix if obvious.",
126111
126434
  `Current workspace: project=${projectId}, branch=${branch ?? "default"}.`
126112
- ].join("\n");
126435
+ ];
126436
+ const rules = this.storage.rules.getByWorkspace(projectId, branch);
126437
+ const enabledRules = rules.filter((r) => r.enabled);
126438
+ if (enabledRules.length > 0) {
126439
+ lines.push("");
126440
+ lines.push("## Workspace Rules");
126441
+ lines.push("The user has configured the following rules for this workspace. Follow them:");
126442
+ enabledRules.forEach((rule, i) => {
126443
+ lines.push(`${i + 1}. [${rule.name}]: ${rule.content}`);
126444
+ });
126445
+ }
126446
+ return lines.join("\n");
126113
126447
  }
126114
126448
  createTools(projectId, branch, sessionId) {
126115
126449
  const storage = this.storage;
@@ -126242,11 +126576,12 @@ var ChatSessionManager = class {
126242
126576
  }
126243
126577
  }),
126244
126578
  runExecutor: tool({
126245
- description: "Start an executor (dev server, build process, etc.) by name. Use this when the user asks to start, run, or launch a process.",
126579
+ description: "Start an executor (dev server, build process, etc.) by name. Use this when the user asks to start, run, or launch a process. Optionally specify a remote server ID to run the executor on a remote machine.",
126246
126580
  inputSchema: external_exports.object({
126247
- executorName: external_exports.string().describe("Name of the executor to start (case-insensitive match)")
126581
+ executorName: external_exports.string().describe("Name of the executor to start (case-insensitive match)"),
126582
+ remote: external_exports.string().optional().describe("Remote server name or ID to run the executor on. If omitted, uses project executor_mode or runs locally.")
126248
126583
  }),
126249
- execute: async ({ executorName }) => {
126584
+ execute: async ({ executorName, remote }) => {
126250
126585
  const group2 = branch ? storage.executorGroups.getByBranch(projectId, branch) : void 0;
126251
126586
  if (!group2) {
126252
126587
  return { success: false, message: "No executor group found for this workspace." };
@@ -126262,6 +126597,99 @@ var ChatSessionManager = class {
126262
126597
  message: `Executor "${executorName}" not found. Available: ${available || "none"}`
126263
126598
  };
126264
126599
  }
126600
+ let remoteServerId = remote;
126601
+ if (remote) {
126602
+ const byId = storage.remoteServers.getById(remote);
126603
+ if (!byId) {
126604
+ const allServers = storage.remoteServers.getAll();
126605
+ const byName = allServers.find((s2) => s2.name.toLowerCase() === remote.toLowerCase());
126606
+ if (byName) {
126607
+ remoteServerId = byName.id;
126608
+ }
126609
+ }
126610
+ }
126611
+ const project = storage.projects.getById(projectId);
126612
+ let executorMode = remoteServerId || project?.executor_mode;
126613
+ let resolvedRemote = executorMode && executorMode !== "local" ? executorMode : void 0;
126614
+ if (!resolvedRemote && !project?.path) {
126615
+ const remotes = storage.projectRemotes.getByProject(projectId);
126616
+ if (remotes.length > 0) {
126617
+ resolvedRemote = remotes[0].remote_server_id;
126618
+ }
126619
+ }
126620
+ if (resolvedRemote) {
126621
+ const remoteConfig = storage.projectRemotes.getByProjectAndServer(projectId, resolvedRemote);
126622
+ if (!remoteConfig) {
126623
+ return { success: false, message: `Remote server "${resolvedRemote}" not configured for this project.` };
126624
+ }
126625
+ const result = await proxyToRemoteAuto(
126626
+ resolvedRemote,
126627
+ remoteConfig.server_url ?? "",
126628
+ remoteConfig.server_api_key || "",
126629
+ "POST",
126630
+ `/api/path/execute`,
126631
+ {
126632
+ path: remoteConfig.remote_path,
126633
+ command: executor.command,
126634
+ executor_type: executor.executor_type,
126635
+ prompt_provider: executor.prompt_provider,
126636
+ branch: branch ?? void 0,
126637
+ cwd: executor.cwd || void 0,
126638
+ pty: executor.pty
126639
+ },
126640
+ { reverseConnectManager: reverseConnectManager ?? void 0 }
126641
+ );
126642
+ if (!result.ok) {
126643
+ return { success: false, message: `Remote start failed: ${JSON.stringify(result.data)}` };
126644
+ }
126645
+ const remoteData = result.data;
126646
+ const localProcessId = `remote-${executor.id}-${remoteData.processId}`;
126647
+ remoteExecutorMap.set(localProcessId, {
126648
+ remoteServerId: resolvedRemote,
126649
+ remoteUrl: remoteConfig.server_url ?? "",
126650
+ remoteApiKey: remoteConfig.server_api_key || "",
126651
+ remoteProcessId: remoteData.processId,
126652
+ executorId: executor.id,
126653
+ projectId,
126654
+ branch
126655
+ });
126656
+ this.storage.remoteExecutorProcesses.insert(localProcessId, {
126657
+ remoteServerId: resolvedRemote,
126658
+ remoteUrl: remoteConfig.server_url ?? "",
126659
+ remoteApiKey: remoteConfig.server_api_key || "",
126660
+ remoteProcessId: remoteData.processId,
126661
+ executorId: executor.id,
126662
+ projectId,
126663
+ branch
126664
+ });
126665
+ this.eventBus?.emit({
126666
+ type: "executor:started",
126667
+ projectId,
126668
+ executorId: executor.id,
126669
+ processId: localProcessId,
126670
+ target: resolvedRemote
126671
+ });
126672
+ if (sessionId) {
126673
+ this.setEventListening(sessionId, true);
126674
+ }
126675
+ this.monitorRemoteExecutor(localProcessId, {
126676
+ remoteServerId: resolvedRemote,
126677
+ remoteUrl: remoteConfig.server_url ?? "",
126678
+ remoteApiKey: remoteConfig.server_api_key || "",
126679
+ remoteProcessId: remoteData.processId,
126680
+ executorId: executor.id,
126681
+ projectId,
126682
+ branch
126683
+ });
126684
+ return {
126685
+ success: true,
126686
+ processId: localProcessId,
126687
+ executorName: executor.name,
126688
+ command: executor.command,
126689
+ target: resolvedRemote,
126690
+ message: `Started "${executor.name}" on remote server "${resolvedRemote}" (${executor.command}).`
126691
+ };
126692
+ }
126265
126693
  const processes = processManager.getProcessesByExecutorId(executor.id);
126266
126694
  const running = processes.find((p) => p.isRunning);
126267
126695
  if (running) {
@@ -126272,13 +126700,15 @@ var ChatSessionManager = class {
126272
126700
  message: `Executor "${executor.name}" is already running (processId=${running.processId}).`
126273
126701
  };
126274
126702
  }
126275
- const project = storage.projects.getById(projectId);
126276
126703
  if (!project?.path) {
126277
- return { success: false, message: "No project path configured." };
126704
+ return { success: false, message: "No project path configured and no remote servers available." };
126278
126705
  }
126279
126706
  const basePath33 = resolveWorktreePath(project.path, branch);
126280
126707
  try {
126281
126708
  const processId = processManager.start(executor, basePath33);
126709
+ if (sessionId) {
126710
+ this.setEventListening(sessionId, true);
126711
+ }
126282
126712
  return {
126283
126713
  success: true,
126284
126714
  processId,
@@ -126293,11 +126723,12 @@ var ChatSessionManager = class {
126293
126723
  }
126294
126724
  }),
126295
126725
  stopExecutor: tool({
126296
- description: "Stop a running executor (dev server, build process, etc.) by name. Use this when the user asks to stop, kill, or terminate a process.",
126726
+ description: "Stop a running executor (dev server, build process, etc.) by name. Use this when the user asks to stop, kill, or terminate a process. Optionally specify a remote server ID to stop a remote executor.",
126297
126727
  inputSchema: external_exports.object({
126298
- executorName: external_exports.string().describe("Name of the executor to stop (case-insensitive match)")
126728
+ executorName: external_exports.string().describe("Name of the executor to stop (case-insensitive match)"),
126729
+ remote: external_exports.string().optional().describe("Remote server name or ID where the executor is running. If omitted, auto-detects.")
126299
126730
  }),
126300
- execute: async ({ executorName }) => {
126731
+ execute: async ({ executorName, remote }) => {
126301
126732
  const group2 = branch ? storage.executorGroups.getByBranch(projectId, branch) : void 0;
126302
126733
  if (!group2) {
126303
126734
  return { success: false, message: "No executor group found for this workspace." };
@@ -126313,6 +126744,73 @@ var ChatSessionManager = class {
126313
126744
  message: `Executor "${executorName}" not found. Available: ${available || "none"}`
126314
126745
  };
126315
126746
  }
126747
+ let remoteServerId = remote;
126748
+ if (remote) {
126749
+ const byId = storage.remoteServers.getById(remote);
126750
+ if (!byId) {
126751
+ const allServers = storage.remoteServers.getAll();
126752
+ const byName = allServers.find((s2) => s2.name.toLowerCase() === remote.toLowerCase());
126753
+ if (byName) {
126754
+ remoteServerId = byName.id;
126755
+ }
126756
+ }
126757
+ }
126758
+ let resolvedRemote = remoteServerId;
126759
+ if (!resolvedRemote) {
126760
+ const runningRemotes = [];
126761
+ for (const [, info] of remoteExecutorMap.entries()) {
126762
+ if (info.executorId === executor.id) {
126763
+ runningRemotes.push(info.remoteServerId);
126764
+ }
126765
+ }
126766
+ if (runningRemotes.length === 1) {
126767
+ resolvedRemote = runningRemotes[0];
126768
+ } else if (runningRemotes.length > 1) {
126769
+ const remoteNames = runningRemotes.map((id) => {
126770
+ const server = storage.remoteServers.getById(id);
126771
+ return server?.name ?? id;
126772
+ });
126773
+ return {
126774
+ success: false,
126775
+ needsClarification: true,
126776
+ availableRemotes: remoteNames,
126777
+ message: `Executor "${executor.name}" is running on multiple remotes. Please ask the user which one to stop. Running on: ${remoteNames.join(", ")}`
126778
+ };
126779
+ }
126780
+ }
126781
+ if (resolvedRemote) {
126782
+ let remoteEntry;
126783
+ for (const [key, info] of remoteExecutorMap.entries()) {
126784
+ if (info.executorId === executor.id && info.remoteServerId === resolvedRemote) {
126785
+ remoteEntry = { key, info };
126786
+ break;
126787
+ }
126788
+ }
126789
+ if (!remoteEntry) {
126790
+ } else {
126791
+ const result = await proxyToRemoteAuto(
126792
+ remoteEntry.info.remoteServerId,
126793
+ remoteEntry.info.remoteUrl,
126794
+ remoteEntry.info.remoteApiKey,
126795
+ "POST",
126796
+ `/api/executor-processes/${remoteEntry.info.remoteProcessId}/stop`,
126797
+ void 0,
126798
+ { reverseConnectManager: reverseConnectManager ?? void 0 }
126799
+ );
126800
+ if (!result.ok) {
126801
+ return { success: false, message: `Remote stop failed: ${JSON.stringify(result.data)}` };
126802
+ }
126803
+ remoteExecutorMap.delete(remoteEntry.key);
126804
+ this.storage.remoteExecutorProcesses.delete(remoteEntry.key);
126805
+ return {
126806
+ success: true,
126807
+ executorName: executor.name,
126808
+ processId: remoteEntry.key,
126809
+ target: resolvedRemote,
126810
+ message: `Stopped "${executor.name}" on remote server "${resolvedRemote}".`
126811
+ };
126812
+ }
126813
+ }
126316
126814
  const processes = processManager.getProcessesByExecutorId(executor.id);
126317
126815
  const running = processes.find((p) => p.isRunning);
126318
126816
  if (!running) {
@@ -126640,9 +127138,13 @@ var ChatSessionManager = class {
126640
127138
  console.log(`[ChatSession] sendMessage: session ${sessionId} not found`);
126641
127139
  return false;
126642
127140
  }
126643
- console.log(`[ChatSession] sendMessage called: session=${sessionId}, contentLen=${content.length}, isTerminalEvent=${content.includes("[Terminal Event]")}`);
127141
+ const isExecutorEvent = content.includes("[Executor Event");
127142
+ console.log(`[ChatSession] sendMessage called: session=${sessionId}, contentLen=${content.length}, isExecutorEvent=${isExecutorEvent}, isTerminalEvent=${content.includes("[Terminal Event]")}, subscribers=${session.subscribers.size}`);
126644
127143
  const userMsg = { type: "user", content, timestamp: Date.now() };
126645
127144
  this.pushEntry(session, userMsg);
127145
+ if (isExecutorEvent) {
127146
+ console.log(`[ChatSession] Executor event user message pushed at index ${session.store.nextIndex - 1}, broadcasting to ${session.subscribers.size} subscribers`);
127147
+ }
126646
127148
  session.status = "running";
126647
127149
  this.broadcastPatch(session, ConversationPatch.updateStatus("running"));
126648
127150
  const messages = session.store.entries.filter(
@@ -126775,6 +127277,8 @@ var ChatSessionManager = class {
126775
127277
  session.abortController = null;
126776
127278
  session.status = "stopped";
126777
127279
  this.broadcastPatch(session, ConversationPatch.updateStatus("stopped"));
127280
+ const queueLen = this.messageQueue.get(sessionId)?.length ?? 0;
127281
+ console.log(`[ChatSession] sendMessage finished for ${sessionId}, draining queue (${queueLen} items), subscribers=${session.subscribers.size}`);
126778
127282
  this.drainQueue(sessionId);
126779
127283
  }
126780
127284
  return true;
@@ -126786,6 +127290,28 @@ var ChatSessionManager = class {
126786
127290
  session.abortController.abort();
126787
127291
  return true;
126788
127292
  }
127293
+ /**
127294
+ * Reset a chat session — abort any in-flight generation, clear messages,
127295
+ * and broadcast a clearAll patch so connected frontends reset.
127296
+ */
127297
+ resetSession(sessionId) {
127298
+ const session = this.sessions.get(sessionId);
127299
+ if (!session) return false;
127300
+ if (session.abortController) {
127301
+ session.abortController.abort();
127302
+ session.abortController = null;
127303
+ }
127304
+ session.store.patches = [];
127305
+ session.store.entries = [];
127306
+ session.store.nextIndex = 0;
127307
+ session.status = "stopped";
127308
+ const clearPatch = ConversationPatch.clearAll();
127309
+ this.broadcastPatch(session, clearPatch);
127310
+ const statusPatch = ConversationPatch.updateStatus("stopped");
127311
+ this.broadcastPatch(session, statusPatch);
127312
+ console.log(`[ChatSession] Reset session ${sessionId}`);
127313
+ return true;
127314
+ }
126789
127315
  // ---- Internal helpers ----
126790
127316
  pushEntry(session, entry) {
126791
127317
  const index = session.store.nextIndex;
@@ -126796,11 +127322,22 @@ var ChatSessionManager = class {
126796
127322
  this.broadcastPatch(session, patch);
126797
127323
  }
126798
127324
  broadcastPatch(session, patch) {
127325
+ if (session.subscribers.size === 0) {
127326
+ const hasEntry = patch.some((p) => p.value?.type === "ENTRY");
127327
+ if (hasEntry) {
127328
+ console.log(`[ChatSession] broadcastPatch: ENTRY patch but 0 subscribers for session ${session.id}`);
127329
+ }
127330
+ }
126799
127331
  const raw = JSON.stringify({ JsonPatch: patch });
126800
127332
  for (const ws of session.subscribers) {
126801
127333
  try {
127334
+ if (ws.readyState !== 1) {
127335
+ console.log(`[ChatSession] broadcastPatch: subscriber ws.readyState=${ws.readyState} (not OPEN), skipping`);
127336
+ continue;
127337
+ }
126802
127338
  ws.send(raw);
126803
- } catch {
127339
+ } catch (err) {
127340
+ console.log(`[ChatSession] broadcastPatch: send failed:`, err);
126804
127341
  }
126805
127342
  }
126806
127343
  }
@@ -127044,10 +127581,25 @@ var DEFAULT_HTTP_TIMEOUT_MS = 3e4;
127044
127581
  var ReverseConnectManager = class {
127045
127582
  connections = /* @__PURE__ */ new Map();
127046
127583
  statusChangeHandlers = [];
127584
+ // Aliases map old/stale server IDs to currently-connected server IDs.
127585
+ // This handles cases where the same physical machine reconnects under
127586
+ // a different remote_servers.id (e.g., after server entry recreation).
127587
+ aliases = /* @__PURE__ */ new Map();
127588
+ /** Resolve a server ID through aliases. */
127589
+ resolveId(serverId) {
127590
+ return this.aliases.get(serverId) ?? serverId;
127591
+ }
127592
+ /** Register an alias so that requests for oldId route to connectedId. */
127593
+ addAlias(oldId, connectedId) {
127594
+ if (oldId !== connectedId) {
127595
+ this.aliases.set(oldId, connectedId);
127596
+ }
127597
+ }
127047
127598
  setStatusChangeHandler(handler) {
127048
127599
  this.statusChangeHandlers.push(handler);
127049
127600
  }
127050
127601
  registerConnection(remoteServerId, ws) {
127602
+ this.aliases.delete(remoteServerId);
127051
127603
  const existing = this.connections.get(remoteServerId);
127052
127604
  if (existing) {
127053
127605
  console.log(`[ReverseConnect] Replacing existing connection for ${remoteServerId}`);
@@ -127093,11 +127645,11 @@ var ReverseConnectManager = class {
127093
127645
  this.connections.delete(remoteServerId);
127094
127646
  }
127095
127647
  isConnected(remoteServerId) {
127096
- const conn = this.connections.get(remoteServerId);
127648
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127097
127649
  return conn !== void 0 && conn.ws.readyState === 1;
127098
127650
  }
127099
- async sendHttpRequest(remoteServerId, method, path11, body, timeoutMs = DEFAULT_HTTP_TIMEOUT_MS) {
127100
- const conn = this.connections.get(remoteServerId);
127651
+ async sendHttpRequest(remoteServerId, method, path12, body, timeoutMs = DEFAULT_HTTP_TIMEOUT_MS) {
127652
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127101
127653
  if (!conn || conn.ws.readyState !== 1) {
127102
127654
  return {
127103
127655
  ok: false,
@@ -127111,7 +127663,7 @@ var ReverseConnectManager = class {
127111
127663
  type: "http_request",
127112
127664
  requestId,
127113
127665
  method,
127114
- path: path11,
127666
+ path: path12,
127115
127667
  headers: body !== void 0 ? { "content-type": "application/json" } : {},
127116
127668
  body: body !== void 0 ? JSON.stringify(body) : void 0
127117
127669
  };
@@ -127133,8 +127685,8 @@ var ReverseConnectManager = class {
127133
127685
  * Send an HTTP request and return the raw response (body as string, headers intact).
127134
127686
  * Used by the browser proxy to forward HTML/CSS/JS without JSON parsing.
127135
127687
  */
127136
- async sendRawHttpRequest(remoteServerId, method, path11, headers, body, timeoutMs = DEFAULT_HTTP_TIMEOUT_MS, port) {
127137
- const conn = this.connections.get(remoteServerId);
127688
+ async sendRawHttpRequest(remoteServerId, method, path12, headers, body, timeoutMs = DEFAULT_HTTP_TIMEOUT_MS, port) {
127689
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127138
127690
  if (!conn || conn.ws.readyState !== 1) {
127139
127691
  return { ok: false, status: 0, headers: {}, body: "" };
127140
127692
  }
@@ -127143,7 +127695,7 @@ var ReverseConnectManager = class {
127143
127695
  type: "http_request",
127144
127696
  requestId,
127145
127697
  method,
127146
- path: path11,
127698
+ path: path12,
127147
127699
  headers: headers ?? {},
127148
127700
  body,
127149
127701
  port
@@ -127157,20 +127709,20 @@ var ReverseConnectManager = class {
127157
127709
  conn.ws.send(JSON.stringify(frame));
127158
127710
  });
127159
127711
  }
127160
- openVirtualChannel(remoteServerId, channelId, path11, query) {
127161
- const conn = this.connections.get(remoteServerId);
127712
+ openVirtualChannel(remoteServerId, channelId, path12, query) {
127713
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127162
127714
  if (!conn || conn.ws.readyState !== 1) return;
127163
- const frame = { type: "ws_open", channelId, path: path11, query };
127715
+ const frame = { type: "ws_open", channelId, path: path12, query };
127164
127716
  conn.ws.send(JSON.stringify(frame));
127165
127717
  }
127166
127718
  sendChannelData(remoteServerId, channelId, data) {
127167
- const conn = this.connections.get(remoteServerId);
127719
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127168
127720
  if (!conn || conn.ws.readyState !== 1) return;
127169
127721
  const frame = { type: "ws_data", channelId, data };
127170
127722
  conn.ws.send(JSON.stringify(frame));
127171
127723
  }
127172
127724
  closeChannel(remoteServerId, channelId, code, reason) {
127173
- const conn = this.connections.get(remoteServerId);
127725
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127174
127726
  if (!conn) return;
127175
127727
  conn.virtualChannels.delete(channelId);
127176
127728
  if (conn.ws.readyState === 1) {
@@ -127179,7 +127731,7 @@ var ReverseConnectManager = class {
127179
127731
  }
127180
127732
  }
127181
127733
  setChannelAdapter(remoteServerId, channelId, adapter) {
127182
- const conn = this.connections.get(remoteServerId);
127734
+ const conn = this.connections.get(this.resolveId(remoteServerId));
127183
127735
  if (!conn) return;
127184
127736
  conn.virtualChannels.set(channelId, adapter);
127185
127737
  }
@@ -127491,8 +128043,69 @@ var sharedServices = async (fastify2, opts) => {
127491
128043
  const reverseConnectManager = new ReverseConnectManager();
127492
128044
  const browserManager = new BrowserManager();
127493
128045
  const chatSessionManager = new ChatSessionManager(opts.storage, processManager, agentSessionManager, remoteSessionMap, remoteExecutorMap, remotePatchCache, reverseConnectManager, browserManager);
128046
+ async function restoreRemoteExecutorsForServer(connectedServerId, directUrl) {
128047
+ const allRows = opts.storage.remoteExecutorProcesses.getAll();
128048
+ const unrestoredRows = allRows.filter((r) => !remoteExecutorMap.has(r.local_process_id));
128049
+ if (unrestoredRows.length === 0) return;
128050
+ const candidateRows = directUrl ? unrestoredRows.filter((r) => r.remote_server_id === connectedServerId) : unrestoredRows;
128051
+ if (candidateRows.length === 0) return;
128052
+ try {
128053
+ const result = await proxyToRemoteAuto(
128054
+ connectedServerId,
128055
+ directUrl ?? "",
128056
+ candidateRows[0].remote_api_key,
128057
+ "GET",
128058
+ "/api/executor-processes/running",
128059
+ void 0,
128060
+ { timeoutMs: 5e3, reverseConnectManager }
128061
+ );
128062
+ if (result.ok) {
128063
+ const data = result.data;
128064
+ const processes = Array.isArray(data?.processes) ? data.processes : [];
128065
+ const runningIds = new Set(processes.map((p) => p.id));
128066
+ for (const row of candidateRows) {
128067
+ if (remoteExecutorMap.has(row.local_process_id)) continue;
128068
+ if (runningIds.has(row.remote_process_id)) {
128069
+ if (row.remote_server_id !== connectedServerId) {
128070
+ reverseConnectManager.addAlias(row.remote_server_id, connectedServerId);
128071
+ console.log(`[SharedServices] Registered server alias: ${row.remote_server_id} \u2192 ${connectedServerId}`);
128072
+ }
128073
+ remoteExecutorMap.set(row.local_process_id, {
128074
+ remoteServerId: row.remote_server_id,
128075
+ remoteUrl: row.remote_url,
128076
+ remoteApiKey: row.remote_api_key,
128077
+ remoteProcessId: row.remote_process_id,
128078
+ executorId: row.executor_id,
128079
+ projectId: row.project_id ?? void 0,
128080
+ branch: row.branch
128081
+ });
128082
+ eventBus.emit({
128083
+ type: "executor:started",
128084
+ projectId: row.project_id ?? "",
128085
+ executorId: row.executor_id,
128086
+ processId: row.local_process_id,
128087
+ target: row.remote_server_id
128088
+ });
128089
+ console.log(`[SharedServices] Restored remote executor: ${row.local_process_id}`);
128090
+ } else if (row.remote_server_id === connectedServerId) {
128091
+ opts.storage.remoteExecutorProcesses.delete(row.local_process_id);
128092
+ console.log(`[SharedServices] Cleaned up stale remote executor: ${row.local_process_id}`);
128093
+ }
128094
+ }
128095
+ } else {
128096
+ console.warn(`[SharedServices] Could not verify remote executors on ${connectedServerId} (status ${result.status})`);
128097
+ }
128098
+ } catch (err) {
128099
+ console.warn(`[SharedServices] Failed to verify remote executors on ${connectedServerId}: ${err}`);
128100
+ }
128101
+ }
127494
128102
  reverseConnectManager.setStatusChangeHandler((remoteServerId, status) => {
127495
128103
  opts.storage.remoteServers.updateStatus(remoteServerId, status);
128104
+ if (status === "online") {
128105
+ restoreRemoteExecutorsForServer(remoteServerId).catch((err) => {
128106
+ console.warn(`[SharedServices] Failed to restore remote executors on reconnect for ${remoteServerId}: ${err}`);
128107
+ });
128108
+ }
127496
128109
  });
127497
128110
  fastify2.decorate("storage", opts.storage);
127498
128111
  fastify2.decorate("processManager", processManager);
@@ -127508,6 +128121,19 @@ var sharedServices = async (fastify2, opts) => {
127508
128121
  agentSessionManager.setEventBus(eventBus);
127509
128122
  chatSessionManager.setEventBus(eventBus);
127510
128123
  processManager.setEventBus(eventBus);
128124
+ void (async () => {
128125
+ const savedRows = opts.storage.remoteExecutorProcesses.getAll();
128126
+ const directUrlRows = savedRows.filter((r) => r.remote_url);
128127
+ if (directUrlRows.length === 0) return;
128128
+ const byServer = /* @__PURE__ */ new Map();
128129
+ for (const r of directUrlRows) byServer.set(r.remote_server_id, r.remote_url);
128130
+ console.log(`[SharedServices] Found ${directUrlRows.length} persisted direct-URL remote executor(s), verifying...`);
128131
+ for (const [serverId, url2] of byServer) {
128132
+ await restoreRemoteExecutorsForServer(serverId, url2);
128133
+ }
128134
+ })().catch((err) => {
128135
+ console.error(`[SharedServices] Unexpected error in remote executor restore:`, err);
128136
+ });
127511
128137
  fastify2.addHook("onClose", async () => {
127512
128138
  agentSessionManager.shutdown();
127513
128139
  processManager.shutdown();
@@ -127537,14 +128163,14 @@ var selectFolder = async () => {
127537
128163
  const { stdout } = await execAsync(
127538
128164
  `osascript -e 'set folderPath to POSIX path of (choose folder with prompt "Select a project folder")' -e 'return folderPath'`
127539
128165
  );
127540
- const path11 = stdout.trim();
127541
- return path11 || null;
128166
+ const path12 = stdout.trim();
128167
+ return path12 || null;
127542
128168
  } else if (os2 === "win32") {
127543
128169
  const { stdout } = await execAsync(
127544
128170
  `powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.FolderBrowserDialog; $f.ShowDialog() | Out-Null; $f.SelectedPath"`
127545
128171
  );
127546
- const path11 = stdout.trim();
127547
- return path11 || null;
128172
+ const path12 = stdout.trim();
128173
+ return path12 || null;
127548
128174
  } else {
127549
128175
  try {
127550
128176
  const { stdout } = await execAsync(
@@ -128382,6 +129008,15 @@ var routes7 = async (fastify2) => {
128382
129008
  executorId: executor.id,
128383
129009
  projectId: project.id
128384
129010
  });
129011
+ fastify2.storage.remoteExecutorProcesses.insert(localProcessId, {
129012
+ remoteServerId: executorMode,
129013
+ remoteUrl: remoteConfig.server_url ?? "",
129014
+ remoteApiKey: remoteConfig.server_api_key || "",
129015
+ remoteProcessId: remoteData.processId,
129016
+ executorId: executor.id,
129017
+ projectId: project.id,
129018
+ branch: branch ?? void 0
129019
+ });
128385
129020
  fastify2.eventBus.emit({
128386
129021
  type: "executor:started",
128387
129022
  projectId: project.id,
@@ -128433,6 +129068,7 @@ var routes7 = async (fastify2) => {
128433
129068
  target: remoteInfo.remoteServerId
128434
129069
  });
128435
129070
  fastify2.remoteExecutorMap.delete(req.params.processId);
129071
+ fastify2.storage.remoteExecutorProcesses.delete(req.params.processId);
128436
129072
  }
128437
129073
  return reply.code(result.status || 200).send(result.data);
128438
129074
  }
@@ -128448,8 +129084,8 @@ var routes7 = async (fastify2) => {
128448
129084
  const runningProcessIds = fastify2.processManager.getRunningProcessIds();
128449
129085
  const processes = runningProcessIds.map((id) => {
128450
129086
  const dbProcess = fastify2.storage.executorProcesses.getById(id);
128451
- return dbProcess ? { ...dbProcess, target: "local" } : null;
128452
- }).filter(Boolean);
129087
+ return dbProcess ? { ...dbProcess, target: "local" } : { id, executor_id: "", status: "running", exit_code: null, started_at: null, finished_at: null, target: "local" };
129088
+ });
128453
129089
  for (const [localProcessId, info] of fastify2.remoteExecutorMap) {
128454
129090
  processes.push({
128455
129091
  id: localProcessId,
@@ -128469,26 +129105,29 @@ var process_routes_default = (0, import_fastify_plugin8.default)(routes7, { name
128469
129105
  // src/routes/worktree-routes.ts
128470
129106
  var import_fastify_plugin9 = __toESM(require_plugin2(), 1);
128471
129107
  import { mkdir as mkdir2 } from "fs/promises";
128472
- function getRemoteConfig(fastify2, project) {
129108
+ function getAllRemoteConfigs(fastify2, project) {
128473
129109
  const remotes = fastify2.storage.projectRemotes.getByProject(project.id);
128474
129110
  if (remotes.length > 0) {
128475
- const primary = remotes[0];
128476
- return {
128477
- serverId: primary.remote_server_id,
128478
- url: primary.server_url ?? "",
128479
- apiKey: primary.server_api_key ?? "",
128480
- remotePath: primary.remote_path
128481
- };
129111
+ return remotes.map((r) => ({
129112
+ serverId: r.remote_server_id,
129113
+ url: r.server_url ?? "",
129114
+ apiKey: r.server_api_key ?? "",
129115
+ remotePath: r.remote_path
129116
+ }));
128482
129117
  }
128483
129118
  if (project.remote_url && project.remote_api_key && project.remote_path) {
128484
- return {
129119
+ return [{
128485
129120
  serverId: "",
128486
129121
  url: project.remote_url,
128487
129122
  apiKey: project.remote_api_key,
128488
129123
  remotePath: project.remote_path
128489
- };
129124
+ }];
128490
129125
  }
128491
- return null;
129126
+ return [];
129127
+ }
129128
+ function getRemoteConfig(fastify2, project) {
129129
+ const all = getAllRemoteConfigs(fastify2, project);
129130
+ return all.length > 0 ? all[0] : null;
128492
129131
  }
128493
129132
  var routes8 = async (fastify2) => {
128494
129133
  fastify2.get("/api/path/branches", async (req, reply) => {
@@ -128708,19 +129347,47 @@ var routes8 = async (fastify2) => {
128708
129347
  return reply.code(400).send({ error: "Branch is required" });
128709
129348
  }
128710
129349
  const hasLocal = !!project.path;
128711
- const remoteConfig = getRemoteConfig(fastify2, project);
128712
- const hasRemote = !!remoteConfig;
128713
- if (!hasLocal && hasRemote) {
128714
- const result = await proxyToRemoteAuto(
128715
- remoteConfig.serverId,
128716
- remoteConfig.url,
128717
- remoteConfig.apiKey,
129350
+ const remoteConfigs = getAllRemoteConfigs(fastify2, project);
129351
+ const hasRemote = remoteConfigs.length > 0;
129352
+ const deleteOnRemote = async (rc) => {
129353
+ return proxyToRemoteAuto(
129354
+ rc.serverId,
129355
+ rc.url,
129356
+ rc.apiKey,
128718
129357
  "DELETE",
128719
129358
  `/api/path/worktrees`,
128720
- { path: remoteConfig.remotePath, branch },
129359
+ { path: rc.remotePath, branch },
128721
129360
  { reverseConnectManager: fastify2.reverseConnectManager }
128722
129361
  );
128723
- return reply.code(result.status || 200).send(result.data);
129362
+ };
129363
+ if (!hasLocal && hasRemote) {
129364
+ if (remoteConfigs.length === 1) {
129365
+ const result = await deleteOnRemote(remoteConfigs[0]);
129366
+ return reply.code(result.status || 200).send(result.data);
129367
+ }
129368
+ const results2 = {};
129369
+ await Promise.allSettled(
129370
+ remoteConfigs.map(async (rc) => {
129371
+ const key = rc.serverId || rc.url;
129372
+ try {
129373
+ const result = await deleteOnRemote(rc);
129374
+ if (result.ok) {
129375
+ results2[key] = { success: true };
129376
+ } else {
129377
+ const data = result.data;
129378
+ results2[key] = { success: false, error: data.error || "Remote deletion failed" };
129379
+ }
129380
+ } catch (error48) {
129381
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
129382
+ results2[key] = { success: false, error: errorMessage };
129383
+ }
129384
+ })
129385
+ );
129386
+ const anyFailed = Object.values(results2).some((r) => !r.success);
129387
+ if (anyFailed) {
129388
+ return reply.code(207).send({ success: true, results: results2 });
129389
+ }
129390
+ return reply.code(200).send({ success: true, results: results2 });
128724
129391
  }
128725
129392
  if (!hasLocal) {
128726
129393
  return reply.code(400).send({ error: "Project has no local path" });
@@ -128783,27 +129450,25 @@ var routes8 = async (fastify2) => {
128783
129450
  const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
128784
129451
  return reply.code(500).send({ error: `Failed to delete local worktree: ${errorMessage}` });
128785
129452
  }
128786
- try {
128787
- const remoteResult = await proxyToRemoteAuto(
128788
- remoteConfig.serverId,
128789
- remoteConfig.url,
128790
- remoteConfig.apiKey,
128791
- "DELETE",
128792
- `/api/path/worktrees`,
128793
- { path: remoteConfig.remotePath, branch },
128794
- { reverseConnectManager: fastify2.reverseConnectManager }
128795
- );
128796
- if (remoteResult.ok) {
128797
- results.remote = { success: true };
128798
- } else {
128799
- const remoteData = remoteResult.data;
128800
- results.remote = { success: false, error: remoteData.error || "Remote deletion failed" };
128801
- }
128802
- } catch (error48) {
128803
- const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
128804
- results.remote = { success: false, error: errorMessage };
128805
- }
128806
- if (!results.remote?.success) {
129453
+ await Promise.allSettled(
129454
+ remoteConfigs.map(async (rc) => {
129455
+ const key = remoteConfigs.length === 1 ? "remote" : rc.serverId || rc.url;
129456
+ try {
129457
+ const remoteResult = await deleteOnRemote(rc);
129458
+ if (remoteResult.ok) {
129459
+ results[key] = { success: true };
129460
+ } else {
129461
+ const remoteData = remoteResult.data;
129462
+ results[key] = { success: false, error: remoteData.error || "Remote deletion failed" };
129463
+ }
129464
+ } catch (error48) {
129465
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
129466
+ results[key] = { success: false, error: errorMessage };
129467
+ }
129468
+ })
129469
+ );
129470
+ const anyRemoteFailed = Object.entries(results).some(([k, v]) => k !== "local" && !v.success);
129471
+ if (anyRemoteFailed) {
128807
129472
  return reply.code(207).send({ success: true, results });
128808
129473
  }
128809
129474
  return reply.code(200).send({ success: true, results });
@@ -128832,8 +129497,8 @@ var routes8 = async (fastify2) => {
128832
129497
  return reply.code(400).send({ error: "Invalid remote base branch name format" });
128833
129498
  }
128834
129499
  const hasLocal = !!project.path;
128835
- const remoteConfig = getRemoteConfig(fastify2, project);
128836
- const hasRemote = !!remoteConfig;
129500
+ const remoteConfigs = getAllRemoteConfigs(fastify2, project);
129501
+ const hasRemote = remoteConfigs.length > 0;
128837
129502
  let targets;
128838
129503
  if (req.body.targets && req.body.targets.length > 0) {
128839
129504
  targets = req.body.targets;
@@ -128848,17 +129513,52 @@ var routes8 = async (fastify2) => {
128848
129513
  if (targets.includes("remote") && !hasRemote) {
128849
129514
  return reply.code(400).send({ error: "Project has no remote configuration" });
128850
129515
  }
128851
- if (targets.length === 1 && targets[0] === "remote") {
128852
- const result = await proxyToRemoteAuto(
128853
- remoteConfig.serverId,
128854
- remoteConfig.url,
128855
- remoteConfig.apiKey,
129516
+ const createOnRemote = async (rc) => {
129517
+ return proxyToRemoteAuto(
129518
+ rc.serverId,
129519
+ rc.url,
129520
+ rc.apiKey,
128856
129521
  "POST",
128857
129522
  `/api/path/worktrees`,
128858
- { path: remoteConfig.remotePath, branchName: trimmedBranch, baseBranch: remoteStartPoint },
129523
+ { path: rc.remotePath, branchName: trimmedBranch, baseBranch: remoteStartPoint },
128859
129524
  { reverseConnectManager: fastify2.reverseConnectManager }
128860
129525
  );
128861
- return reply.code(result.status || 201).send(result.data);
129526
+ };
129527
+ if (targets.length === 1 && targets[0] === "remote") {
129528
+ if (remoteConfigs.length === 1) {
129529
+ const result = await createOnRemote(remoteConfigs[0]);
129530
+ return reply.code(result.status || 201).send(result.data);
129531
+ }
129532
+ const results2 = {};
129533
+ const settled = await Promise.allSettled(
129534
+ remoteConfigs.map(async (rc) => {
129535
+ const key = rc.serverId || rc.url;
129536
+ console.log(`[worktree] Creating remote worktree: project=${req.params.id}, branch=${trimmedBranch}, serverId=${rc.serverId}, url=${rc.url}`);
129537
+ try {
129538
+ const result = await createOnRemote(rc);
129539
+ if (result.ok) {
129540
+ const data = result.data;
129541
+ results2[key] = { success: true, worktree: data.worktree };
129542
+ } else {
129543
+ const data = result.data;
129544
+ console.error(`[worktree] Remote failed: serverId=${rc.serverId}, requestId=${result.requestId}, error=${JSON.stringify(result.data)}`);
129545
+ results2[key] = { success: false, error: data.error || "Remote creation failed", errorCode: result.errorCode, requestId: result.requestId };
129546
+ }
129547
+ } catch (error48) {
129548
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
129549
+ results2[key] = { success: false, error: errorMessage };
129550
+ }
129551
+ })
129552
+ );
129553
+ const anyFailed = Object.values(results2).some((r) => !r.success);
129554
+ const allFailed = Object.values(results2).every((r) => !r.success);
129555
+ if (allFailed) {
129556
+ return reply.code(500).send({ error: "Failed to create worktree on all remotes", results: results2 });
129557
+ }
129558
+ if (anyFailed) {
129559
+ return reply.code(207).send({ worktree: { branch: trimmedBranch }, results: results2 });
129560
+ }
129561
+ return reply.code(201).send({ worktree: { branch: trimmedBranch }, results: results2 });
128862
129562
  }
128863
129563
  const createLocal = async () => {
128864
129564
  const { execSync: execSync2 } = await import("child_process");
@@ -128902,35 +129602,33 @@ var routes8 = async (fastify2) => {
128902
129602
  const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
128903
129603
  return reply.code(500).send({ error: `Failed to create local worktree: ${errorMessage}` });
128904
129604
  }
128905
- console.log(`[worktree] Creating remote worktree: project=${req.params.id}, branch=${trimmedBranch}, serverId=${remoteConfig.serverId}, url=${remoteConfig.url}`);
128906
- try {
128907
- const remoteResult = await proxyToRemoteAuto(
128908
- remoteConfig.serverId,
128909
- remoteConfig.url,
128910
- remoteConfig.apiKey,
128911
- "POST",
128912
- `/api/path/worktrees`,
128913
- { path: remoteConfig.remotePath, branchName: trimmedBranch, baseBranch: remoteStartPoint },
128914
- { reverseConnectManager: fastify2.reverseConnectManager }
128915
- );
128916
- if (remoteResult.ok) {
128917
- const remoteData = remoteResult.data;
128918
- results.remote = { success: true, worktree: remoteData.worktree };
128919
- } else {
128920
- const remoteData = remoteResult.data;
128921
- console.error(`[worktree] Remote failed: requestId=${remoteResult.requestId}, errorCode=${remoteResult.errorCode}, status=${remoteResult.status}, duration=${remoteResult.durationMs}ms, error=${JSON.stringify(remoteResult.data)}`);
128922
- results.remote = {
128923
- success: false,
128924
- error: remoteData.error || "Remote creation failed",
128925
- errorCode: remoteResult.errorCode,
128926
- requestId: remoteResult.requestId
128927
- };
128928
- }
128929
- } catch (error48) {
128930
- const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
128931
- results.remote = { success: false, error: errorMessage };
128932
- }
128933
- if (!results.remote?.success) {
129605
+ await Promise.allSettled(
129606
+ remoteConfigs.map(async (rc) => {
129607
+ const key = remoteConfigs.length === 1 ? "remote" : rc.serverId || rc.url;
129608
+ console.log(`[worktree] Creating remote worktree: project=${req.params.id}, branch=${trimmedBranch}, serverId=${rc.serverId}, url=${rc.url}`);
129609
+ try {
129610
+ const remoteResult = await createOnRemote(rc);
129611
+ if (remoteResult.ok) {
129612
+ const remoteData = remoteResult.data;
129613
+ results[key] = { success: true, worktree: remoteData.worktree };
129614
+ } else {
129615
+ const remoteData = remoteResult.data;
129616
+ console.error(`[worktree] Remote failed: serverId=${rc.serverId}, requestId=${remoteResult.requestId}, errorCode=${remoteResult.errorCode}, status=${remoteResult.status}, duration=${remoteResult.durationMs}ms, error=${JSON.stringify(remoteResult.data)}`);
129617
+ results[key] = {
129618
+ success: false,
129619
+ error: remoteData.error || "Remote creation failed",
129620
+ errorCode: remoteResult.errorCode,
129621
+ requestId: remoteResult.requestId
129622
+ };
129623
+ }
129624
+ } catch (error48) {
129625
+ const errorMessage = error48 instanceof Error ? error48.message : "Unknown error";
129626
+ results[key] = { success: false, error: errorMessage };
129627
+ }
129628
+ })
129629
+ );
129630
+ const anyRemoteFailed = Object.entries(results).some(([k, v]) => k !== "local" && !v.success);
129631
+ if (anyRemoteFailed) {
128934
129632
  return reply.code(207).send({
128935
129633
  worktree: localWorktree,
128936
129634
  results
@@ -128946,6 +129644,8 @@ var worktree_routes_default = (0, import_fastify_plugin9.default)(routes8, { nam
128946
129644
 
128947
129645
  // src/routes/diff-routes.ts
128948
129646
  var import_fastify_plugin10 = __toESM(require_plugin2(), 1);
129647
+ import path6 from "path";
129648
+ import { readFileSync } from "fs";
128949
129649
 
128950
129650
  // src/utils/diff-parser.ts
128951
129651
  function parseDiffOutput(diffOutput) {
@@ -129073,9 +129773,64 @@ function parseGitLogOutput(output) {
129073
129773
  }
129074
129774
  return commits;
129075
129775
  }
129076
- function buildDiffCommand(since) {
129077
- const ref = since || "HEAD";
129078
- return `git diff ${ref} --no-color`;
129776
+ function buildDiffCommand(commit) {
129777
+ if (!commit) {
129778
+ return `git diff HEAD --no-color`;
129779
+ }
129780
+ return `git diff ${commit}^ ${commit} --no-color`;
129781
+ }
129782
+ function buildDiffFallbackCommand(commit) {
129783
+ return `git show ${commit} --format="" --no-color`;
129784
+ }
129785
+ async function getUntrackedFiles(cwd) {
129786
+ let untrackedOutput;
129787
+ try {
129788
+ const { execSync: execSync2 } = await import("child_process");
129789
+ untrackedOutput = execSync2(
129790
+ "git ls-files --others --exclude-standard",
129791
+ { cwd, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 }
129792
+ ).trim();
129793
+ } catch {
129794
+ return [];
129795
+ }
129796
+ if (!untrackedOutput) return [];
129797
+ const untrackedPaths = untrackedOutput.split("\n");
129798
+ const files = [];
129799
+ for (const filePath of untrackedPaths) {
129800
+ try {
129801
+ const fullPath = path6.join(cwd, filePath);
129802
+ const buffer = readFileSync(fullPath);
129803
+ if (buffer.includes(0)) {
129804
+ files.push({ path: filePath, status: "added", hunks: [] });
129805
+ continue;
129806
+ }
129807
+ const content = buffer.toString("utf-8");
129808
+ const lines = content.split("\n");
129809
+ if (lines.length > 0 && lines[lines.length - 1] === "") {
129810
+ lines.pop();
129811
+ }
129812
+ const diffLines = lines.map((line, i) => ({
129813
+ type: "add",
129814
+ content: line,
129815
+ newLineNo: i + 1
129816
+ }));
129817
+ files.push({
129818
+ path: filePath,
129819
+ status: "added",
129820
+ hunks: diffLines.length > 0 ? [
129821
+ {
129822
+ oldStart: 0,
129823
+ oldLines: 0,
129824
+ newStart: 1,
129825
+ newLines: diffLines.length,
129826
+ lines: diffLines
129827
+ }
129828
+ ] : []
129829
+ });
129830
+ } catch {
129831
+ }
129832
+ }
129833
+ return files;
129079
129834
  }
129080
129835
  var routes9 = async (fastify2) => {
129081
129836
  fastify2.get("/api/path/diff", async (req, reply) => {
@@ -129084,32 +129839,32 @@ var routes9 = async (fastify2) => {
129084
129839
  return reply.code(400).send({ error: "Path is required" });
129085
129840
  }
129086
129841
  const branch = req.query.branch;
129087
- const since = req.query.since;
129088
- if (since && !/^[0-9a-f]+$/i.test(since)) {
129842
+ const commit = req.query.commit;
129843
+ if (commit && !/^[0-9a-f]+$/i.test(commit)) {
129089
129844
  return reply.code(400).send({ error: "Invalid commit hash" });
129090
129845
  }
129091
129846
  const cwd = resolveWorktreePath(projectPath, branch ?? null);
129847
+ const untrackedFiles = !commit ? await getUntrackedFiles(cwd) : [];
129092
129848
  try {
129093
129849
  const { execSync: execSync2 } = await import("child_process");
129094
- const diffOutput = execSync2(buildDiffCommand(since), {
129850
+ const diffOutput = execSync2(buildDiffCommand(commit), {
129095
129851
  cwd,
129096
129852
  encoding: "utf-8",
129097
129853
  maxBuffer: 10 * 1024 * 1024
129098
129854
  });
129099
129855
  const files = parseDiffOutput(diffOutput);
129100
- return reply.code(200).send({ files });
129856
+ return reply.code(200).send({ files: [...files, ...untrackedFiles] });
129101
129857
  } catch {
129102
129858
  try {
129103
129859
  const { execSync: execSync2 } = await import("child_process");
129104
- const diffOutput = execSync2("git diff --no-color", {
129105
- cwd,
129106
- encoding: "utf-8",
129107
- maxBuffer: 10 * 1024 * 1024
129108
- });
129860
+ const diffOutput = execSync2(
129861
+ commit ? buildDiffFallbackCommand(commit) : "git diff --no-color",
129862
+ { cwd, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 }
129863
+ );
129109
129864
  const files = parseDiffOutput(diffOutput);
129110
- return reply.code(200).send({ files });
129865
+ return reply.code(200).send({ files: [...files, ...untrackedFiles] });
129111
129866
  } catch {
129112
- return reply.code(200).send({ files: [] });
129867
+ return reply.code(200).send({ files: untrackedFiles });
129113
129868
  }
129114
129869
  }
129115
129870
  });
@@ -129141,9 +129896,9 @@ var routes9 = async (fastify2) => {
129141
129896
  return reply.code(404).send({ error: "Project not found" });
129142
129897
  }
129143
129898
  const branch = req.query.branch;
129144
- const since = req.query.since;
129899
+ const commit = req.query.commit;
129145
129900
  const target = req.query.target;
129146
- if (since && !/^[0-9a-f]+$/i.test(since)) {
129901
+ if (commit && !/^[0-9a-f]+$/i.test(commit)) {
129147
129902
  return reply.code(400).send({ error: "Invalid commit hash" });
129148
129903
  }
129149
129904
  const useRemote = target === "remote" || !target && !project.path;
@@ -129154,7 +129909,7 @@ var routes9 = async (fastify2) => {
129154
129909
  }
129155
129910
  const params = [`path=${encodeURIComponent(remoteConfig.remotePath)}`];
129156
129911
  if (branch) params.push(`branch=${encodeURIComponent(branch)}`);
129157
- if (since) params.push(`since=${encodeURIComponent(since)}`);
129912
+ if (commit) params.push(`commit=${encodeURIComponent(commit)}`);
129158
129913
  const result = await proxyToRemoteAuto(
129159
129914
  remoteConfig.serverId,
129160
129915
  remoteConfig.url,
@@ -129170,27 +129925,27 @@ var routes9 = async (fastify2) => {
129170
129925
  return reply.code(400).send({ error: "Project has no local path" });
129171
129926
  }
129172
129927
  const cwd = resolveWorktreePath(project.path, branch ?? null);
129928
+ const untrackedFiles = !commit ? await getUntrackedFiles(cwd) : [];
129173
129929
  try {
129174
129930
  const { execSync: execSync2 } = await import("child_process");
129175
- const diffOutput = execSync2(buildDiffCommand(since), {
129931
+ const diffOutput = execSync2(buildDiffCommand(commit), {
129176
129932
  cwd,
129177
129933
  encoding: "utf-8",
129178
129934
  maxBuffer: 10 * 1024 * 1024
129179
129935
  });
129180
129936
  const files = parseDiffOutput(diffOutput);
129181
- return reply.code(200).send({ files });
129937
+ return reply.code(200).send({ files: [...files, ...untrackedFiles] });
129182
129938
  } catch {
129183
129939
  try {
129184
129940
  const { execSync: execSync2 } = await import("child_process");
129185
- const diffOutput = execSync2("git diff --no-color", {
129186
- cwd,
129187
- encoding: "utf-8",
129188
- maxBuffer: 10 * 1024 * 1024
129189
- });
129941
+ const diffOutput = execSync2(
129942
+ commit ? buildDiffFallbackCommand(commit) : "git diff --no-color",
129943
+ { cwd, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 }
129944
+ );
129190
129945
  const files = parseDiffOutput(diffOutput);
129191
- return reply.code(200).send({ files });
129946
+ return reply.code(200).send({ files: [...files, ...untrackedFiles] });
129192
129947
  } catch {
129193
- return reply.code(200).send({ files: [] });
129948
+ return reply.code(200).send({ files: untrackedFiles });
129194
129949
  }
129195
129950
  }
129196
129951
  });
@@ -129245,7 +130000,7 @@ var diff_routes_default = (0, import_fastify_plugin10.default)(routes9, { name:
129245
130000
 
129246
130001
  // src/routes/file-routes.ts
129247
130002
  var import_fastify_plugin11 = __toESM(require_plugin2(), 1);
129248
- import path6 from "path";
130003
+ import path7 from "path";
129249
130004
  import fs from "fs/promises";
129250
130005
  import { createReadStream } from "fs";
129251
130006
  import { Readable } from "stream";
@@ -129272,9 +130027,9 @@ function getRemoteConfig3(fastify2, project) {
129272
130027
  }
129273
130028
  var MAX_FILE_SIZE = 1 * 1024 * 1024;
129274
130029
  function isPathSafe(basePath33, relativePath) {
129275
- const normalizedBase = path6.resolve(basePath33);
129276
- const resolved = path6.resolve(normalizedBase, relativePath);
129277
- return resolved.startsWith(normalizedBase + path6.sep) || resolved === normalizedBase;
130030
+ const normalizedBase = path7.resolve(basePath33);
130031
+ const resolved = path7.resolve(normalizedBase, relativePath);
130032
+ return resolved.startsWith(normalizedBase + path7.sep) || resolved === normalizedBase;
129278
130033
  }
129279
130034
  async function isBinaryFile(filePath) {
129280
130035
  const fd = await fs.open(filePath, "r");
@@ -129297,14 +130052,14 @@ async function browseDirectory(dirPath) {
129297
130052
  if (entry.name === "node_modules") continue;
129298
130053
  if (entry.isDirectory()) {
129299
130054
  try {
129300
- const stat = await fs.stat(path6.join(dirPath, entry.name));
130055
+ const stat = await fs.stat(path7.join(dirPath, entry.name));
129301
130056
  items.push({ name: entry.name, type: "directory", mtime: stat.mtime.toISOString() });
129302
130057
  } catch {
129303
130058
  items.push({ name: entry.name, type: "directory" });
129304
130059
  }
129305
130060
  } else if (entry.isFile()) {
129306
130061
  try {
129307
- const stat = await fs.stat(path6.join(dirPath, entry.name));
130062
+ const stat = await fs.stat(path7.join(dirPath, entry.name));
129308
130063
  items.push({ name: entry.name, type: "file", size: stat.size, mtime: stat.mtime.toISOString() });
129309
130064
  } catch {
129310
130065
  items.push({ name: entry.name, type: "file" });
@@ -129343,7 +130098,7 @@ var routes10 = async (fastify2) => {
129343
130098
  if (!isPathSafe(basePath33, filePath)) {
129344
130099
  return reply.code(403).send({ error: "Path traversal not allowed" });
129345
130100
  }
129346
- const fullPath = path6.resolve(basePath33, filePath);
130101
+ const fullPath = path7.resolve(basePath33, filePath);
129347
130102
  try {
129348
130103
  const stat = await fs.stat(fullPath);
129349
130104
  if (stat.size > MAX_FILE_SIZE) {
@@ -129370,8 +130125,8 @@ var routes10 = async (fastify2) => {
129370
130125
  if (!isPathSafe(basePath33, filePath)) {
129371
130126
  return reply.code(403).send({ error: "Path traversal not allowed" });
129372
130127
  }
129373
- const fullPath = path6.resolve(basePath33, filePath);
129374
- const fileName = path6.basename(fullPath);
130128
+ const fullPath = path7.resolve(basePath33, filePath);
130129
+ const fileName = path7.basename(fullPath);
129375
130130
  try {
129376
130131
  await fs.access(fullPath);
129377
130132
  const stream = createReadStream(fullPath);
@@ -129396,7 +130151,7 @@ var routes10 = async (fastify2) => {
129396
130151
  if (!remoteConfig) {
129397
130152
  return reply.code(400).send({ error: "Project has no remote configuration" });
129398
130153
  }
129399
- const remotePath = relativePath ? path6.posix.join(remoteConfig.remotePath, relativePath) : remoteConfig.remotePath;
130154
+ const remotePath = relativePath ? path7.posix.join(remoteConfig.remotePath, relativePath) : remoteConfig.remotePath;
129400
130155
  const params = [`path=${encodeURIComponent(remotePath)}`];
129401
130156
  if (branch) params.push(`branch=${encodeURIComponent(branch)}`);
129402
130157
  const result = await proxyToRemoteAuto(
@@ -129414,7 +130169,7 @@ var routes10 = async (fastify2) => {
129414
130169
  return reply.code(400).send({ error: "Project has no local path" });
129415
130170
  }
129416
130171
  const basePath33 = resolveWorktreePath(project.path, branch ?? null);
129417
- const dirPath = relativePath ? path6.resolve(basePath33, relativePath) : basePath33;
130172
+ const dirPath = relativePath ? path7.resolve(basePath33, relativePath) : basePath33;
129418
130173
  if (!isPathSafe(basePath33, relativePath || ".")) {
129419
130174
  return reply.code(403).send({ error: "Path traversal not allowed" });
129420
130175
  }
@@ -129467,7 +130222,7 @@ var routes10 = async (fastify2) => {
129467
130222
  if (!isPathSafe(basePath33, filePath)) {
129468
130223
  return reply.code(403).send({ error: "Path traversal not allowed" });
129469
130224
  }
129470
- const fullPath = path6.resolve(basePath33, filePath);
130225
+ const fullPath = path7.resolve(basePath33, filePath);
129471
130226
  try {
129472
130227
  const stat = await fs.stat(fullPath);
129473
130228
  if (stat.size > MAX_FILE_SIZE) {
@@ -129528,7 +130283,7 @@ var routes10 = async (fastify2) => {
129528
130283
  if (!result.ok) {
129529
130284
  return reply.code(result.status || 500).send({ error: "Failed to download file from remote" });
129530
130285
  }
129531
- const fileName2 = path6.basename(filePath);
130286
+ const fileName2 = path7.basename(filePath);
129532
130287
  reply.header("Content-Disposition", `attachment; filename="${fileName2}"`);
129533
130288
  reply.type("application/octet-stream");
129534
130289
  if (result.body) {
@@ -129544,8 +130299,8 @@ var routes10 = async (fastify2) => {
129544
130299
  if (!isPathSafe(basePath33, filePath)) {
129545
130300
  return reply.code(403).send({ error: "Path traversal not allowed" });
129546
130301
  }
129547
- const fullPath = path6.resolve(basePath33, filePath);
129548
- const fileName = path6.basename(fullPath);
130302
+ const fullPath = path7.resolve(basePath33, filePath);
130303
+ const fileName = path7.basename(fullPath);
129549
130304
  try {
129550
130305
  await fs.access(fullPath);
129551
130306
  const stream = createReadStream(fullPath);
@@ -130118,6 +130873,14 @@ var routes12 = async (fastify2) => {
130118
130873
  }
130119
130874
  return reply.send({ ok: true });
130120
130875
  });
130876
+ fastify2.post("/api/chat-sessions/:sessionId/reset", async (req, reply) => {
130877
+ const { sessionId } = req.params;
130878
+ const reset = fastify2.chatSessionManager.resetSession(sessionId);
130879
+ if (!reset) {
130880
+ return reply.code(404).send({ error: "Session not found" });
130881
+ }
130882
+ return reply.send({ ok: true });
130883
+ });
130121
130884
  };
130122
130885
  var chat_session_routes_default = (0, import_fastify_plugin13.default)(routes12, { name: "chat-session-routes" });
130123
130886
 
@@ -130222,10 +130985,89 @@ Description: ${description}`
130222
130985
  };
130223
130986
  var task_routes_default = (0, import_fastify_plugin14.default)(routes13, { name: "task-routes" });
130224
130987
 
130225
- // src/routes/settings-routes.ts
130988
+ // src/routes/rule-routes.ts
130226
130989
  var import_fastify_plugin15 = __toESM(require_plugin2(), 1);
130227
- var DEFAULT_PROXY_CONFIG = { type: "none", host: "", port: 0 };
130990
+ import { randomUUID as randomUUID11 } from "crypto";
130228
130991
  var routes14 = async (fastify2) => {
130992
+ fastify2.get(
130993
+ "/api/projects/:projectId/rules",
130994
+ async (req, reply) => {
130995
+ const userId = requireAuth(req, reply);
130996
+ if (userId === null) return;
130997
+ const project = fastify2.storage.projects.getById(req.params.projectId, userId);
130998
+ if (!project) {
130999
+ return reply.code(404).send({ error: "Project not found" });
131000
+ }
131001
+ const branch = req.query.branch ?? null;
131002
+ const rules = fastify2.storage.rules.getByWorkspace(req.params.projectId, branch);
131003
+ return reply.code(200).send({ rules });
131004
+ }
131005
+ );
131006
+ fastify2.post("/api/projects/:projectId/rules", async (req, reply) => {
131007
+ const userId = requireAuth(req, reply);
131008
+ if (userId === null) return;
131009
+ const project = fastify2.storage.projects.getById(req.params.projectId, userId);
131010
+ if (!project) {
131011
+ return reply.code(404).send({ error: "Project not found" });
131012
+ }
131013
+ const { branch, name: name25, content, enabled } = req.body;
131014
+ if (!name25 || !content) {
131015
+ return reply.code(400).send({ error: "name and content are required" });
131016
+ }
131017
+ const id = randomUUID11();
131018
+ const rule = fastify2.storage.rules.create({
131019
+ id,
131020
+ project_id: req.params.projectId,
131021
+ branch: branch ?? null,
131022
+ name: name25,
131023
+ content,
131024
+ enabled
131025
+ });
131026
+ return reply.code(201).send({ rule });
131027
+ });
131028
+ fastify2.put("/api/rules/:id", async (req, reply) => {
131029
+ const existing = fastify2.storage.rules.getById(req.params.id);
131030
+ if (!existing) {
131031
+ return reply.code(404).send({ error: "Rule not found" });
131032
+ }
131033
+ const rule = fastify2.storage.rules.update(req.params.id, {
131034
+ name: req.body.name,
131035
+ content: req.body.content,
131036
+ enabled: req.body.enabled,
131037
+ position: req.body.position
131038
+ });
131039
+ return reply.code(200).send({ rule });
131040
+ });
131041
+ fastify2.delete("/api/rules/:id", async (req, reply) => {
131042
+ const existing = fastify2.storage.rules.getById(req.params.id);
131043
+ if (!existing) {
131044
+ return reply.code(404).send({ error: "Rule not found" });
131045
+ }
131046
+ fastify2.storage.rules.delete(req.params.id);
131047
+ return reply.code(200).send({ success: true });
131048
+ });
131049
+ fastify2.put("/api/projects/:projectId/rules/reorder", async (req, reply) => {
131050
+ const userId = requireAuth(req, reply);
131051
+ if (userId === null) return;
131052
+ const project = fastify2.storage.projects.getById(req.params.projectId, userId);
131053
+ if (!project) {
131054
+ return reply.code(404).send({ error: "Project not found" });
131055
+ }
131056
+ const { orderedIds } = req.body;
131057
+ if (!Array.isArray(orderedIds)) {
131058
+ return reply.code(400).send({ error: "orderedIds must be an array" });
131059
+ }
131060
+ const branch = req.query.branch ?? null;
131061
+ fastify2.storage.rules.reorder(req.params.projectId, branch, orderedIds);
131062
+ return reply.code(200).send({ success: true });
131063
+ });
131064
+ };
131065
+ var rule_routes_default = (0, import_fastify_plugin15.default)(routes14, { name: "rule-routes" });
131066
+
131067
+ // src/routes/settings-routes.ts
131068
+ var import_fastify_plugin16 = __toESM(require_plugin2(), 1);
131069
+ var DEFAULT_PROXY_CONFIG = { type: "none", host: "", port: 0 };
131070
+ var routes15 = async (fastify2) => {
130229
131071
  fastify2.get("/api/settings/proxy", async (_req, reply) => {
130230
131072
  const saved = fastify2.storage.settings.get("proxy");
130231
131073
  if (!saved) {
@@ -130338,11 +131180,11 @@ var routes14 = async (fastify2) => {
130338
131180
  });
130339
131181
  });
130340
131182
  };
130341
- var settings_routes_default = (0, import_fastify_plugin15.default)(routes14, { name: "settings-routes" });
131183
+ var settings_routes_default = (0, import_fastify_plugin16.default)(routes15, { name: "settings-routes" });
130342
131184
 
130343
131185
  // src/routes/translate-routes.ts
130344
- var import_fastify_plugin16 = __toESM(require_plugin2(), 1);
130345
- var routes15 = async (fastify2) => {
131186
+ var import_fastify_plugin17 = __toESM(require_plugin2(), 1);
131187
+ var routes16 = async (fastify2) => {
130346
131188
  fastify2.post(
130347
131189
  "/api/translate",
130348
131190
  async (req, reply) => {
@@ -130375,11 +131217,11 @@ ${text2}`
130375
131217
  }
130376
131218
  );
130377
131219
  };
130378
- var translate_routes_default = (0, import_fastify_plugin16.default)(routes15, { name: "translate-routes" });
131220
+ var translate_routes_default = (0, import_fastify_plugin17.default)(routes16, { name: "translate-routes" });
130379
131221
 
130380
131222
  // src/routes/websocket-routes.ts
130381
- var import_fastify_plugin17 = __toESM(require_plugin2(), 1);
130382
- import { randomUUID as randomUUID11 } from "crypto";
131223
+ var import_fastify_plugin18 = __toESM(require_plugin2(), 1);
131224
+ import { randomUUID as randomUUID12 } from "crypto";
130383
131225
  async function verifyWsToken(token) {
130384
131226
  try {
130385
131227
  const { verifyToken: verifyToken3 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
@@ -130408,13 +131250,13 @@ function tryParseWsMessage(raw) {
130408
131250
  return void 0;
130409
131251
  }
130410
131252
  }
130411
- function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager) {
131253
+ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager, eventBus) {
130412
131254
  const hasCachedData = cache2.hasData(sessionId);
130413
131255
  const useVirtual = reverseConnectManager && reverseConnectManager.isConnected(remoteInfo.remoteServerId);
130414
131256
  console.log(`[AgentWS] Opening persistent remote WS for ${sessionId} (cached=${hasCachedData}, virtual=${!!useVirtual})`);
130415
131257
  let remoteWs;
130416
131258
  if (useVirtual) {
130417
- const channelId = randomUUID11();
131259
+ const channelId = randomUUID12();
130418
131260
  const wsPath = `/api/agent-sessions/${remoteInfo.remoteSessionId}/stream`;
130419
131261
  const wsQuery = `apiKey=${encodeURIComponent(remoteInfo.remoteApiKey)}`;
130420
131262
  const adapter = new VirtualWsAdapter(
@@ -130459,6 +131301,22 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
130459
131301
  } else if ("taskCompleted" in parsed) {
130460
131302
  cache2.appendMessage(sessionId, raw, false);
130461
131303
  cache2.broadcast(sessionId, raw);
131304
+ if (eventBus) {
131305
+ const tc = parsed.taskCompleted;
131306
+ const prefix = `remote-${remoteInfo.remoteServerId}-`;
131307
+ const suffix = `-${remoteInfo.remoteSessionId}`;
131308
+ const projectId = sessionId.startsWith(prefix) && sessionId.endsWith(suffix) ? sessionId.slice(prefix.length, sessionId.length - suffix.length) : sessionId.split("-").slice(2, -1).join("-");
131309
+ eventBus.emit({
131310
+ type: "session:taskCompleted",
131311
+ projectId,
131312
+ branch: remoteInfo.branch ?? null,
131313
+ sessionId,
131314
+ duration_ms: tc?.duration_ms,
131315
+ cost_usd: tc?.cost_usd,
131316
+ input_tokens: tc?.input_tokens,
131317
+ output_tokens: tc?.output_tokens
131318
+ });
131319
+ }
130462
131320
  } else if ("error" in parsed) {
130463
131321
  cache2.appendMessage(sessionId, raw, false);
130464
131322
  cache2.broadcast(sessionId, raw);
@@ -130550,10 +131408,10 @@ function connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, rev
130550
131408
  cache2.setRemoteWs(sessionId, null);
130551
131409
  const entry = cache2.get(sessionId);
130552
131410
  if (!entry || entry.finished) return;
130553
- scheduleRemoteReconnect(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager);
131411
+ scheduleRemoteReconnect(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager, eventBus);
130554
131412
  });
130555
131413
  }
130556
- function scheduleRemoteReconnect(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager) {
131414
+ function scheduleRemoteReconnect(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager, eventBus) {
130557
131415
  const entry = cache2.get(sessionId);
130558
131416
  if (!entry || entry.finished) return;
130559
131417
  const attempt = cache2.getReconnectAttempt(sessionId);
@@ -130575,11 +131433,11 @@ function scheduleRemoteReconnect(sessionId, remoteInfo, cache2, wsOptions, rever
130575
131433
  cache2.setReconnecting(sessionId, false);
130576
131434
  return;
130577
131435
  }
130578
- connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager);
131436
+ connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, reverseConnectManager, eventBus);
130579
131437
  }, totalDelay);
130580
131438
  cache2.setReconnectTimer(sessionId, timer);
130581
131439
  }
130582
- var routes16 = async (fastify2) => {
131440
+ var routes17 = async (fastify2) => {
130583
131441
  fastify2.reverseConnectManager.setStatusChangeHandler((remoteServerId, status) => {
130584
131442
  if (status !== "online") return;
130585
131443
  const cache2 = fastify2.remotePatchCache;
@@ -130591,7 +131449,7 @@ var routes16 = async (fastify2) => {
130591
131449
  if (cache2.getRemoteWs(sessionId) || cache2.isReconnecting(sessionId)) continue;
130592
131450
  console.log(`[AgentWS] Reverse-connect restored for ${remoteServerId}, re-establishing WS for ${sessionId}`);
130593
131451
  cache2.resetReconnectAttempt(sessionId);
130594
- connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, fastify2.reverseConnectManager);
131452
+ connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, fastify2.reverseConnectManager, fastify2.eventBus);
130595
131453
  }
130596
131454
  });
130597
131455
  fastify2.after(() => {
@@ -130612,7 +131470,7 @@ var routes16 = async (fastify2) => {
130612
131470
  const useVirtualExec = fastify2.reverseConnectManager.isConnected(remoteInfo.remoteServerId);
130613
131471
  let remoteWs;
130614
131472
  if (useVirtualExec) {
130615
- const channelId = randomUUID11();
131473
+ const channelId = randomUUID12();
130616
131474
  const wsPath = `/api/executor-processes/${remoteInfo.remoteProcessId}/logs`;
130617
131475
  const wsQuery = `apiKey=${encodeURIComponent(remoteInfo.remoteApiKey)}`;
130618
131476
  const adapter = new VirtualWsAdapter(
@@ -130652,9 +131510,13 @@ var routes16 = async (fastify2) => {
130652
131510
  socket.send(raw);
130653
131511
  try {
130654
131512
  const parsed = JSON.parse(raw);
131513
+ if (parsed.type === "init" || parsed.type === "history_end") {
131514
+ console.log(`[WebSocket] Remote proxy forwarded: ${parsed.type} for ${processId}`);
131515
+ }
130655
131516
  if (parsed.type === "finished") {
130656
131517
  const info = fastify2.remoteExecutorMap.get(processId);
130657
- if (info) {
131518
+ if (info && !info.stoppedEmitted) {
131519
+ info.stoppedEmitted = true;
130658
131520
  fastify2.eventBus.emit({
130659
131521
  type: "executor:stopped",
130660
131522
  projectId: info.projectId ?? "",
@@ -130663,7 +131525,10 @@ var routes16 = async (fastify2) => {
130663
131525
  exitCode: parsed.exitCode ?? 0,
130664
131526
  target: info.remoteServerId
130665
131527
  });
131528
+ }
131529
+ if (info) {
130666
131530
  fastify2.remoteExecutorMap.delete(processId);
131531
+ fastify2.storage.remoteExecutorProcesses.delete(processId);
130667
131532
  }
130668
131533
  }
130669
131534
  } catch {
@@ -130815,7 +131680,7 @@ var routes16 = async (fastify2) => {
130815
131680
  const wsOptions = fastify2.proxyManager.getWsOptions();
130816
131681
  const existingRemoteWs = cache2.getRemoteWs(sessionId);
130817
131682
  if (!existingRemoteWs && !cache2.isReconnecting(sessionId)) {
130818
- connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, fastify2.reverseConnectManager);
131683
+ connectPersistentRemoteWs(sessionId, remoteInfo, cache2, wsOptions, fastify2.reverseConnectManager, fastify2.eventBus);
130819
131684
  }
130820
131685
  if (cache2.getRemoteWs(sessionId)) {
130821
131686
  try {
@@ -130910,11 +131775,11 @@ var routes16 = async (fastify2) => {
130910
131775
  );
130911
131776
  });
130912
131777
  };
130913
- var websocket_routes_default = (0, import_fastify_plugin17.default)(routes16, { name: "websocket-routes" });
131778
+ var websocket_routes_default = (0, import_fastify_plugin18.default)(routes17, { name: "websocket-routes" });
130914
131779
 
130915
131780
  // src/routes/reverse-connect-routes.ts
130916
- var import_fastify_plugin18 = __toESM(require_plugin2(), 1);
130917
- var routes17 = async (fastify2) => {
131781
+ var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
131782
+ var routes18 = async (fastify2) => {
130918
131783
  fastify2.after(() => {
130919
131784
  fastify2.get(
130920
131785
  "/api/reverse-connect",
@@ -130944,11 +131809,11 @@ var routes17 = async (fastify2) => {
130944
131809
  );
130945
131810
  });
130946
131811
  };
130947
- var reverse_connect_routes_default = (0, import_fastify_plugin18.default)(routes17, { name: "reverse-connect-routes" });
131812
+ var reverse_connect_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "reverse-connect-routes" });
130948
131813
 
130949
131814
  // src/routes/event-routes.ts
130950
- var import_fastify_plugin19 = __toESM(require_plugin2(), 1);
130951
- var routes18 = async (fastify2) => {
131815
+ var import_fastify_plugin20 = __toESM(require_plugin2(), 1);
131816
+ var routes19 = async (fastify2) => {
130952
131817
  fastify2.get("/api/events", async (req, reply) => {
130953
131818
  if (fastify2.authEnabled) {
130954
131819
  const apiKey = req.headers["x-vibedeckx-api-key"];
@@ -130992,10 +131857,10 @@ var routes18 = async (fastify2) => {
130992
131857
  await reply;
130993
131858
  });
130994
131859
  };
130995
- var event_routes_default = (0, import_fastify_plugin19.default)(routes18, { name: "event-routes" });
131860
+ var event_routes_default = (0, import_fastify_plugin20.default)(routes19, { name: "event-routes" });
130996
131861
 
130997
131862
  // src/routes/terminal-routes.ts
130998
- var import_fastify_plugin20 = __toESM(require_plugin2(), 1);
131863
+ var import_fastify_plugin21 = __toESM(require_plugin2(), 1);
130999
131864
  function getRemoteConfig4(fastify2, project, remoteServerId) {
131000
131865
  const remotes = fastify2.storage.projectRemotes.getByProject(project.id);
131001
131866
  if (remotes.length > 0) {
@@ -131019,7 +131884,7 @@ function getRemoteConfig4(fastify2, project, remoteServerId) {
131019
131884
  }
131020
131885
  return null;
131021
131886
  }
131022
- var routes19 = async (fastify2) => {
131887
+ var routes20 = async (fastify2) => {
131023
131888
  fastify2.post("/api/path/terminals", async (req, reply) => {
131024
131889
  const { path: projectPath, branch } = req.body;
131025
131890
  if (!projectPath) {
@@ -131121,6 +131986,15 @@ var routes19 = async (fastify2) => {
131121
131986
  projectId: req.params.projectId,
131122
131987
  branch: branch ?? null
131123
131988
  });
131989
+ fastify2.storage.remoteExecutorProcesses.insert(localId, {
131990
+ remoteServerId: remoteConfig.serverId,
131991
+ remoteUrl: remoteConfig.url,
131992
+ remoteApiKey: remoteConfig.apiKey,
131993
+ remoteProcessId: remoteId,
131994
+ executorId: "",
131995
+ projectId: req.params.projectId,
131996
+ branch: branch ?? null
131997
+ });
131124
131998
  return reply.code(201).send({
131125
131999
  terminal: {
131126
132000
  id: localId,
@@ -131164,6 +132038,7 @@ var routes19 = async (fastify2) => {
131164
132038
  { reverseConnectManager: fastify2.reverseConnectManager }
131165
132039
  );
131166
132040
  fastify2.remoteExecutorMap.delete(terminalId);
132041
+ fastify2.storage.remoteExecutorProcesses.delete(terminalId);
131167
132042
  if (!result.ok) {
131168
132043
  return reply.code(result.status || 502).send(result.data);
131169
132044
  }
@@ -131177,11 +132052,11 @@ var routes19 = async (fastify2) => {
131177
132052
  }
131178
132053
  );
131179
132054
  };
131180
- var terminal_routes_default = (0, import_fastify_plugin20.default)(routes19, { name: "terminal-routes" });
132055
+ var terminal_routes_default = (0, import_fastify_plugin21.default)(routes20, { name: "terminal-routes" });
131181
132056
 
131182
132057
  // src/routes/browser-routes.ts
131183
- var import_fastify_plugin21 = __toESM(require_plugin2(), 1);
131184
- var routes20 = async (fastify2) => {
132058
+ var import_fastify_plugin22 = __toESM(require_plugin2(), 1);
132059
+ var routes21 = async (fastify2) => {
131185
132060
  fastify2.post("/api/projects/:id/browser", async (req, reply) => {
131186
132061
  if (requireAuth(req, reply) === null) return;
131187
132062
  const { id: projectId } = req.params;
@@ -131241,11 +132116,11 @@ var routes20 = async (fastify2) => {
131241
132116
  return reply.code(200).send({ ok: true });
131242
132117
  });
131243
132118
  };
131244
- var browser_routes_default = (0, import_fastify_plugin21.default)(routes20, { name: "browser-routes" });
132119
+ var browser_routes_default = (0, import_fastify_plugin22.default)(routes21, { name: "browser-routes" });
131245
132120
 
131246
132121
  // src/routes/browser-proxy-routes.ts
131247
- var import_fastify_plugin22 = __toESM(require_plugin2(), 1);
131248
- import { randomUUID as randomUUID12 } from "crypto";
132122
+ var import_fastify_plugin23 = __toESM(require_plugin2(), 1);
132123
+ import { randomUUID as randomUUID13 } from "crypto";
131249
132124
  function resolveTarget(targetUrl, projectRemotes, reverseConnectManager) {
131250
132125
  const parsed = new URL(targetUrl);
131251
132126
  const hostname3 = parsed.hostname;
@@ -131269,11 +132144,11 @@ async function proxyFetch(resolved, requestHeaders, reverseConnectManager) {
131269
132144
  if (resolved.remoteServerId && reverseConnectManager?.isConnected(resolved.remoteServerId)) {
131270
132145
  const parsed = new URL(resolved.fetchUrl);
131271
132146
  const port = parsed.port ? parseInt(parsed.port, 10) : void 0;
131272
- const path11 = parsed.pathname + parsed.search;
132147
+ const path12 = parsed.pathname + parsed.search;
131273
132148
  const raw = await reverseConnectManager.sendRawHttpRequest(
131274
132149
  resolved.remoteServerId,
131275
132150
  "GET",
131276
- path11,
132151
+ path12,
131277
132152
  requestHeaders,
131278
132153
  void 0,
131279
132154
  void 0,
@@ -131495,7 +132370,7 @@ function generateInjectedScript(projectId, targetOrigin, proxyWsPrefix) {
131495
132370
  })();
131496
132371
  </script>`;
131497
132372
  }
131498
- var routes21 = async (fastify2) => {
132373
+ var routes22 = async (fastify2) => {
131499
132374
  fastify2.get("/api/projects/:id/browser/proxy/*", async (req, reply) => {
131500
132375
  const { id: projectId } = req.params;
131501
132376
  const targetUrl = extractTargetUrl(req.url, projectId);
@@ -131565,7 +132440,7 @@ var routes21 = async (fastify2) => {
131565
132440
  const rcm = fastify2.reverseConnectManager;
131566
132441
  if (resolved.remoteServerId && rcm.isConnected(resolved.remoteServerId)) {
131567
132442
  const remoteServerId = resolved.remoteServerId;
131568
- const channelId = randomUUID12();
132443
+ const channelId = randomUUID13();
131569
132444
  const parsed = new URL(resolved.fetchUrl);
131570
132445
  const wsPath = parsed.pathname;
131571
132446
  const wsQuery = parsed.search ? parsed.search.slice(1) : void 0;
@@ -131628,7 +132503,7 @@ var routes21 = async (fastify2) => {
131628
132503
  });
131629
132504
  });
131630
132505
  };
131631
- var browser_proxy_routes_default = (0, import_fastify_plugin22.default)(routes21, { name: "browser-proxy-routes" });
132506
+ var browser_proxy_routes_default = (0, import_fastify_plugin23.default)(routes22, { name: "browser-proxy-routes" });
131632
132507
 
131633
132508
  // ../../node_modules/.pnpm/@clerk+fastify@3.1.2_fastify@5.7.2_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/fastify/dist/chunk-RY4T2JMQ.mjs
131634
132509
  import { Readable as Readable2 } from "stream";
@@ -131680,7 +132555,7 @@ var requestToProxyRequest = (req) => {
131680
132555
 
131681
132556
  // ../../node_modules/.pnpm/@clerk+fastify@3.1.2_fastify@5.7.2_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/fastify/dist/index.mjs
131682
132557
  init_dist();
131683
- var import_fastify_plugin23 = __toESM(require_plugin2(), 1);
132558
+ var import_fastify_plugin24 = __toESM(require_plugin2(), 1);
131684
132559
 
131685
132560
  // ../../node_modules/.pnpm/@clerk+backend@3.2.0_react-dom@19.2.3_react@19.2.3__react@19.2.3/node_modules/@clerk/backend/dist/internal.mjs
131686
132561
  init_chunk_JW73PKED();
@@ -131968,7 +132843,7 @@ var plugin = (instance, opts, done) => {
131968
132843
  instance.addHook(hookName, withClerkMiddleware(opts));
131969
132844
  done();
131970
132845
  };
131971
- var clerkPlugin = (0, import_fastify_plugin23.default)(plugin, {
132846
+ var clerkPlugin = (0, import_fastify_plugin24.default)(plugin, {
131972
132847
  name: "@clerk/fastify",
131973
132848
  fastify: "5.x"
131974
132849
  });
@@ -132025,8 +132900,8 @@ var createServer = async (opts) => {
132025
132900
  process.exit(1);
132026
132901
  }
132027
132902
  }
132028
- const UI_ROOT = path7.join(
132029
- path7.dirname(fileURLToPath(import.meta.url)),
132903
+ const UI_ROOT = path8.join(
132904
+ path8.dirname(fileURLToPath(import.meta.url)),
132030
132905
  "./ui"
132031
132906
  );
132032
132907
  const server = (0, import_fastify.default)({ maxParamLength: 500 });
@@ -132120,6 +132995,7 @@ var createServer = async (opts) => {
132120
132995
  server.register(agent_session_routes_default);
132121
132996
  server.register(chat_session_routes_default);
132122
132997
  server.register(task_routes_default);
132998
+ server.register(rule_routes_default);
132123
132999
  server.register(settings_routes_default);
132124
133000
  server.register(translate_routes_default);
132125
133001
  server.register(event_routes_default);
@@ -132417,15 +133293,15 @@ var ReverseConnectClient = class {
132417
133293
 
132418
133294
  // src/constants.ts
132419
133295
  import { homedir } from "os";
132420
- import path8 from "path";
132421
- var VIBEDECKX_HOME = path8.join(homedir(), ".vibedeckx");
132422
- var DB_PATH = path8.join(VIBEDECKX_HOME, "data.sqlite");
133296
+ import path9 from "path";
133297
+ var VIBEDECKX_HOME = path9.join(homedir(), ".vibedeckx");
133298
+ var DB_PATH = path9.join(VIBEDECKX_HOME, "data.sqlite");
132423
133299
  var DEFAULT_PORT = 5173;
132424
133300
 
132425
133301
  // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
132426
133302
  import process8 from "node:process";
132427
133303
  import { Buffer as Buffer2 } from "node:buffer";
132428
- import path9 from "node:path";
133304
+ import path10 from "node:path";
132429
133305
  import { fileURLToPath as fileURLToPath2 } from "node:url";
132430
133306
  import { promisify as promisify6 } from "node:util";
132431
133307
  import childProcess from "node:child_process";
@@ -132676,8 +133552,8 @@ async function defaultBrowser2() {
132676
133552
 
132677
133553
  // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
132678
133554
  var execFile5 = promisify6(childProcess.execFile);
132679
- var __dirname2 = path9.dirname(fileURLToPath2(import.meta.url));
132680
- var localXdgOpenPath = path9.join(__dirname2, "xdg-open");
133555
+ var __dirname2 = path10.dirname(fileURLToPath2(import.meta.url));
133556
+ var localXdgOpenPath = path10.join(__dirname2, "xdg-open");
132681
133557
  var { platform: platform2, arch } = process8;
132682
133558
  async function getWindowsDefaultBrowserFromWsl() {
132683
133559
  const powershellPath = await powerShellPath();
@@ -132958,7 +133834,7 @@ var startCommand = buildCommand({
132958
133834
  const port = flags.port ?? DEFAULT_PORT;
132959
133835
  const authEnabled = flags.auth ?? false;
132960
133836
  console.log("Starting vibedeckx...");
132961
- const dbPath = flags["data-dir"] ? path10.join(flags["data-dir"], "data.sqlite") : DB_PATH;
133837
+ const dbPath = flags["data-dir"] ? path11.join(flags["data-dir"], "data.sqlite") : DB_PATH;
132962
133838
  const storage = await createSqliteStorage(dbPath);
132963
133839
  const server = await createServer({ storage, authEnabled });
132964
133840
  const url2 = await server.start(port);
@@ -133022,7 +133898,7 @@ var connectCommand = buildCommand({
133022
133898
  func: async (flags) => {
133023
133899
  const requestedPort = flags.port ?? 0;
133024
133900
  console.log("Starting vibedeckx in reverse-connect mode...");
133025
- const dbPath = flags["data-dir"] ? path10.join(flags["data-dir"], "data.sqlite") : DB_PATH;
133901
+ const dbPath = flags["data-dir"] ? path11.join(flags["data-dir"], "data.sqlite") : DB_PATH;
133026
133902
  const storage = await createSqliteStorage(dbPath);
133027
133903
  const server = await createServer({ storage });
133028
133904
  const { instance, port: localPort } = await server.startLocal(requestedPort);
@@ -133059,7 +133935,7 @@ var connectCommand = buildCommand({
133059
133935
  brief: "Connect to a remote Vibedeckx server as an inbound node"
133060
133936
  }
133061
133937
  });
133062
- var routes22 = buildRouteMap({
133938
+ var routes23 = buildRouteMap({
133063
133939
  routes: {
133064
133940
  start: startCommand,
133065
133941
  connect: connectCommand
@@ -133069,7 +133945,7 @@ var routes22 = buildRouteMap({
133069
133945
  brief: "Vibedeckx - AI-powered app generator"
133070
133946
  }
133071
133947
  });
133072
- var program = buildApplication(routes22, {
133948
+ var program = buildApplication(routes23, {
133073
133949
  name: "vibedeckx",
133074
133950
  versionInfo: {
133075
133951
  currentVersion: "0.1.0"