@swmansion/argent 0.29.1-next.21 → 0.29.1-next.23

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.
@@ -2990,7 +2990,7 @@ var require_compile = __commonJS({
2990
2990
  const schOrFunc = root.refs[ref];
2991
2991
  if (schOrFunc)
2992
2992
  return schOrFunc;
2993
- let _sch = resolve9.call(this, root, ref);
2993
+ let _sch = resolve10.call(this, root, ref);
2994
2994
  if (_sch === void 0) {
2995
2995
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2996
2996
  const { schemaId } = this.opts;
@@ -3017,7 +3017,7 @@ var require_compile = __commonJS({
3017
3017
  function sameSchemaEnv(s1, s2) {
3018
3018
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3019
3019
  }
3020
- function resolve9(root, ref) {
3020
+ function resolve10(root, ref) {
3021
3021
  let sch;
3022
3022
  while (typeof (sch = this.refs[ref]) == "string")
3023
3023
  ref = sch;
@@ -3235,8 +3235,8 @@ var require_utils = __commonJS({
3235
3235
  }
3236
3236
  return ind;
3237
3237
  }
3238
- function removeDotSegments(path16) {
3239
- let input = path16;
3238
+ function removeDotSegments(path17) {
3239
+ let input = path17;
3240
3240
  const output = [];
3241
3241
  let nextSlash = -1;
3242
3242
  let len = 0;
@@ -3488,8 +3488,8 @@ var require_schemes = __commonJS({
3488
3488
  wsComponent.secure = void 0;
3489
3489
  }
3490
3490
  if (wsComponent.resourceName) {
3491
- const [path16, query] = wsComponent.resourceName.split("?");
3492
- wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
3491
+ const [path17, query] = wsComponent.resourceName.split("?");
3492
+ wsComponent.path = path17 && path17 !== "/" ? path17 : void 0;
3493
3493
  wsComponent.query = query;
3494
3494
  wsComponent.resourceName = void 0;
3495
3495
  }
@@ -3648,7 +3648,7 @@ var require_fast_uri = __commonJS({
3648
3648
  }
3649
3649
  return uri;
3650
3650
  }
3651
- function resolve9(baseURI, relativeURI, options) {
3651
+ function resolve10(baseURI, relativeURI, options) {
3652
3652
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3653
3653
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3654
3654
  schemelessOptions.skipEscape = true;
@@ -3906,7 +3906,7 @@ var require_fast_uri = __commonJS({
3906
3906
  var fastUri = {
3907
3907
  SCHEMES,
3908
3908
  normalize: normalize3,
3909
- resolve: resolve9,
3909
+ resolve: resolve10,
3910
3910
  resolveComponent,
3911
3911
  equal,
3912
3912
  serialize,
@@ -6882,12 +6882,12 @@ var require_dist = __commonJS({
6882
6882
  throw new Error(`Unknown format "${name}"`);
6883
6883
  return f;
6884
6884
  };
6885
- function addFormats(ajv, list, fs11, exportName) {
6885
+ function addFormats(ajv, list, fs12, exportName) {
6886
6886
  var _a3;
6887
6887
  var _b;
6888
6888
  (_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6889
6889
  for (const f of list)
6890
- ajv.addFormat(f, fs11[f]);
6890
+ ajv.addFormat(f, fs12[f]);
6891
6891
  }
6892
6892
  module.exports = exports = formatsPlugin;
6893
6893
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -6972,17 +6972,17 @@ var require_visit = __commonJS({
6972
6972
  visit.BREAK = BREAK;
6973
6973
  visit.SKIP = SKIP;
6974
6974
  visit.REMOVE = REMOVE;
6975
- function visit_(key, node2, visitor, path16) {
6976
- const ctrl = callVisitor(key, node2, visitor, path16);
6975
+ function visit_(key, node2, visitor, path17) {
6976
+ const ctrl = callVisitor(key, node2, visitor, path17);
6977
6977
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
6978
- replaceNode(key, path16, ctrl);
6979
- return visit_(key, ctrl, visitor, path16);
6978
+ replaceNode(key, path17, ctrl);
6979
+ return visit_(key, ctrl, visitor, path17);
6980
6980
  }
6981
6981
  if (typeof ctrl !== "symbol") {
6982
6982
  if (identity.isCollection(node2)) {
6983
- path16 = Object.freeze(path16.concat(node2));
6983
+ path17 = Object.freeze(path17.concat(node2));
6984
6984
  for (let i = 0; i < node2.items.length; ++i) {
6985
- const ci = visit_(i, node2.items[i], visitor, path16);
6985
+ const ci = visit_(i, node2.items[i], visitor, path17);
6986
6986
  if (typeof ci === "number")
6987
6987
  i = ci - 1;
6988
6988
  else if (ci === BREAK)
@@ -6993,13 +6993,13 @@ var require_visit = __commonJS({
6993
6993
  }
6994
6994
  }
6995
6995
  } else if (identity.isPair(node2)) {
6996
- path16 = Object.freeze(path16.concat(node2));
6997
- const ck = visit_("key", node2.key, visitor, path16);
6996
+ path17 = Object.freeze(path17.concat(node2));
6997
+ const ck = visit_("key", node2.key, visitor, path17);
6998
6998
  if (ck === BREAK)
6999
6999
  return BREAK;
7000
7000
  else if (ck === REMOVE)
7001
7001
  node2.key = null;
7002
- const cv = visit_("value", node2.value, visitor, path16);
7002
+ const cv = visit_("value", node2.value, visitor, path17);
7003
7003
  if (cv === BREAK)
7004
7004
  return BREAK;
7005
7005
  else if (cv === REMOVE)
@@ -7020,17 +7020,17 @@ var require_visit = __commonJS({
7020
7020
  visitAsync.BREAK = BREAK;
7021
7021
  visitAsync.SKIP = SKIP;
7022
7022
  visitAsync.REMOVE = REMOVE;
7023
- async function visitAsync_(key, node2, visitor, path16) {
7024
- const ctrl = await callVisitor(key, node2, visitor, path16);
7023
+ async function visitAsync_(key, node2, visitor, path17) {
7024
+ const ctrl = await callVisitor(key, node2, visitor, path17);
7025
7025
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
7026
- replaceNode(key, path16, ctrl);
7027
- return visitAsync_(key, ctrl, visitor, path16);
7026
+ replaceNode(key, path17, ctrl);
7027
+ return visitAsync_(key, ctrl, visitor, path17);
7028
7028
  }
7029
7029
  if (typeof ctrl !== "symbol") {
7030
7030
  if (identity.isCollection(node2)) {
7031
- path16 = Object.freeze(path16.concat(node2));
7031
+ path17 = Object.freeze(path17.concat(node2));
7032
7032
  for (let i = 0; i < node2.items.length; ++i) {
7033
- const ci = await visitAsync_(i, node2.items[i], visitor, path16);
7033
+ const ci = await visitAsync_(i, node2.items[i], visitor, path17);
7034
7034
  if (typeof ci === "number")
7035
7035
  i = ci - 1;
7036
7036
  else if (ci === BREAK)
@@ -7041,13 +7041,13 @@ var require_visit = __commonJS({
7041
7041
  }
7042
7042
  }
7043
7043
  } else if (identity.isPair(node2)) {
7044
- path16 = Object.freeze(path16.concat(node2));
7045
- const ck = await visitAsync_("key", node2.key, visitor, path16);
7044
+ path17 = Object.freeze(path17.concat(node2));
7045
+ const ck = await visitAsync_("key", node2.key, visitor, path17);
7046
7046
  if (ck === BREAK)
7047
7047
  return BREAK;
7048
7048
  else if (ck === REMOVE)
7049
7049
  node2.key = null;
7050
- const cv = await visitAsync_("value", node2.value, visitor, path16);
7050
+ const cv = await visitAsync_("value", node2.value, visitor, path17);
7051
7051
  if (cv === BREAK)
7052
7052
  return BREAK;
7053
7053
  else if (cv === REMOVE)
@@ -7074,23 +7074,23 @@ var require_visit = __commonJS({
7074
7074
  }
7075
7075
  return visitor;
7076
7076
  }
7077
- function callVisitor(key, node2, visitor, path16) {
7077
+ function callVisitor(key, node2, visitor, path17) {
7078
7078
  if (typeof visitor === "function")
7079
- return visitor(key, node2, path16);
7079
+ return visitor(key, node2, path17);
7080
7080
  if (identity.isMap(node2))
7081
- return visitor.Map?.(key, node2, path16);
7081
+ return visitor.Map?.(key, node2, path17);
7082
7082
  if (identity.isSeq(node2))
7083
- return visitor.Seq?.(key, node2, path16);
7083
+ return visitor.Seq?.(key, node2, path17);
7084
7084
  if (identity.isPair(node2))
7085
- return visitor.Pair?.(key, node2, path16);
7085
+ return visitor.Pair?.(key, node2, path17);
7086
7086
  if (identity.isScalar(node2))
7087
- return visitor.Scalar?.(key, node2, path16);
7087
+ return visitor.Scalar?.(key, node2, path17);
7088
7088
  if (identity.isAlias(node2))
7089
- return visitor.Alias?.(key, node2, path16);
7089
+ return visitor.Alias?.(key, node2, path17);
7090
7090
  return void 0;
7091
7091
  }
7092
- function replaceNode(key, path16, node2) {
7093
- const parent = path16[path16.length - 1];
7092
+ function replaceNode(key, path17, node2) {
7093
+ const parent = path17[path17.length - 1];
7094
7094
  if (identity.isCollection(parent)) {
7095
7095
  parent.items[key] = node2;
7096
7096
  } else if (identity.isPair(parent)) {
@@ -7702,10 +7702,10 @@ var require_Collection = __commonJS({
7702
7702
  var createNode = require_createNode();
7703
7703
  var identity = require_identity();
7704
7704
  var Node = require_Node();
7705
- function collectionFromPath(schema, path16, value) {
7705
+ function collectionFromPath(schema, path17, value) {
7706
7706
  let v = value;
7707
- for (let i = path16.length - 1; i >= 0; --i) {
7708
- const k = path16[i];
7707
+ for (let i = path17.length - 1; i >= 0; --i) {
7708
+ const k = path17[i];
7709
7709
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
7710
7710
  const a = [];
7711
7711
  a[k] = v;
@@ -7724,7 +7724,7 @@ var require_Collection = __commonJS({
7724
7724
  sourceObjects: /* @__PURE__ */ new Map()
7725
7725
  });
7726
7726
  }
7727
- var isEmptyPath = (path16) => path16 == null || typeof path16 === "object" && !!path16[Symbol.iterator]().next().done;
7727
+ var isEmptyPath = (path17) => path17 == null || typeof path17 === "object" && !!path17[Symbol.iterator]().next().done;
7728
7728
  var Collection = class extends Node.NodeBase {
7729
7729
  constructor(type, schema) {
7730
7730
  super(type);
@@ -7754,11 +7754,11 @@ var require_Collection = __commonJS({
7754
7754
  * be a Pair instance or a `{ key, value }` object, which may not have a key
7755
7755
  * that already exists in the map.
7756
7756
  */
7757
- addIn(path16, value) {
7758
- if (isEmptyPath(path16))
7757
+ addIn(path17, value) {
7758
+ if (isEmptyPath(path17))
7759
7759
  this.add(value);
7760
7760
  else {
7761
- const [key, ...rest] = path16;
7761
+ const [key, ...rest] = path17;
7762
7762
  const node2 = this.get(key, true);
7763
7763
  if (identity.isCollection(node2))
7764
7764
  node2.addIn(rest, value);
@@ -7772,8 +7772,8 @@ var require_Collection = __commonJS({
7772
7772
  * Removes a value from the collection.
7773
7773
  * @returns `true` if the item was found and removed.
7774
7774
  */
7775
- deleteIn(path16) {
7776
- const [key, ...rest] = path16;
7775
+ deleteIn(path17) {
7776
+ const [key, ...rest] = path17;
7777
7777
  if (rest.length === 0)
7778
7778
  return this.delete(key);
7779
7779
  const node2 = this.get(key, true);
@@ -7787,8 +7787,8 @@ var require_Collection = __commonJS({
7787
7787
  * scalar values from their surrounding node; to disable set `keepScalar` to
7788
7788
  * `true` (collections are always returned intact).
7789
7789
  */
7790
- getIn(path16, keepScalar) {
7791
- const [key, ...rest] = path16;
7790
+ getIn(path17, keepScalar) {
7791
+ const [key, ...rest] = path17;
7792
7792
  const node2 = this.get(key, true);
7793
7793
  if (rest.length === 0)
7794
7794
  return !keepScalar && identity.isScalar(node2) ? node2.value : node2;
@@ -7806,8 +7806,8 @@ var require_Collection = __commonJS({
7806
7806
  /**
7807
7807
  * Checks if the collection includes a value with the key `key`.
7808
7808
  */
7809
- hasIn(path16) {
7810
- const [key, ...rest] = path16;
7809
+ hasIn(path17) {
7810
+ const [key, ...rest] = path17;
7811
7811
  if (rest.length === 0)
7812
7812
  return this.has(key);
7813
7813
  const node2 = this.get(key, true);
@@ -7817,8 +7817,8 @@ var require_Collection = __commonJS({
7817
7817
  * Sets a value in this collection. For `!!set`, `value` needs to be a
7818
7818
  * boolean to add/remove the item from the set.
7819
7819
  */
7820
- setIn(path16, value) {
7821
- const [key, ...rest] = path16;
7820
+ setIn(path17, value) {
7821
+ const [key, ...rest] = path17;
7822
7822
  if (rest.length === 0) {
7823
7823
  this.set(key, value);
7824
7824
  } else {
@@ -10333,9 +10333,9 @@ var require_Document = __commonJS({
10333
10333
  this.contents.add(value);
10334
10334
  }
10335
10335
  /** Adds a value to the document. */
10336
- addIn(path16, value) {
10336
+ addIn(path17, value) {
10337
10337
  if (assertCollection(this.contents))
10338
- this.contents.addIn(path16, value);
10338
+ this.contents.addIn(path17, value);
10339
10339
  }
10340
10340
  /**
10341
10341
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -10410,14 +10410,14 @@ var require_Document = __commonJS({
10410
10410
  * Removes a value from the document.
10411
10411
  * @returns `true` if the item was found and removed.
10412
10412
  */
10413
- deleteIn(path16) {
10414
- if (Collection.isEmptyPath(path16)) {
10413
+ deleteIn(path17) {
10414
+ if (Collection.isEmptyPath(path17)) {
10415
10415
  if (this.contents == null)
10416
10416
  return false;
10417
10417
  this.contents = null;
10418
10418
  return true;
10419
10419
  }
10420
- return assertCollection(this.contents) ? this.contents.deleteIn(path16) : false;
10420
+ return assertCollection(this.contents) ? this.contents.deleteIn(path17) : false;
10421
10421
  }
10422
10422
  /**
10423
10423
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -10432,10 +10432,10 @@ var require_Document = __commonJS({
10432
10432
  * scalar values from their surrounding node; to disable set `keepScalar` to
10433
10433
  * `true` (collections are always returned intact).
10434
10434
  */
10435
- getIn(path16, keepScalar) {
10436
- if (Collection.isEmptyPath(path16))
10435
+ getIn(path17, keepScalar) {
10436
+ if (Collection.isEmptyPath(path17))
10437
10437
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
10438
- return identity.isCollection(this.contents) ? this.contents.getIn(path16, keepScalar) : void 0;
10438
+ return identity.isCollection(this.contents) ? this.contents.getIn(path17, keepScalar) : void 0;
10439
10439
  }
10440
10440
  /**
10441
10441
  * Checks if the document includes a value with the key `key`.
@@ -10446,10 +10446,10 @@ var require_Document = __commonJS({
10446
10446
  /**
10447
10447
  * Checks if the document includes a value at `path`.
10448
10448
  */
10449
- hasIn(path16) {
10450
- if (Collection.isEmptyPath(path16))
10449
+ hasIn(path17) {
10450
+ if (Collection.isEmptyPath(path17))
10451
10451
  return this.contents !== void 0;
10452
- return identity.isCollection(this.contents) ? this.contents.hasIn(path16) : false;
10452
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path17) : false;
10453
10453
  }
10454
10454
  /**
10455
10455
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -10466,13 +10466,13 @@ var require_Document = __commonJS({
10466
10466
  * Sets a value in this document. For `!!set`, `value` needs to be a
10467
10467
  * boolean to add/remove the item from the set.
10468
10468
  */
10469
- setIn(path16, value) {
10470
- if (Collection.isEmptyPath(path16)) {
10469
+ setIn(path17, value) {
10470
+ if (Collection.isEmptyPath(path17)) {
10471
10471
  this.contents = value;
10472
10472
  } else if (this.contents == null) {
10473
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path16), value);
10473
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path17), value);
10474
10474
  } else if (assertCollection(this.contents)) {
10475
- this.contents.setIn(path16, value);
10475
+ this.contents.setIn(path17, value);
10476
10476
  }
10477
10477
  }
10478
10478
  /**
@@ -12433,9 +12433,9 @@ var require_cst_visit = __commonJS({
12433
12433
  visit.BREAK = BREAK;
12434
12434
  visit.SKIP = SKIP;
12435
12435
  visit.REMOVE = REMOVE;
12436
- visit.itemAtPath = (cst, path16) => {
12436
+ visit.itemAtPath = (cst, path17) => {
12437
12437
  let item = cst;
12438
- for (const [field, index] of path16) {
12438
+ for (const [field, index] of path17) {
12439
12439
  const tok = item?.[field];
12440
12440
  if (tok && "items" in tok) {
12441
12441
  item = tok.items[index];
@@ -12444,23 +12444,23 @@ var require_cst_visit = __commonJS({
12444
12444
  }
12445
12445
  return item;
12446
12446
  };
12447
- visit.parentCollection = (cst, path16) => {
12448
- const parent = visit.itemAtPath(cst, path16.slice(0, -1));
12449
- const field = path16[path16.length - 1][0];
12447
+ visit.parentCollection = (cst, path17) => {
12448
+ const parent = visit.itemAtPath(cst, path17.slice(0, -1));
12449
+ const field = path17[path17.length - 1][0];
12450
12450
  const coll = parent?.[field];
12451
12451
  if (coll && "items" in coll)
12452
12452
  return coll;
12453
12453
  throw new Error("Parent collection not found");
12454
12454
  };
12455
- function _visit(path16, item, visitor) {
12456
- let ctrl = visitor(item, path16);
12455
+ function _visit(path17, item, visitor) {
12456
+ let ctrl = visitor(item, path17);
12457
12457
  if (typeof ctrl === "symbol")
12458
12458
  return ctrl;
12459
12459
  for (const field of ["key", "value"]) {
12460
12460
  const token = item[field];
12461
12461
  if (token && "items" in token) {
12462
12462
  for (let i = 0; i < token.items.length; ++i) {
12463
- const ci = _visit(Object.freeze(path16.concat([[field, i]])), token.items[i], visitor);
12463
+ const ci = _visit(Object.freeze(path17.concat([[field, i]])), token.items[i], visitor);
12464
12464
  if (typeof ci === "number")
12465
12465
  i = ci - 1;
12466
12466
  else if (ci === BREAK)
@@ -12471,10 +12471,10 @@ var require_cst_visit = __commonJS({
12471
12471
  }
12472
12472
  }
12473
12473
  if (typeof ctrl === "function" && field === "key")
12474
- ctrl = ctrl(item, path16);
12474
+ ctrl = ctrl(item, path17);
12475
12475
  }
12476
12476
  }
12477
- return typeof ctrl === "function" ? ctrl(item, path16) : ctrl;
12477
+ return typeof ctrl === "function" ? ctrl(item, path17) : ctrl;
12478
12478
  }
12479
12479
  exports.visit = visit;
12480
12480
  }
@@ -13776,14 +13776,14 @@ var require_parser = __commonJS({
13776
13776
  case "scalar":
13777
13777
  case "single-quoted-scalar":
13778
13778
  case "double-quoted-scalar": {
13779
- const fs11 = this.flowScalar(this.type);
13779
+ const fs12 = this.flowScalar(this.type);
13780
13780
  if (atNextItem || it.value) {
13781
- map.items.push({ start, key: fs11, sep: [] });
13781
+ map.items.push({ start, key: fs12, sep: [] });
13782
13782
  this.onKeyLine = true;
13783
13783
  } else if (it.sep) {
13784
- this.stack.push(fs11);
13784
+ this.stack.push(fs12);
13785
13785
  } else {
13786
- Object.assign(it, { key: fs11, sep: [] });
13786
+ Object.assign(it, { key: fs12, sep: [] });
13787
13787
  this.onKeyLine = true;
13788
13788
  }
13789
13789
  return;
@@ -13911,13 +13911,13 @@ var require_parser = __commonJS({
13911
13911
  case "scalar":
13912
13912
  case "single-quoted-scalar":
13913
13913
  case "double-quoted-scalar": {
13914
- const fs11 = this.flowScalar(this.type);
13914
+ const fs12 = this.flowScalar(this.type);
13915
13915
  if (!it || it.value)
13916
- fc.items.push({ start: [], key: fs11, sep: [] });
13916
+ fc.items.push({ start: [], key: fs12, sep: [] });
13917
13917
  else if (it.sep)
13918
- this.stack.push(fs11);
13918
+ this.stack.push(fs12);
13919
13919
  else
13920
- Object.assign(it, { key: fs11, sep: [] });
13920
+ Object.assign(it, { key: fs12, sep: [] });
13921
13921
  return;
13922
13922
  }
13923
13923
  case "flow-map-end":
@@ -14619,7 +14619,7 @@ var require_dist3 = __commonJS({
14619
14619
 
14620
14620
  // ../argent-mcp/src/mcp-server.ts
14621
14621
  import { appendFile, mkdir as mkdir5 } from "node:fs/promises";
14622
- import { dirname as dirname9 } from "node:path";
14622
+ import { dirname as dirname10 } from "node:path";
14623
14623
  import { homedir as homedir5 } from "node:os";
14624
14624
 
14625
14625
  // ../../node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
@@ -14862,10 +14862,10 @@ function mergeDefs(...defs) {
14862
14862
  function cloneDef(schema) {
14863
14863
  return mergeDefs(schema._zod.def);
14864
14864
  }
14865
- function getElementAtPath(obj, path16) {
14866
- if (!path16)
14865
+ function getElementAtPath(obj, path17) {
14866
+ if (!path17)
14867
14867
  return obj;
14868
- return path16.reduce((acc, key) => acc?.[key], obj);
14868
+ return path17.reduce((acc, key) => acc?.[key], obj);
14869
14869
  }
14870
14870
  function promiseAllObject(promisesObj) {
14871
14871
  const keys = Object.keys(promisesObj);
@@ -15205,11 +15205,11 @@ function explicitlyAborted(x, startIndex = 0) {
15205
15205
  }
15206
15206
  return false;
15207
15207
  }
15208
- function prefixIssues(path16, issues) {
15208
+ function prefixIssues(path17, issues) {
15209
15209
  return issues.map((iss) => {
15210
15210
  var _a3;
15211
15211
  (_a3 = iss).path ?? (_a3.path = []);
15212
- iss.path.unshift(path16);
15212
+ iss.path.unshift(path17);
15213
15213
  return iss;
15214
15214
  });
15215
15215
  }
@@ -15667,16 +15667,16 @@ function flattenError(error2, mapper = (issue2) => issue2.message) {
15667
15667
  }
15668
15668
  function formatError(error2, mapper = (issue2) => issue2.message) {
15669
15669
  const fieldErrors = { _errors: [] };
15670
- const processError = (error3, path16 = []) => {
15670
+ const processError = (error3, path17 = []) => {
15671
15671
  for (const issue2 of error3.issues) {
15672
15672
  if (issue2.code === "invalid_union" && issue2.errors.length) {
15673
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
15673
+ issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
15674
15674
  } else if (issue2.code === "invalid_key") {
15675
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15675
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
15676
15676
  } else if (issue2.code === "invalid_element") {
15677
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15677
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
15678
15678
  } else {
15679
- const fullpath = [...path16, ...issue2.path];
15679
+ const fullpath = [...path17, ...issue2.path];
15680
15680
  if (fullpath.length === 0) {
15681
15681
  fieldErrors._errors.push(mapper(issue2));
15682
15682
  } else {
@@ -17976,7 +17976,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
17976
17976
  var NONE = 0;
17977
17977
  var ASSUMED = 1;
17978
17978
  var PROVEN = 2;
17979
- function isRecursive(inst, stack, resolve9) {
17979
+ function isRecursive(inst, stack, resolve10) {
17980
17980
  const cached2 = recursive.get(inst);
17981
17981
  if (cached2 !== void 0)
17982
17982
  return cached2 ? PROVEN : NONE;
@@ -17986,7 +17986,7 @@ function isRecursive(inst, stack, resolve9) {
17986
17986
  let result = NONE;
17987
17987
  const check = (child) => {
17988
17988
  if (result !== PROVEN && child?._zod) {
17989
- const answer = isRecursive(child, stack, resolve9);
17989
+ const answer = isRecursive(child, stack, resolve10);
17990
17990
  if (answer > result)
17991
17991
  result = answer;
17992
17992
  }
@@ -17997,7 +17997,7 @@ function isRecursive(inst, stack, resolve9) {
17997
17997
  const desc = Object.getOwnPropertyDescriptor(sh, key);
17998
17998
  if (spread && !desc.enumerable)
17999
17999
  continue;
18000
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve9) : NONE;
18000
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve10) : NONE;
18001
18001
  if (child > answer)
18002
18002
  answer = child;
18003
18003
  }
@@ -18061,7 +18061,7 @@ function isRecursive(inst, stack, resolve9) {
18061
18061
  break;
18062
18062
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
18063
18063
  case "lazy": {
18064
- const inner = def._cachedInner ?? (resolve9 ? inst._zod.innerType : void 0);
18064
+ const inner = def._cachedInner ?? (resolve10 ? inst._zod.innerType : void 0);
18065
18065
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
18066
18066
  break;
18067
18067
  }
@@ -22639,12 +22639,12 @@ var StdioServerTransport = class {
22639
22639
  this.onclose?.();
22640
22640
  }
22641
22641
  send(message) {
22642
- return new Promise((resolve9) => {
22642
+ return new Promise((resolve10) => {
22643
22643
  const json = serializeMessage(message);
22644
22644
  if (this._stdout.write(json)) {
22645
- resolve9();
22645
+ resolve10();
22646
22646
  } else {
22647
- this._stdout.once("drain", resolve9);
22647
+ this._stdout.once("drain", resolve10);
22648
22648
  }
22649
22649
  });
22650
22650
  }
@@ -23264,7 +23264,7 @@ var Protocol = class {
23264
23264
  return;
23265
23265
  }
23266
23266
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
23267
- await new Promise((resolve9) => setTimeout(resolve9, pollInterval));
23267
+ await new Promise((resolve10) => setTimeout(resolve10, pollInterval));
23268
23268
  options?.signal?.throwIfAborted();
23269
23269
  }
23270
23270
  } catch (error2) {
@@ -23281,7 +23281,7 @@ var Protocol = class {
23281
23281
  */
23282
23282
  request(request, resultSchema, options) {
23283
23283
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
23284
- return new Promise((resolve9, reject) => {
23284
+ return new Promise((resolve10, reject) => {
23285
23285
  const earlyReject = (error2) => {
23286
23286
  reject(error2);
23287
23287
  };
@@ -23359,7 +23359,7 @@ var Protocol = class {
23359
23359
  if (!parseResult.success) {
23360
23360
  reject(parseResult.error);
23361
23361
  } else {
23362
- resolve9(parseResult.data);
23362
+ resolve10(parseResult.data);
23363
23363
  }
23364
23364
  } catch (error2) {
23365
23365
  reject(error2);
@@ -23621,12 +23621,12 @@ var Protocol = class {
23621
23621
  }
23622
23622
  } catch {
23623
23623
  }
23624
- return new Promise((resolve9, reject) => {
23624
+ return new Promise((resolve10, reject) => {
23625
23625
  if (signal.aborted) {
23626
23626
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
23627
23627
  return;
23628
23628
  }
23629
- const timeoutId = setTimeout(resolve9, interval);
23629
+ const timeoutId = setTimeout(resolve10, interval);
23630
23630
  signal.addEventListener("abort", () => {
23631
23631
  clearTimeout(timeoutId);
23632
23632
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -24442,7 +24442,7 @@ function generateToken() {
24442
24442
  return randomBytes(AUTH_TOKEN_BYTES).toString("hex");
24443
24443
  }
24444
24444
  function findFreePort() {
24445
- return new Promise((resolve9, reject) => {
24445
+ return new Promise((resolve10, reject) => {
24446
24446
  const srv = net.createServer();
24447
24447
  srv.listen(0, "127.0.0.1", () => {
24448
24448
  const addr = srv.address();
@@ -24453,7 +24453,7 @@ function findFreePort() {
24453
24453
  const port = addr.port;
24454
24454
  srv.close((err) => {
24455
24455
  if (err) reject(err);
24456
- else resolve9(port);
24456
+ else resolve10(port);
24457
24457
  });
24458
24458
  });
24459
24459
  srv.on("error", reject);
@@ -24551,7 +24551,7 @@ function killSpawnedChild(child, pid) {
24551
24551
  }
24552
24552
  }
24553
24553
  function spawnToolsServer(paths, port, options = {}) {
24554
- return new Promise((resolve9, reject) => {
24554
+ return new Promise((resolve10, reject) => {
24555
24555
  let logFd;
24556
24556
  try {
24557
24557
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -24597,7 +24597,7 @@ function spawnToolsServer(paths, port, options = {}) {
24597
24597
  rl.close();
24598
24598
  child.stdout?.resume();
24599
24599
  child.stdout?.unref?.();
24600
- settle2(() => resolve9({ port: actualPort, pid }));
24600
+ settle2(() => resolve10({ port: actualPort, pid }));
24601
24601
  }
24602
24602
  });
24603
24603
  child.on("error", (err) => {
@@ -24892,10 +24892,11 @@ async function ensureToolsServer(paths) {
24892
24892
  }
24893
24893
 
24894
24894
  // ../argent-tools-client/src/tools-client.ts
24895
- import * as path6 from "node:path";
24895
+ import * as path7 from "node:path";
24896
24896
 
24897
24897
  // ../registry/src/types.ts
24898
24898
  var LINKED_CALL_HEADER = "x-argent-linked";
24899
+ var E2E_DIR_CLIENT_HEADER = "x-argent-e2e-dir";
24899
24900
 
24900
24901
  // ../registry/src/artifacts.ts
24901
24902
  import { stat } from "node:fs/promises";
@@ -24933,19 +24934,95 @@ function toolStepFiles(specs, args) {
24933
24934
  }
24934
24935
  return files;
24935
24936
  }
24936
- function isClientFileArgument({ spec, path: path16 }) {
24937
- return spec.kind === "file" && spec.path === `\${${spec.target}}` && path16.startsWith("/") && hasToolFileExtension(path16);
24937
+ function isClientFileArgument({ spec, path: path17 }) {
24938
+ return spec.kind === "file" && spec.path === `\${${spec.target}}` && path17.startsWith("/") && hasToolFileExtension(path17);
24938
24939
  }
24939
24940
 
24940
24941
  // ../registry/src/flow-file-refs.ts
24942
+ import * as fs3 from "node:fs/promises";
24943
+ import * as path3 from "node:path";
24944
+
24945
+ // ../registry/src/e2e-dirs.ts
24941
24946
  import * as fs2 from "node:fs/promises";
24942
24947
  import * as path2 from "node:path";
24948
+ var E2E_DIR = path2.join(".argent", "e2e");
24949
+ var LEGACY_E2E_DIRS = Object.freeze([path2.join(".argent", "flows")]);
24950
+ var E2E_DIRS = Object.freeze([E2E_DIR, ...LEGACY_E2E_DIRS]);
24951
+ function e2eDirFor(projectRoot) {
24952
+ return path2.join(projectRoot, E2E_DIR);
24953
+ }
24954
+ function e2eDirsFor(projectRoot) {
24955
+ return E2E_DIRS.map((dir) => path2.join(projectRoot, dir));
24956
+ }
24957
+ function e2eFileCandidates(projectRoot, name) {
24958
+ return e2eDirsFor(projectRoot).map((dir) => path2.join(dir, `${name}.yaml`));
24959
+ }
24960
+ async function exists(file) {
24961
+ return fs2.stat(file).then(
24962
+ () => true,
24963
+ () => false
24964
+ );
24965
+ }
24966
+ async function pickE2eFile(candidates) {
24967
+ for (let i = 0; i < candidates.length; i++) {
24968
+ if (!await exists(candidates[i])) continue;
24969
+ let shadowed;
24970
+ for (const later of candidates.slice(i + 1)) {
24971
+ if (await exists(later)) {
24972
+ shadowed = later;
24973
+ break;
24974
+ }
24975
+ }
24976
+ return {
24977
+ path: candidates[i],
24978
+ exists: true,
24979
+ legacy: i > 0,
24980
+ ...shadowed === void 0 ? {} : { shadowed }
24981
+ };
24982
+ }
24983
+ return { path: candidates[0], exists: false, legacy: false };
24984
+ }
24985
+ function e2eShadowWarning(used, shadowed) {
24986
+ return `${shadowed} is not used: ${used} has the same name and is read first.`;
24987
+ }
24988
+ var E2E_DIR_NAMES = E2E_DIRS.map((dir) => path2.basename(dir));
24989
+ function e2eDirProject(dir) {
24990
+ const trimmed = dir.length > 1 ? dir.replace(/[\\/]+$/, "") : dir;
24991
+ const argent = path2.dirname(trimmed);
24992
+ if (!E2E_DIR_NAMES.includes(path2.basename(trimmed)) || path2.basename(argent) !== ".argent") {
24993
+ return null;
24994
+ }
24995
+ return path2.dirname(argent);
24996
+ }
24997
+ function e2eRunFallbackDirs(anchorDir, target) {
24998
+ if (target.includes("/") || target.includes("\\")) return [];
24999
+ const project = e2eDirProject(anchorDir);
25000
+ if (project === null) return [];
25001
+ const anchor2 = path2.resolve(anchorDir);
25002
+ return e2eDirsFor(project).filter((dir) => path2.resolve(dir) !== anchor2);
25003
+ }
25004
+
25005
+ // ../registry/src/tool-ids.ts
25006
+ var TOOL_ID_ALIASES = Object.freeze({
25007
+ "flow-start-recording": "e2e-start-recording",
25008
+ "flow-add-step": "e2e-add-step",
25009
+ "flow-add-echo": "e2e-add-echo",
25010
+ "flow-add-script": "e2e-add-script",
25011
+ "flow-finish-recording": "e2e-finish-recording",
25012
+ "flow-read-prerequisite": "e2e-read-prerequisite",
25013
+ "flow-execute": "e2e-execute"
25014
+ });
25015
+ function canonicalToolId(id) {
25016
+ return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
25017
+ }
25018
+
25019
+ // ../registry/src/flow-file-refs.ts
24943
25020
  async function canonicalFlowPath(p) {
24944
25021
  try {
24945
- return await fs2.realpath(p);
25022
+ return await fs3.realpath(p);
24946
25023
  } catch {
24947
25024
  try {
24948
- return path2.join(await fs2.realpath(path2.dirname(p)), path2.basename(p));
25025
+ return path3.join(await fs3.realpath(path3.dirname(p)), path3.basename(p));
24949
25026
  } catch {
24950
25027
  return p;
24951
25028
  }
@@ -24954,7 +25031,7 @@ async function canonicalFlowPath(p) {
24954
25031
  function completeRunExtension(value) {
24955
25032
  if (value.endsWith(".yaml")) return value;
24956
25033
  const candidate = `${value}.yaml`;
24957
- return FLOW_FILE_NAME_PATTERN.test(path2.posix.basename(candidate)) ? candidate : value;
25034
+ return FLOW_FILE_NAME_PATTERN.test(path3.posix.basename(candidate)) ? candidate : value;
24958
25035
  }
24959
25036
  var MAX_RUN_DEPTH = 20;
24960
25037
  var MAX_BLOCK_NESTING = 64;
@@ -24973,16 +25050,16 @@ function collectFlowRequests(doc) {
24973
25050
  for (const step of steps) {
24974
25051
  if (!isRecord(step)) continue;
24975
25052
  const run = step.run;
24976
- if (typeof run === "string" && !run.includes("\\") && !path2.posix.isAbsolute(run) && !/^[A-Za-z]:/.test(run)) {
25053
+ if (typeof run === "string" && !run.includes("\\") && !path3.posix.isAbsolute(run) && !/^[A-Za-z]:/.test(run)) {
24977
25054
  const target = completeRunExtension(run);
24978
- if (FLOW_FILE_NAME_PATTERN.test(path2.posix.basename(target))) runTargets.add(target);
25055
+ if (FLOW_FILE_NAME_PATTERN.test(path3.posix.basename(target))) runTargets.add(target);
24979
25056
  }
24980
25057
  const snapshot = isRecord(step.snapshot) ? step.snapshot.name : step.snapshot;
24981
25058
  if (typeof snapshot === "string" && FLOW_NAME_PATTERN.test(snapshot)) snapshots.add(snapshot);
24982
25059
  if (typeof step.tool === "string") {
24983
25060
  const args = isRecord(step.args) ? step.args : {};
24984
25061
  toolSteps.push({ tool: step.tool, args });
24985
- const target = step.tool === "flow-execute" ? nestedFlowTarget(args) : void 0;
25062
+ const target = canonicalToolId(step.tool) === "e2e-execute" ? nestedFlowTarget(args) : void 0;
24986
25063
  if (target !== void 0) nested.push({ target, args });
24987
25064
  }
24988
25065
  visit(step.steps, depth + 1);
@@ -24992,14 +25069,14 @@ function collectFlowRequests(doc) {
24992
25069
  return { runTargets: [...runTargets], snapshots: [...snapshots], toolSteps, nested };
24993
25070
  }
24994
25071
  function baselineKeyFor(canonicalPath, flowName) {
24995
- const stem = path2.basename(canonicalPath, ".yaml");
25072
+ const stem = path3.basename(canonicalPath, ".yaml");
24996
25073
  return FLOW_NAME_PATTERN.test(stem) ? stem : flowName;
24997
25074
  }
24998
25075
  function flowMemberKey(anchorDir, target) {
24999
25076
  return `${anchorDir}\0${target}`;
25000
25077
  }
25001
25078
  async function classifyOnDiskSpelling(dir, base, addressable = FLOW_FILE_NAME_PATTERN) {
25002
- const entries = await fs2.readdir(dir).catch(() => null);
25079
+ const entries = await fs3.readdir(dir).catch(() => null);
25003
25080
  if (entries === null || entries.includes(base)) return { state: "listed" };
25004
25081
  const actual = entries.find((entry) => entry.toLowerCase() === base.toLowerCase());
25005
25082
  if (actual === void 0) return { state: "absent" };
@@ -25011,19 +25088,15 @@ function nestedFlowTarget(args) {
25011
25088
  if (flowPath === void 0) {
25012
25089
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
25013
25090
  if (!isResolvedAbsolute(projectRoot)) return void 0;
25014
- return {
25015
- kind: "name",
25016
- projectRoot,
25017
- name,
25018
- path: path2.join(projectRoot, ".argent", "flows", `${name}.yaml`)
25019
- };
25091
+ const paths = e2eFileCandidates(projectRoot, name);
25092
+ return { kind: "name", projectRoot, name, path: paths[0], paths };
25020
25093
  }
25021
25094
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
25022
- if (!FLOW_FILE_NAME_PATTERN.test(path2.basename(flowPath))) return void 0;
25095
+ if (!FLOW_FILE_NAME_PATTERN.test(path3.basename(flowPath))) return void 0;
25023
25096
  return { kind: "flow_path", path: flowPath };
25024
25097
  }
25025
25098
  function isResolvedAbsolute(value) {
25026
- return typeof value === "string" && path2.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
25099
+ return typeof value === "string" && path3.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
25027
25100
  }
25028
25101
 
25029
25102
  // ../registry/src/failure-codes.ts
@@ -25392,9 +25465,9 @@ var FAILURE_SPAWN_CODE_SET = new Set(FAILURE_SPAWN_CODES);
25392
25465
  import { randomUUID as randomUUID2 } from "node:crypto";
25393
25466
  import { AsyncLocalStorage } from "node:async_hooks";
25394
25467
  var resolvedDuringInvocation = new AsyncLocalStorage();
25395
- function valueAtPath(root, path16) {
25468
+ function valueAtPath(root, path17) {
25396
25469
  let current = root;
25397
- for (const key of path16) {
25470
+ for (const key of path17) {
25398
25471
  if (current === null || typeof current !== "object") return void 0;
25399
25472
  if (!Object.hasOwn(current, key)) return void 0;
25400
25473
  current = current[key];
@@ -25452,11 +25525,11 @@ function describeParamIssues(error2, params) {
25452
25525
  }
25453
25526
 
25454
25527
  // ../argent-tools-client/src/link-config.ts
25455
- import * as path3 from "node:path";
25528
+ import * as path4 from "node:path";
25456
25529
  import { homedir as homedir2 } from "node:os";
25457
25530
  import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2, chmod as chmod2 } from "node:fs/promises";
25458
- var LINK_DIR = path3.join(homedir2(), ".argent");
25459
- var LINK_FILE = path3.join(LINK_DIR, "link.json");
25531
+ var LINK_DIR = path4.join(homedir2(), ".argent");
25532
+ var LINK_FILE = path4.join(LINK_DIR, "link.json");
25460
25533
  async function readLinkConfig() {
25461
25534
  try {
25462
25535
  const raw = await readFile2(LINK_FILE, "utf8");
@@ -25505,22 +25578,22 @@ import {
25505
25578
  realpath as realpath2,
25506
25579
  rename as rename2,
25507
25580
  rm as rm2,
25508
- stat as stat2,
25581
+ stat as stat3,
25509
25582
  writeFile as writeFile3
25510
25583
  } from "node:fs/promises";
25511
25584
  import { constants, tmpdir } from "node:os";
25512
- import * as path4 from "node:path";
25585
+ import * as path5 from "node:path";
25513
25586
 
25514
25587
  // ../archive/src/index.ts
25515
25588
  import { execFile } from "node:child_process";
25516
25589
  import { rm, readdir as readdir3 } from "node:fs/promises";
25517
- import { basename as basename3, dirname as dirname3, join as join4, posix as posix2, resolve as resolve2, sep as sep2 } from "node:path";
25590
+ import { basename as basename4, dirname as dirname4, join as join5, posix as posix2, resolve as resolve3, sep as sep2 } from "node:path";
25518
25591
  import { promisify } from "node:util";
25519
25592
  var execFileAsync = promisify(execFile);
25520
25593
  var ArchiveError = class extends Error {
25521
25594
  };
25522
25595
  function createTarGzArgs(sourcePath, target) {
25523
- return ["-czf", target, "-C", dirname3(sourcePath), basename3(sourcePath)];
25596
+ return ["-czf", target, "-C", dirname4(sourcePath), basename4(sourcePath)];
25524
25597
  }
25525
25598
  async function createTarGzFile(sourcePath, tarPath) {
25526
25599
  try {
@@ -25542,8 +25615,8 @@ function isSafeTarMember(memberPath, destDir) {
25542
25615
  if (relative2 === ".." || relative2.startsWith("../") || relative2.split("/").includes("..")) {
25543
25616
  return false;
25544
25617
  }
25545
- const root = resolve2(destDir);
25546
- const resolved = resolve2(destDir, relative2);
25618
+ const root = resolve3(destDir);
25619
+ const resolved = resolve3(destDir, relative2);
25547
25620
  return resolved === root || resolved.startsWith(root + sep2);
25548
25621
  }
25549
25622
  async function listTarMembers(tarPath) {
@@ -25597,7 +25670,7 @@ async function assertSafeArchive(tarPath, destDir) {
25597
25670
  async function resolveMember(destDir, expectedName) {
25598
25671
  const entries = await readdir3(destDir);
25599
25672
  if (entries.includes(expectedName)) {
25600
- return join4(destDir, expectedName);
25673
+ return join5(destDir, expectedName);
25601
25674
  }
25602
25675
  const real = entries.filter((e) => !e.startsWith("._"));
25603
25676
  if (real.length !== 1) {
@@ -25605,7 +25678,7 @@ async function resolveMember(destDir, expectedName) {
25605
25678
  `Could not identify the extracted member (expected "${expectedName}", found ${real.length} entries).`
25606
25679
  );
25607
25680
  }
25608
- return join4(destDir, real[0]);
25681
+ return join5(destDir, real[0]);
25609
25682
  }
25610
25683
  async function safeExtractTarGz(tarPath, destDir, expectedName) {
25611
25684
  await assertSafeArchive(tarPath, destDir);
@@ -25643,6 +25716,16 @@ function interpolatePath(template, args) {
25643
25716
  });
25644
25717
  return missing ? null : out;
25645
25718
  }
25719
+ async function specPath(spec, args) {
25720
+ if (spec.kind !== "file" || !spec.paths?.length) return interpolatePath(spec.path, args);
25721
+ const candidates = [];
25722
+ for (const template of spec.paths) {
25723
+ const filled = interpolatePath(template, args);
25724
+ if (filled === null) return null;
25725
+ candidates.push(filled);
25726
+ }
25727
+ return (await pickE2eFile(candidates)).path;
25728
+ }
25646
25729
  var pendingArchives = /* @__PURE__ */ new Set();
25647
25730
  var ARCHIVE_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
25648
25731
  function removePendingArchives() {
@@ -25678,9 +25761,9 @@ function untrackArchive(archive) {
25678
25761
  process.removeListener("exit", removePendingArchives);
25679
25762
  }
25680
25763
  function sha256File(filePath) {
25681
- return new Promise((resolve9, reject) => {
25764
+ return new Promise((resolve10, reject) => {
25682
25765
  const hash = createHash2("sha256");
25683
- createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
25766
+ createReadStream(filePath).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve10(hash.digest("hex"))).on("error", reject);
25684
25767
  });
25685
25768
  }
25686
25769
  function toolServerError(text) {
@@ -25707,7 +25790,7 @@ function uploadFailure(url, res, text, bytes) {
25707
25790
  });
25708
25791
  }
25709
25792
  async function uploadTar(tarPath, endpoint, signal) {
25710
- const { size } = await stat2(tarPath);
25793
+ const { size } = await stat3(tarPath);
25711
25794
  const init = {
25712
25795
  method: "POST",
25713
25796
  headers: {
@@ -25731,7 +25814,7 @@ async function uploadTar(tarPath, endpoint, signal) {
25731
25814
  return json.uploadId;
25732
25815
  }
25733
25816
  async function uploadFile(sourcePath, endpoint, signal) {
25734
- const tarPath = path4.join(tmpdir(), `argent-upload-${randomUUID3()}.tar.gz`);
25817
+ const tarPath = path5.join(tmpdir(), `argent-upload-${randomUUID3()}.tar.gz`);
25735
25818
  trackArchive(tarPath);
25736
25819
  try {
25737
25820
  await createTarGzFile(await realpath2(sourcePath), tarPath);
@@ -25746,7 +25829,7 @@ async function uploadFile(sourcePath, endpoint, signal) {
25746
25829
  async function readFileInputWire(filePath, opts) {
25747
25830
  let st;
25748
25831
  try {
25749
- st = await stat2(filePath);
25832
+ st = await stat3(filePath);
25750
25833
  } catch {
25751
25834
  return null;
25752
25835
  }
@@ -25774,7 +25857,7 @@ async function prepareFileInputs(specs, args, opts) {
25774
25857
  for (const spec of specs) {
25775
25858
  if (spec.skipWhenSet && record2[spec.skipWhenSet] !== void 0) continue;
25776
25859
  if (spec.target in record2 && typeof record2[spec.target] !== "string") continue;
25777
- const filePath = interpolatePath(spec.path, record2);
25860
+ const filePath = await specPath(spec, record2);
25778
25861
  if (filePath === null) continue;
25779
25862
  if (spec.target in record2 && record2[spec.target] !== filePath) continue;
25780
25863
  const wire = { [FILE_INPUT_MARKER2]: true, path: filePath };
@@ -25792,13 +25875,13 @@ async function prepareFileInputs(specs, args, opts) {
25792
25875
  wire.members = await opts.collectStepMembers(record2, opts);
25793
25876
  }
25794
25877
  if (spec.kind === "tar-upload") {
25795
- const st = await stat2(filePath).catch(() => null);
25878
+ const st = await stat3(filePath).catch(() => null);
25796
25879
  if (st) {
25797
25880
  wire.size = st.size;
25798
25881
  wire.mtimeMs = st.mtimeMs;
25799
25882
  }
25800
25883
  if (opts.uploadEndpoint && st) {
25801
- process.stderr.write(`Uploading ${path4.basename(filePath)} to the remote tool-server...
25884
+ process.stderr.write(`Uploading ${path5.basename(filePath)} to the remote tool-server...
25802
25885
  `);
25803
25886
  Object.assign(wire, await uploadFile(filePath, opts.uploadEndpoint, opts.signal));
25804
25887
  }
@@ -25809,18 +25892,18 @@ async function prepareFileInputs(specs, args, opts) {
25809
25892
  return out ?? args;
25810
25893
  }
25811
25894
  function isAllowedClientFilePath(p) {
25812
- if (!path4.isAbsolute(p)) return false;
25895
+ if (!path5.isAbsolute(p)) return false;
25813
25896
  const segments = p.split(/[\\/]+/);
25814
25897
  if (segments.includes("..")) return false;
25815
25898
  const file = segments[segments.length - 1] ?? "";
25816
25899
  if (!FLOW_FILE_NAME_PATTERN.test(file)) return false;
25817
- return segments[segments.length - 3] === ".argent" && segments[segments.length - 2] === "flows";
25900
+ return e2eDirProject(segments.slice(0, -1).join("/")) !== null;
25818
25901
  }
25819
25902
  function isClientFileDirective2(value) {
25820
25903
  return !!value && typeof value === "object" && value[CLIENT_FILE_MARKER2] === true && typeof value.path === "string" && typeof value.content === "string";
25821
25904
  }
25822
25905
  async function replaceFile(target, bytes, mode) {
25823
- const temp = path4.join(path4.dirname(target), `.baseline-${randomUUID3()}.tmp`);
25906
+ const temp = path5.join(path5.dirname(target), `.baseline-${randomUUID3()}.tmp`);
25824
25907
  try {
25825
25908
  await writeFile3(temp, bytes, { flag: "wx" });
25826
25909
  if (mode !== void 0) await chmod3(temp, mode & 511);
@@ -25831,27 +25914,27 @@ async function replaceFile(target, bytes, mode) {
25831
25914
  }
25832
25915
  }
25833
25916
  async function writeBaselineFile(file, bytes, allowedDirs) {
25834
- if (!path4.isAbsolute(file) || path4.normalize(file) !== file || file.split(/[\\/]/).includes("..") || !file.endsWith(".png") || !allowedDirs.includes(path4.dirname(file))) {
25917
+ if (!path5.isAbsolute(file) || path5.normalize(file) !== file || file.split(/[\\/]/).includes("..") || !file.endsWith(".png") || !allowedDirs.includes(path5.dirname(file))) {
25835
25918
  return allowedDirs.length === 0 ? "this call writes no baselines" : `${file} is not a baseline of this call (${allowedDirs.map((d) => `${d}/<name>.png`).join(", ")})`;
25836
25919
  }
25837
25920
  if (bytes.length > MAX_CONTENT_BYTES) {
25838
25921
  return `${file}: the baseline is larger than the 32 MiB cap on a file this client writes`;
25839
25922
  }
25840
- const dir = path4.dirname(file);
25923
+ const dir = path5.dirname(file);
25841
25924
  await mkdir3(dir, { recursive: true });
25842
25925
  const link = await lstat(file).catch(() => null);
25843
25926
  const real = link === null ? null : await realpath2(file).catch(() => null);
25844
25927
  if (link !== null && real === null) return `${file} is a symbolic link to a missing file`;
25845
25928
  if (real !== null) {
25846
25929
  if (!real.endsWith(".png")) return `${file} links to a file that is not a PNG file`;
25847
- if (path4.dirname(real) !== await realpath2(dir)) {
25930
+ if (path5.dirname(real) !== await realpath2(dir)) {
25848
25931
  return `${file} links outside its baseline directory`;
25849
25932
  }
25850
25933
  }
25851
- const existing = real === null ? null : await stat2(real);
25934
+ const existing = real === null ? null : await stat3(real);
25852
25935
  if (existing !== null && !existing.isFile()) return `${file} is not a regular file`;
25853
25936
  await replaceFile(
25854
- real ?? path4.join(await realpath2(dir), path4.basename(file)),
25937
+ real ?? path5.join(await realpath2(dir), path5.basename(file)),
25855
25938
  bytes,
25856
25939
  existing?.mode
25857
25940
  );
@@ -25877,7 +25960,7 @@ async function applyClientFileDirectives(result, opts = {}) {
25877
25960
  if (isClientFileDirective2(value)) {
25878
25961
  if (!isAllowedClientFilePath(value.path)) return null;
25879
25962
  try {
25880
- await mkdir3(path4.dirname(value.path), { recursive: true });
25963
+ await mkdir3(path5.dirname(value.path), { recursive: true });
25881
25964
  await writeFile3(value.path, value.content, "utf8");
25882
25965
  written.push(value.path);
25883
25966
  return value.path;
@@ -25905,12 +25988,14 @@ async function applyClientFileDirectives(result, opts = {}) {
25905
25988
 
25906
25989
  // ../argent-tools-client/src/flow-files.ts
25907
25990
  var import_yaml = __toESM(require_dist2(), 1);
25908
- import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat3 } from "node:fs/promises";
25909
- import * as path5 from "node:path";
25991
+ import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat4 } from "node:fs/promises";
25992
+ import * as path6 from "node:path";
25910
25993
  var INLINE_MEMBERS_BYTES = 256 * 1024;
25911
- var FLOW_FILES_LOG_ENV = "ARGENT_FLOW_FILES_LOG";
25994
+ function filesLogEnabled() {
25995
+ return (process.env.ARGENT_E2E_FILES_LOG ?? process.env.ARGENT_FLOW_FILES_LOG) === "1";
25996
+ }
25912
25997
  function isWithin(inner, outer) {
25913
- return inner === outer || inner.startsWith(outer.endsWith(path5.sep) ? outer : outer + path5.sep);
25998
+ return inner === outer || inner.startsWith(outer.endsWith(path6.sep) ? outer : outer + path6.sep);
25914
25999
  }
25915
26000
  function printable(text) {
25916
26001
  return [...text].map(
@@ -25918,23 +26003,21 @@ function printable(text) {
25918
26003
  ).join("");
25919
26004
  }
25920
26005
  function isResolvedAbsolute2(value) {
25921
- return typeof value === "string" && path5.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
26006
+ return typeof value === "string" && path6.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
25922
26007
  }
25923
26008
  function namesValidFlow(args) {
25924
26009
  const { project_root, flow_path, name } = args;
25925
26010
  if (!isResolvedAbsolute2(project_root)) return false;
25926
26011
  if (name === void 0) {
25927
- return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path5.basename(flow_path));
26012
+ return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path6.basename(flow_path));
25928
26013
  }
25929
26014
  return flow_path === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
25930
26015
  }
25931
26016
  function savedFlowProject(file) {
25932
- if (!path5.isAbsolute(file)) return null;
25933
- const parts = file.split(path5.sep);
25934
- for (let i = parts.length - 3; i >= 0; i--) {
25935
- if (parts[i] === ".argent" && parts[i + 1] === "flows") {
25936
- return parts.slice(0, i).join(path5.sep) || path5.sep;
25937
- }
26017
+ if (!path6.isAbsolute(file)) return null;
26018
+ for (let dir = path6.dirname(file); dir !== path6.dirname(dir); dir = path6.dirname(dir)) {
26019
+ const project = e2eDirProject(dir);
26020
+ if (project !== null) return project;
25938
26021
  }
25939
26022
  return null;
25940
26023
  }
@@ -25947,11 +26030,11 @@ async function landing(spelled) {
25947
26030
  const canonical = await canonicalFlowPath(spelled);
25948
26031
  let at = spelled;
25949
26032
  for (; ; ) {
25950
- const parent = path5.dirname(at);
26033
+ const parent = path6.dirname(at);
25951
26034
  if (parent === at) return { canonical, fence: spelled, ...failure2 };
25952
26035
  const real = await realpath3(parent).catch(() => null);
25953
26036
  if (real !== null) {
25954
- return { canonical, fence: path5.join(real, path5.basename(at)), ...failure2 };
26037
+ return { canonical, fence: path6.join(real, path6.basename(at)), ...failure2 };
25955
26038
  }
25956
26039
  at = parent;
25957
26040
  }
@@ -25959,10 +26042,10 @@ async function landing(spelled) {
25959
26042
  }
25960
26043
  async function closureRoots(rootPath, rootCanonical, projectRoot) {
25961
26044
  const candidates = [];
25962
- if (typeof projectRoot === "string" && path5.isAbsolute(projectRoot)) {
25963
- candidates.push(projectRoot, path5.join(projectRoot, ".argent", "flows"));
26045
+ if (typeof projectRoot === "string" && path6.isAbsolute(projectRoot)) {
26046
+ candidates.push(projectRoot, ...e2eDirsFor(projectRoot));
25964
26047
  }
25965
- candidates.push(path5.dirname(rootPath), path5.dirname(rootCanonical));
26048
+ candidates.push(path6.dirname(rootPath), path6.dirname(rootCanonical));
25966
26049
  for (const file of [rootPath, rootCanonical]) {
25967
26050
  const project = savedFlowProject(file);
25968
26051
  if (project !== null) candidates.push(project);
@@ -25975,11 +26058,11 @@ async function closureRoots(rootPath, rootCanonical, projectRoot) {
25975
26058
  return real.filter((root) => !real.some((other) => other !== root && isWithin(root, other)));
25976
26059
  }
25977
26060
  async function readFlowMember(anchorDir, target, roots, budget, opts) {
25978
- const spelled = anchorDir + path5.sep + target;
26061
+ const spelled = anchorDir + path6.sep + target;
25979
26062
  const { canonical, fence, missing, error: error2 } = await landing(spelled);
25980
26063
  const spelling = await classifyOnDiskSpelling(
25981
- path5.dirname(spelled),
25982
- path5.posix.basename(target),
26064
+ path6.dirname(spelled),
26065
+ path6.posix.basename(target),
25983
26066
  FLOW_FILE_NAME_PATTERN
25984
26067
  );
25985
26068
  const member = {
@@ -25998,13 +26081,13 @@ async function readFlowMember(anchorDir, target, roots, budget, opts) {
25998
26081
  }
25999
26082
  if (error2 !== void 0) return refuse(error2);
26000
26083
  if (missing) return { member: { ...member, state: "missing" }, sent: "missing" };
26001
- const st = await stat3(canonical).catch((err) => err);
26084
+ const st = await stat4(canonical).catch((err) => err);
26002
26085
  if (st instanceof Error) {
26003
26086
  if (st.code !== "ENOENT") return refuse(st.message);
26004
26087
  return { member: { ...member, state: "missing" }, sent: "missing" };
26005
26088
  }
26006
26089
  if (st.isDirectory()) return refuse("EISDIR: illegal operation on a directory, read");
26007
- if (!/\.ya?ml$/i.test(path5.basename(canonical))) {
26090
+ if (!/\.ya?ml$/i.test(path6.basename(canonical))) {
26008
26091
  return refuse(`${target} links to a file that is not a YAML file`);
26009
26092
  }
26010
26093
  const sent = await sendBytes(member, canonical, budget, opts);
@@ -26023,7 +26106,7 @@ async function readToolMember(file, roots, budget, opts) {
26023
26106
  if (!hasToolFileExtension(canonical)) {
26024
26107
  return refuse(`${file} links to a file that is not one of ${TOOL_FILE_EXTENSIONS.join(", ")}`);
26025
26108
  }
26026
- const st = await stat3(canonical).catch((err) => err);
26109
+ const st = await stat4(canonical).catch((err) => err);
26027
26110
  if (st instanceof Error) {
26028
26111
  if (st.code === "ENOENT" || st.code === "ENOTDIR") {
26029
26112
  return { member: { ...member, state: "missing" }, sent: "missing" };
@@ -26047,7 +26130,7 @@ async function baselineEntry(file, roots, forWrite) {
26047
26130
  };
26048
26131
  }
26049
26132
  if (error2 !== void 0) return { state: "refused", error: error2 };
26050
- const st = await stat3(canonical).catch((err) => err);
26133
+ const st = await stat4(canonical).catch((err) => err);
26051
26134
  if (st instanceof Error) {
26052
26135
  if (st.code !== "ENOENT") return { state: "refused", error: st.message };
26053
26136
  return forWrite ? { state: "refused", error: `${file} is a symbolic link to a missing file` } : { state: "missing" };
@@ -26097,7 +26180,7 @@ function memberCollector(roots, opts) {
26097
26180
  const runs = /* @__PURE__ */ new Set();
26098
26181
  const baselineDirs = /* @__PURE__ */ new Map();
26099
26182
  const budget = { inline: 0 };
26100
- const logging = process.env[FLOW_FILES_LOG_ENV] === "1";
26183
+ const logging = filesLogEnabled();
26101
26184
  const log = opts.log ?? ((line) => void process.stderr.write(`${line}
26102
26185
  `));
26103
26186
  const emit = (member, sent) => {
@@ -26105,18 +26188,19 @@ function memberCollector(roots, opts) {
26105
26188
  const subject = member.role === "flow" ? member.canonical : member.key;
26106
26189
  if (logging) log(printable(`[flow-files] ${member.role} ${subject}: ${sent}`));
26107
26190
  };
26108
- async function flow(anchorDir, target) {
26191
+ async function flow(anchorDir, target, onlyPresent) {
26109
26192
  const key = flowMemberKey(anchorDir, target);
26110
26193
  const known = flows.get(key);
26111
- if (known !== void 0) return known;
26194
+ if (known !== void 0) return onlyPresent && known.text === void 0 ? void 0 : known;
26112
26195
  const { member, text, sent } = await readFlowMember(anchorDir, target, roots, budget, opts);
26196
+ if (onlyPresent && text === void 0) return void 0;
26113
26197
  const entry = { member, ...text === void 0 ? {} : { text } };
26114
26198
  flows.set(key, entry);
26115
26199
  emit(member, sent);
26116
26200
  return entry;
26117
26201
  }
26118
26202
  async function toolFiles(step) {
26119
- if (step.tool === "flow-execute") return;
26203
+ if (canonicalToolId(step.tool) === "e2e-execute") return;
26120
26204
  for (const file of toolStepFiles(opts.toolFileInputs?.(step.tool), step.args)) {
26121
26205
  const { unwrapWhenSet } = file.spec;
26122
26206
  if (unwrapWhenSet !== void 0 && step.args[unwrapWhenSet] !== void 0) continue;
@@ -26126,11 +26210,31 @@ function memberCollector(roots, opts) {
26126
26210
  emit(read.member, read.sent);
26127
26211
  }
26128
26212
  }
26213
+ async function savedTest(target) {
26214
+ for (const candidate of target.paths) {
26215
+ const found = await flow(path6.dirname(candidate), path6.basename(candidate), true);
26216
+ if (found !== void 0) return found;
26217
+ }
26218
+ let first;
26219
+ for (const candidate of target.paths) {
26220
+ first ??= await flow(path6.dirname(candidate), path6.basename(candidate));
26221
+ }
26222
+ return first;
26223
+ }
26129
26224
  async function nestedRun(target, hop, updates, platform) {
26130
- const { member, text } = await flow(path5.dirname(target.path), `${target.name}.yaml`);
26225
+ const { member, text } = await savedTest(target);
26131
26226
  if (text === void 0 || hop >= MAX_RUN_DEPTH) return void 0;
26132
26227
  return { canonical: member.canonical, text, flowName: target.name, hop, updates, platform };
26133
26228
  }
26229
+ async function runTarget(anchorDir, target) {
26230
+ const found = await flow(anchorDir, target);
26231
+ if (found.member.spelling?.state !== "absent") return found;
26232
+ for (const dir of e2eRunFallbackDirs(anchorDir, target)) {
26233
+ const other = await flow(dir, target, true);
26234
+ if (other !== void 0) return other;
26235
+ }
26236
+ return found;
26237
+ }
26134
26238
  async function walk(start) {
26135
26239
  const queue = [...start];
26136
26240
  for (let run = queue.shift(); run !== void 0; run = queue.shift()) {
@@ -26150,12 +26254,12 @@ function memberCollector(roots, opts) {
26150
26254
  const requests = collectFlowRequests(doc);
26151
26255
  for (const name of requests.snapshots) snapshots.add(name);
26152
26256
  for (const step of requests.toolSteps) await toolFiles(step);
26153
- const anchorDir = path5.dirname(file.canonical);
26257
+ const anchorDir = path6.dirname(file.canonical);
26154
26258
  for (const target of requests.runTargets) {
26155
26259
  const key = flowMemberKey(anchorDir, target);
26156
26260
  if (visited.has(key)) continue;
26157
26261
  visited.add(key);
26158
- const { member, text } = await flow(anchorDir, target);
26262
+ const { member, text } = await runTarget(anchorDir, target);
26159
26263
  if (text !== void 0 && file.hop + 1 < MAX_RUN_DEPTH) {
26160
26264
  files.push({ canonical: member.canonical, text, hop: file.hop + 1 });
26161
26265
  }
@@ -26172,8 +26276,8 @@ function memberCollector(roots, opts) {
26172
26276
  }
26173
26277
  }
26174
26278
  if (snapshots.size === 0) continue;
26175
- const dir = path5.join(
26176
- path5.dirname(run.canonical),
26279
+ const dir = path6.join(
26280
+ path6.dirname(run.canonical),
26177
26281
  "__baselines__",
26178
26282
  baselineKeyFor(run.canonical, run.flowName)
26179
26283
  );
@@ -26197,7 +26301,7 @@ function memberCollector(roots, opts) {
26197
26301
  if (!name.endsWith(".png")) continue;
26198
26302
  const compared = [...prefixes].some((prefix) => name.startsWith(prefix));
26199
26303
  if (!updates && !compared) continue;
26200
- const file = path5.join(dir, name);
26304
+ const file = path6.join(dir, name);
26201
26305
  if (tools.has(file)) continue;
26202
26306
  const member = { role: "baseline", key: file, path: file };
26203
26307
  const entry = await baselineEntry(file, roots, updates && !compared);
@@ -26220,8 +26324,8 @@ async function collectFlowMembers(rootPath, rootBytes, args, opts) {
26220
26324
  if (!namesValidFlow(args)) return {};
26221
26325
  const canonical = await canonicalFlowPath(rootPath);
26222
26326
  const spelling = await classifyOnDiskSpelling(
26223
- path5.dirname(rootPath),
26224
- path5.basename(rootPath),
26327
+ path6.dirname(rootPath),
26328
+ path6.basename(rootPath),
26225
26329
  FLOW_FILE_NAME_PATTERN
26226
26330
  );
26227
26331
  const collector = memberCollector(
@@ -26232,7 +26336,7 @@ async function collectFlowMembers(rootPath, rootBytes, args, opts) {
26232
26336
  {
26233
26337
  canonical,
26234
26338
  text: rootBytes.toString("utf8"),
26235
- flowName: path5.basename(rootPath, ".yaml"),
26339
+ flowName: path6.basename(rootPath, ".yaml"),
26236
26340
  hop: 0,
26237
26341
  updates: args.updateBaselines === true,
26238
26342
  platform: callPlatform(args)
@@ -26255,33 +26359,37 @@ function recordedStep(args) {
26255
26359
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
26256
26360
  return { tool: command, args: parsed };
26257
26361
  }
26258
- async function collectStepMembers(args, opts) {
26362
+ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
26259
26363
  const { name, project_root: projectRoot } = args;
26260
26364
  const step = recordedStep(args);
26261
- if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path5.isAbsolute(projectRoot) || step === void 0) {
26365
+ if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path6.isAbsolute(projectRoot) || step === void 0) {
26262
26366
  return [];
26263
26367
  }
26264
- const recording = path5.join(projectRoot, ".argent", "flows", `${name}.yaml`);
26368
+ const recording = path6.join(recordingDirFor(projectRoot), `${name}.yaml`);
26265
26369
  const collector = memberCollector(
26266
26370
  await closureRoots(recording, (await landing(recording)).canonical, projectRoot),
26267
26371
  opts
26268
26372
  );
26269
26373
  await collector.toolFiles(step);
26270
- if (step.tool === "flow-execute") {
26271
- const self = await collector.flow(path5.dirname(recording), path5.basename(recording));
26374
+ if (canonicalToolId(step.tool) === "e2e-execute") {
26375
+ const self = await collector.flow(path6.dirname(recording), path6.basename(recording));
26272
26376
  let runArgs = step.args;
26273
26377
  const named = nestedFlowTarget(runArgs);
26274
26378
  if (named?.kind === "flow_path") {
26275
- const stem = path5.basename(named.path, ".yaml");
26276
- if (path5.resolve(path5.dirname(named.path)) === path5.resolve(path5.dirname(recording))) {
26277
- await collector.flow(path5.dirname(recording), path5.basename(named.path));
26379
+ const stem = path6.basename(named.path, ".yaml");
26380
+ const base = path6.basename(named.path);
26381
+ const dir = path6.resolve(path6.dirname(named.path));
26382
+ const recordingDir = path6.dirname(recording);
26383
+ const dirs = [recordingDir, ...e2eRunFallbackDirs(recordingDir, base)];
26384
+ if (dirs.some((d) => path6.resolve(d) === dir)) {
26385
+ await collector.flow(path6.dirname(named.path), base);
26278
26386
  runArgs = { ...runArgs, name: stem };
26279
26387
  delete runArgs.flow_path;
26280
26388
  }
26281
26389
  }
26282
26390
  const target = nestedFlowTarget(runArgs);
26283
26391
  if (target?.kind === "name") {
26284
- await collector.flow(path5.dirname(self.member.canonical), `${target.name}.yaml`);
26392
+ await collector.flow(path6.dirname(self.member.canonical), `${target.name}.yaml`);
26285
26393
  const run = await collector.nestedRun(
26286
26394
  target,
26287
26395
  0,
@@ -26294,6 +26402,43 @@ async function collectStepMembers(args, opts) {
26294
26402
  await collector.sendBaselines();
26295
26403
  return collector.members;
26296
26404
  }
26405
+ async function nameToE2ePathForOlderServer(tool, fileInputs, args) {
26406
+ const id = canonicalToolId(tool);
26407
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return args;
26408
+ const spec = fileInputs?.find((s) => s.target === "flow_file");
26409
+ if (spec === void 0 || spec.kind !== "file" || spec.paths?.length) return args;
26410
+ const target = nestedFlowTarget(args);
26411
+ if (target?.kind !== "name") return args;
26412
+ const picked = await pickE2eFile(target.paths);
26413
+ if (!picked.exists || picked.legacy) return args;
26414
+ const { name: _name, ...rest } = args;
26415
+ return { ...rest, flow_path: picked.path };
26416
+ }
26417
+ async function stepForOlderServer(args, listedId) {
26418
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
26419
+ const record2 = args;
26420
+ if (typeof record2.command !== "string") return args;
26421
+ const command = listedId(record2.command) ?? record2.command;
26422
+ const step = recordedStep({ ...record2, command });
26423
+ const target = step && canonicalToolId(step.tool) === "e2e-execute" && nestedFlowTarget(step.args);
26424
+ if (target && target.kind === "name") {
26425
+ const picked = await pickE2eFile(target.paths);
26426
+ if (picked.exists && !picked.legacy) {
26427
+ throw new Error(
26428
+ `Cannot record a nested ${record2.command} of "${target.name}": the tool-server runs an older argent that records and runs nested e2e tests only from .argent/flows/, and "${target.name}" is ${picked.path}. Upgrade the tool-server to record it, or run it with e2e-execute outside the recording.`
26429
+ );
26430
+ }
26431
+ }
26432
+ return command === record2.command ? args : { ...record2, command };
26433
+ }
26434
+ async function e2eShadowWarningFor(tool, args) {
26435
+ const id = canonicalToolId(tool);
26436
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return void 0;
26437
+ const target = nestedFlowTarget(args);
26438
+ if (target?.kind !== "name") return void 0;
26439
+ const picked = await pickE2eFile(target.paths);
26440
+ return picked.shadowed === void 0 ? void 0 : e2eShadowWarning(picked.path, picked.shadowed);
26441
+ }
26297
26442
 
26298
26443
  // ../argent-tools-client/src/tools-client.ts
26299
26444
  function authHeaders2(token) {
@@ -26371,6 +26516,10 @@ function errorBodyMessage(body) {
26371
26516
  if (Array.isArray(body.issues) && typeof body.message === "string") return body.message;
26372
26517
  return body.error ?? body.message;
26373
26518
  }
26519
+ function findTool(tools, name) {
26520
+ const id = canonicalToolId(name);
26521
+ return tools.find((t) => t.name === name) ?? tools.find((t) => canonicalToolId(t.name) === id) ?? null;
26522
+ }
26374
26523
  function assertRequiredPresent(meta2, args) {
26375
26524
  const record2 = typeof args === "object" && args !== null ? args : {};
26376
26525
  const schema = meta2.inputSchema;
@@ -26446,26 +26595,33 @@ function createToolsClient(options = {}) {
26446
26595
  return json.tools;
26447
26596
  }
26448
26597
  async function fetchTool(name, opts) {
26449
- const tools = await fetchTools(opts);
26450
- return tools.find((t) => t.name === name) ?? null;
26598
+ return findTool(await fetchTools(opts), name);
26451
26599
  }
26452
26600
  async function callTool(name, args, opts) {
26453
26601
  opts?.signal?.throwIfAborted();
26454
26602
  const { url, token, remote } = await route();
26455
26603
  let finalArgs = args;
26456
26604
  const tools = await fetchTools({ signal: opts?.signal });
26457
- const meta2 = tools.find((t) => t.name === name) ?? null;
26605
+ const meta2 = findTool(tools, name);
26606
+ const olderServer = meta2 !== null && !tools.some((t) => t.name === canonicalToolId(meta2.name));
26607
+ if (meta2) {
26608
+ finalArgs = await nameToE2ePathForOlderServer(meta2.name, meta2.fileInputs, args);
26609
+ }
26610
+ if (olderServer && canonicalToolId(meta2.name) === "e2e-add-step") {
26611
+ finalArgs = await stepForOlderServer(finalArgs, (tool) => findTool(tools, tool)?.name);
26612
+ }
26613
+ const shadowWarning = await e2eShadowWarningFor(name, args);
26458
26614
  const baselineDirs = [];
26459
26615
  if (meta2?.fileInputs?.length) {
26460
- if (remote) assertRequiredPresent(meta2, args);
26461
- finalArgs = await prepareFileInputs(meta2.fileInputs, args ?? {}, {
26616
+ if (remote) assertRequiredPresent(meta2, finalArgs);
26617
+ finalArgs = await prepareFileInputs(meta2.fileInputs, finalArgs ?? {}, {
26462
26618
  includeContent: remote,
26463
26619
  uploadEndpoint: remote ? { url, token } : void 0,
26464
26620
  log: diagnose,
26465
26621
  baselineDirs,
26466
26622
  collectMembers: collectFlowMembers,
26467
- collectStepMembers,
26468
- toolFileInputs: (tool) => tools.find((t) => t.name === tool)?.fileInputs,
26623
+ collectStepMembers: olderServer ? (record2, o) => collectStepMembers(record2, o, (root) => path7.join(root, LEGACY_E2E_DIRS[0])) : collectStepMembers,
26624
+ toolFileInputs: (tool) => findTool(tools, tool)?.fileInputs,
26469
26625
  signal: opts?.signal
26470
26626
  });
26471
26627
  }
@@ -26474,19 +26630,23 @@ function createToolsClient(options = {}) {
26474
26630
  for (const { path: file, error: error2 } of applied.failed) {
26475
26631
  diagnose(`The baseline ${file} was not written on this client: ${error2}`);
26476
26632
  }
26477
- if (process.env.ARGENT_FLOW_FILES_LOG === "1") {
26633
+ if (filesLogEnabled()) {
26478
26634
  for (const file of applied.written) {
26479
- if (baselineDirs.includes(path6.dirname(file))) {
26635
+ if (baselineDirs.includes(path7.dirname(file))) {
26480
26636
  diagnose(`[flow-files] baseline ${file}: written`);
26481
26637
  }
26482
26638
  }
26483
26639
  }
26484
- return applied.result;
26640
+ const result = applied.result;
26641
+ if (shadowWarning === void 0 || typeof result !== "object" || result === null || Array.isArray(result) || typeof result.warning === "string") {
26642
+ return result;
26643
+ }
26644
+ return { ...result, warning: shadowWarning };
26485
26645
  };
26486
26646
  const stream = opts?.onProgress !== void 0 || carriesMembers(finalArgs);
26487
26647
  const sentOnce = carriesUpload(finalArgs);
26488
26648
  const res = await doFetch(
26489
- `${url}/tools/${encodeURIComponent(name)}`,
26649
+ `${url}/tools/${encodeURIComponent(meta2?.name ?? name)}`,
26490
26650
  {
26491
26651
  method: "POST",
26492
26652
  headers: {
@@ -26494,6 +26654,9 @@ function createToolsClient(options = {}) {
26494
26654
  // Tells the tool-server the call came over a link, a link to
26495
26655
  // 127.0.0.1 included, which nothing else in the request shows.
26496
26656
  ...remote ? { [LINKED_CALL_HEADER]: "1" } : {},
26657
+ // Tells the tool-server this client writes recordings under
26658
+ // `.argent/e2e/`; an older client writes only `.argent/flows/`.
26659
+ [E2E_DIR_CLIENT_HEADER]: "1",
26497
26660
  // A proxy that compresses the stream holds each line until its buffer
26498
26661
  // fills. `identity` keeps the stream uncompressed end to end.
26499
26662
  ...stream ? { "Accept": "application/x-ndjson", "Accept-Encoding": "identity" } : {},
@@ -26551,43 +26714,43 @@ function createToolsClient(options = {}) {
26551
26714
  }
26552
26715
 
26553
26716
  // ../argent-tools-client/src/artifacts.ts
26554
- import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
26717
+ import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat5, writeFile as writeFile4 } from "node:fs/promises";
26555
26718
  import { constants as fsConstants } from "node:fs";
26556
26719
  import { tmpdir as tmpdir2 } from "node:os";
26557
- import { basename as basename6, dirname as dirname8, extname as extname2, isAbsolute as isAbsolute6, join as join11, normalize as normalize2, resolve as resolve7, sep as sep4 } from "node:path";
26720
+ import { basename as basename7, dirname as dirname9, extname as extname2, isAbsolute as isAbsolute6, join as join13, normalize as normalize2, resolve as resolve8, sep as sep4 } from "node:path";
26558
26721
  import { createHash as createHash3 } from "node:crypto";
26559
26722
 
26560
26723
  // ../configuration-core/src/flags.ts
26561
- import * as fs3 from "node:fs";
26562
- import * as path7 from "node:path";
26724
+ import * as fs4 from "node:fs";
26725
+ import * as path8 from "node:path";
26563
26726
  import { homedir as homedir3 } from "node:os";
26564
26727
  var PROJECT_MARKERS = [".argent", ".git", "package.json"];
26565
26728
  function findProjectRoot(startDir) {
26566
- let current = path7.resolve(startDir);
26729
+ let current = path8.resolve(startDir);
26567
26730
  while (true) {
26568
26731
  for (const marker of PROJECT_MARKERS) {
26569
- if (fs3.existsSync(path7.join(current, marker))) return current;
26732
+ if (fs4.existsSync(path8.join(current, marker))) return current;
26570
26733
  }
26571
- const parent = path7.dirname(current);
26734
+ const parent = path8.dirname(current);
26572
26735
  if (parent === current) return null;
26573
26736
  current = parent;
26574
26737
  }
26575
26738
  }
26576
26739
  function resolveProjectRoot(startDir) {
26577
- return findProjectRoot(startDir) ?? path7.resolve(startDir);
26740
+ return findProjectRoot(startDir) ?? path8.resolve(startDir);
26578
26741
  }
26579
26742
  function getFlagsPath(scope, options = {}) {
26580
26743
  const home = options.homeDir ?? homedir3();
26581
26744
  if (scope === "global") {
26582
- return path7.join(home, ".argent", "flags.json");
26745
+ return path8.join(home, ".argent", "flags.json");
26583
26746
  }
26584
26747
  const cwd = options.cwd ?? process.cwd();
26585
- return path7.join(resolveProjectRoot(cwd), ".argent", "flags.json");
26748
+ return path8.join(resolveProjectRoot(cwd), ".argent", "flags.json");
26586
26749
  }
26587
26750
  function readFlagsFile(filePath) {
26588
26751
  let raw;
26589
26752
  try {
26590
- raw = fs3.readFileSync(filePath, "utf8");
26753
+ raw = fs4.readFileSync(filePath, "utf8");
26591
26754
  } catch {
26592
26755
  return {};
26593
26756
  }
@@ -26619,7 +26782,7 @@ function isFlagEnabled(name, options = {}) {
26619
26782
 
26620
26783
  // ../configuration-core/src/paths.ts
26621
26784
  import * as os from "node:os";
26622
- import * as path8 from "node:path";
26785
+ import * as path9 from "node:path";
26623
26786
  function nonEmpty(value) {
26624
26787
  if (value == void 0) return null;
26625
26788
  const trimmed = value.trim();
@@ -26630,26 +26793,26 @@ function resolveHomeDir(options = {}) {
26630
26793
  return process.platform === "win32" ? nonEmpty(process.env.USERPROFILE) ?? os.homedir() : nonEmpty(process.env.HOME) ?? os.homedir();
26631
26794
  }
26632
26795
  function argentHomeDir() {
26633
- return path8.join(resolveHomeDir(), ".argent");
26796
+ return path9.join(resolveHomeDir(), ".argent");
26634
26797
  }
26635
26798
  function configDir(scope = "global", options = {}) {
26636
26799
  if (scope === "global") {
26637
- return path8.join(resolveHomeDir(options), ".argent");
26800
+ return path9.join(resolveHomeDir(options), ".argent");
26638
26801
  }
26639
26802
  const cwd = options.cwd ?? process.cwd();
26640
- return path8.join(resolveProjectRoot(cwd), ".argent");
26803
+ return path9.join(resolveProjectRoot(cwd), ".argent");
26641
26804
  }
26642
26805
  function configFilePath(scope = "global", options = {}) {
26643
- return path8.join(configDir(scope, options), "config.json");
26806
+ return path9.join(configDir(scope, options), "config.json");
26644
26807
  }
26645
26808
 
26646
26809
  // ../configuration-core/src/config.ts
26647
26810
  import * as crypto from "node:crypto";
26648
- import * as fs4 from "node:fs";
26649
- import * as path9 from "node:path";
26811
+ import * as fs5 from "node:fs";
26812
+ import * as path10 from "node:path";
26650
26813
  function readConfigObject(scope = "global", options = {}) {
26651
26814
  try {
26652
- const raw = fs4.readFileSync(configFilePath(scope, options), "utf8");
26815
+ const raw = fs5.readFileSync(configFilePath(scope, options), "utf8");
26653
26816
  const json = JSON.parse(raw);
26654
26817
  if (json && typeof json === "object" && !Array.isArray(json)) {
26655
26818
  return json;
@@ -26694,9 +26857,9 @@ function acquireConfigLock(finalPath) {
26694
26857
  const deadline = Date.now() + LOCK_MAX_WAIT_MS;
26695
26858
  for (; ; ) {
26696
26859
  try {
26697
- const fd = fs4.openSync(lockPath, "wx", 384);
26860
+ const fd = fs5.openSync(lockPath, "wx", 384);
26698
26861
  try {
26699
- fs4.writeSync(fd, `${process.pid}
26862
+ fs5.writeSync(fd, `${process.pid}
26700
26863
  `);
26701
26864
  } catch {
26702
26865
  }
@@ -26704,8 +26867,8 @@ function acquireConfigLock(finalPath) {
26704
26867
  } catch (err) {
26705
26868
  if (err.code !== "EEXIST") return null;
26706
26869
  try {
26707
- if (Date.now() - fs4.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
26708
- fs4.unlinkSync(lockPath);
26870
+ if (Date.now() - fs5.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
26871
+ fs5.unlinkSync(lockPath);
26709
26872
  continue;
26710
26873
  }
26711
26874
  } catch {
@@ -26717,35 +26880,35 @@ function acquireConfigLock(finalPath) {
26717
26880
  }
26718
26881
  function releaseConfigLock(lock) {
26719
26882
  try {
26720
- fs4.closeSync(lock.fd);
26883
+ fs5.closeSync(lock.fd);
26721
26884
  } catch {
26722
26885
  }
26723
26886
  try {
26724
- fs4.unlinkSync(lock.lockPath);
26887
+ fs5.unlinkSync(lock.lockPath);
26725
26888
  } catch {
26726
26889
  }
26727
26890
  }
26728
26891
  function updateConfig(mutate, scope = "global", options = {}) {
26729
26892
  const dir = configDir(scope, options);
26730
- fs4.mkdirSync(dir, { recursive: true });
26893
+ fs5.mkdirSync(dir, { recursive: true });
26731
26894
  const finalPath = configFilePath(scope, options);
26732
26895
  const lock = acquireConfigLock(finalPath);
26733
26896
  try {
26734
26897
  const next = readConfigObject(scope, options);
26735
26898
  mutate(next);
26736
- const tmpPath = path9.join(dir, `.config.tmp.${process.pid}.${crypto.randomUUID()}`);
26737
- const fd = fs4.openSync(tmpPath, "wx", 384);
26899
+ const tmpPath = path10.join(dir, `.config.tmp.${process.pid}.${crypto.randomUUID()}`);
26900
+ const fd = fs5.openSync(tmpPath, "wx", 384);
26738
26901
  try {
26739
- fs4.writeSync(fd, JSON.stringify(next, null, 2) + "\n");
26740
- fs4.fsyncSync(fd);
26902
+ fs5.writeSync(fd, JSON.stringify(next, null, 2) + "\n");
26903
+ fs5.fsyncSync(fd);
26741
26904
  } finally {
26742
- fs4.closeSync(fd);
26905
+ fs5.closeSync(fd);
26743
26906
  }
26744
26907
  try {
26745
- fs4.renameSync(tmpPath, finalPath);
26908
+ fs5.renameSync(tmpPath, finalPath);
26746
26909
  } catch (err) {
26747
26910
  try {
26748
- fs4.unlinkSync(tmpPath);
26911
+ fs5.unlinkSync(tmpPath);
26749
26912
  } catch {
26750
26913
  }
26751
26914
  throw err;
@@ -26757,8 +26920,8 @@ function updateConfig(mutate, scope = "global", options = {}) {
26757
26920
 
26758
26921
  // ../configuration-core/src/secrets.ts
26759
26922
  var import_dotenv = __toESM(require_dist3(), 1);
26760
- import * as fs5 from "node:fs";
26761
- import * as path10 from "node:path";
26923
+ import * as fs6 from "node:fs";
26924
+ import * as path11 from "node:path";
26762
26925
 
26763
26926
  // ../configuration-core/src/merge.ts
26764
26927
  function mergeRestrictive(local, global) {
@@ -26902,7 +27065,7 @@ var CONFIG_SCHEMA = [
26902
27065
  // nominal here — the project scope of a global-only key is never read.
26903
27066
  {
26904
27067
  key: "scripts.maxTimeoutMs",
26905
- description: `Upper bound, in milliseconds, on the time limit a flow \`script\` step may ask for (default 300000 \u2014 five minutes). Bounds how long one script can occupy the host. Values below ${MIN_SCRIPT_TIMEOUT_MS} ms are refused: the step starts a Node process before the script runs, so a smaller ceiling ends a script that did nothing wrong.`,
27068
+ description: `Upper bound, in milliseconds, on the time limit an e2e test \`script\` step may ask for (default 300000 \u2014 five minutes). Bounds how long one script can occupy the host. Values below ${MIN_SCRIPT_TIMEOUT_MS} ms are refused: the step starts a Node process before the script runs, so a smaller ceiling ends a script that did nothing wrong.`,
26906
27069
  scopes: ["global"],
26907
27070
  parse: (raw) => {
26908
27071
  const value = asPositiveInteger(raw);
@@ -26915,7 +27078,7 @@ var CONFIG_SCHEMA = [
26915
27078
  },
26916
27079
  {
26917
27080
  key: "scripts.heapLimitMb",
26918
- description: `Old-space heap limit, in MiB, given to each flow \`script\` process (default 512). Values below ${MIN_SCRIPT_HEAP_LIMIT_MB} MiB are refused: that is already below what importing a real npm dependency needs, and under about 5 MiB the process dies inside V8's own startup before any script runs.`,
27081
+ description: `Old-space heap limit, in MiB, given to each e2e test \`script\` process (default 512). Values below ${MIN_SCRIPT_HEAP_LIMIT_MB} MiB are refused: that is already below what importing a real npm dependency needs, and under about 5 MiB the process dies inside V8's own startup before any script runs.`,
26919
27082
  scopes: ["global"],
26920
27083
  parse: (raw) => {
26921
27084
  const value = asPositiveInteger(raw);
@@ -26932,7 +27095,7 @@ function getConfigDefinition(key, registry2 = CONFIG_SCHEMA) {
26932
27095
  }
26933
27096
 
26934
27097
  // ../configuration-core/src/config-access.ts
26935
- import * as path11 from "node:path";
27098
+ import * as path12 from "node:path";
26936
27099
  function readScopeValue(def, scope, options) {
26937
27100
  if (!def.scopes.includes(scope)) return void 0;
26938
27101
  const raw = getAtPath(readConfigObject(scope, options), def.key);
@@ -26983,20 +27146,20 @@ function sanitizeSegment(segment) {
26983
27146
  function projectSlug() {
26984
27147
  const cwd = process.cwd();
26985
27148
  const hash = createHash3("sha1").update(cwd).digest("hex").slice(0, 6);
26986
- const name = sanitizeSegment(basename6(cwd)) || "root";
27149
+ const name = sanitizeSegment(basename7(cwd)) || "root";
26987
27150
  return `${name}-${hash}`;
26988
27151
  }
26989
27152
  function artifactsRoot() {
26990
- return process.env.ARGENT_ARTIFACTS_DIR ?? join11(tmpdir2(), "argent-artifacts");
27153
+ return process.env.ARGENT_ARTIFACTS_DIR ?? join13(tmpdir2(), "argent-artifacts");
26991
27154
  }
26992
27155
  function artifactDir(deviceId) {
26993
27156
  const parts = [artifactsRoot(), projectSlug(), sessionId()];
26994
27157
  if (deviceId) parts.push(sanitizeSegment(deviceId));
26995
- return join11(...parts);
27158
+ return join13(...parts);
26996
27159
  }
26997
27160
  function durableBaseDir() {
26998
27161
  const projectRoot = findProjectRoot(process.cwd());
26999
- return projectRoot ?? dirname8(argentHomeDir());
27162
+ return projectRoot ?? dirname9(argentHomeDir());
27000
27163
  }
27001
27164
  var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize2(".argent/recordings")]);
27002
27165
  var RECORDINGS_SAVE_DIR = normalize2(".argent/recordings");
@@ -27010,9 +27173,9 @@ function configuredRecordingsDir() {
27010
27173
  if (typeof value !== "string") return null;
27011
27174
  const trimmed = value.trim();
27012
27175
  if (trimmed === "") return null;
27013
- const home = dirname8(argentHomeDir());
27014
- const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join11(home, trimmed.slice(2)) : trimmed;
27015
- return resolve7(durableBaseDir(), expanded);
27176
+ const home = dirname9(argentHomeDir());
27177
+ const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join13(home, trimmed.slice(2)) : trimmed;
27178
+ return resolve8(durableBaseDir(), expanded);
27016
27179
  }
27017
27180
  var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
27018
27181
  async function readCapped(res, cap) {
@@ -27045,10 +27208,10 @@ async function writeDurableUnique(dir, filename, write) {
27045
27208
  const stem = filename.slice(0, filename.length - ext.length);
27046
27209
  for (let i = 1; i <= 1e3; i++) {
27047
27210
  const candidate = i === 1 ? filename : `${stem} (${i})${ext}`;
27048
- const path16 = join11(dir, candidate);
27211
+ const path17 = join13(dir, candidate);
27049
27212
  try {
27050
- await write(path16);
27051
- return path16;
27213
+ await write(path17);
27214
+ return path17;
27052
27215
  } catch (err) {
27053
27216
  if (err?.code === "EEXIST") continue;
27054
27217
  throw err;
@@ -27068,21 +27231,21 @@ function durableSaveTarget(handle) {
27068
27231
  if (configured) {
27069
27232
  return {
27070
27233
  dir: configured,
27071
- path: join11(configured, sanitizeSegment(handle.filename)),
27234
+ path: join13(configured, sanitizeSegment(handle.filename)),
27072
27235
  base: configured,
27073
27236
  rel: ""
27074
27237
  };
27075
27238
  }
27076
27239
  }
27077
27240
  const base = durableBaseDir();
27078
- const dir = join11(base, rel);
27079
- return { dir, path: join11(dir, sanitizeSegment(handle.filename)), base, rel };
27241
+ const dir = join13(base, rel);
27242
+ return { dir, path: join13(dir, sanitizeSegment(handle.filename)), base, rel };
27080
27243
  }
27081
27244
  async function confineToRealBase(dir, base, rel) {
27082
27245
  try {
27083
27246
  const realDir = await realpath4(dir);
27084
27247
  const realBase = await realpath4(base);
27085
- return realDir === join11(realBase, rel);
27248
+ return realDir === join13(realBase, rel);
27086
27249
  } catch {
27087
27250
  return false;
27088
27251
  }
@@ -27090,7 +27253,7 @@ async function confineToRealBase(dir, base, rel) {
27090
27253
  async function resolveLocalFile(handle) {
27091
27254
  if (!handle.hostPath) return null;
27092
27255
  try {
27093
- const st = await stat4(handle.hostPath);
27256
+ const st = await stat5(handle.hostPath);
27094
27257
  if (handle.archive) {
27095
27258
  return st.isDirectory() ? handle.hostPath : null;
27096
27259
  }
@@ -27105,7 +27268,7 @@ async function resolveLocalFile(handle) {
27105
27268
  }
27106
27269
  }
27107
27270
  async function downloadAndExtractArchive(handle, data, dir) {
27108
- const tarball = join11(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
27271
+ const tarball = join13(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
27109
27272
  try {
27110
27273
  await writeFile4(tarball, data);
27111
27274
  return await safeExtractTarGz(tarball, dir, handle.filename);
@@ -27133,7 +27296,7 @@ async function materializeArtifacts(result, ctx) {
27133
27296
  const localPath = await resolveLocalFile(value);
27134
27297
  const saveTarget = durableSaveTarget(value);
27135
27298
  if (saveTarget) {
27136
- const filename = basename6(saveTarget.path);
27299
+ const filename = basename7(saveTarget.path);
27137
27300
  try {
27138
27301
  await mkdir4(saveTarget.dir, { recursive: true });
27139
27302
  if (!await confineToRealBase(saveTarget.dir, saveTarget.base, saveTarget.rel)) {
@@ -27197,7 +27360,7 @@ async function materializeArtifacts(result, ctx) {
27197
27360
  return await downloadAndExtractArchive(value, data, dir);
27198
27361
  }
27199
27362
  if (value.size > 0 && data.length !== value.size) return null;
27200
- const downloadedPath = join11(dir, sanitizeSegment(value.filename));
27363
+ const downloadedPath = join13(dir, sanitizeSegment(value.filename));
27201
27364
  await writeFile4(downloadedPath, data);
27202
27365
  if (value.mimeType.startsWith("image/")) {
27203
27366
  images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
@@ -27231,10 +27394,10 @@ function getDeviceIdFromArgs(args) {
27231
27394
  }
27232
27395
 
27233
27396
  // ../telemetry/src/debug.ts
27234
- import * as fs6 from "node:fs";
27397
+ import * as fs7 from "node:fs";
27235
27398
 
27236
27399
  // ../telemetry/src/paths.ts
27237
- import * as path12 from "node:path";
27400
+ import * as path13 from "node:path";
27238
27401
 
27239
27402
  // ../telemetry/src/events.ts
27240
27403
  var PLATFORMS = [
@@ -27459,6 +27622,7 @@ var ALLOWED = {
27459
27622
  "tool:invoke": {
27460
27623
  device_provider: DEVICE_PROVIDER,
27461
27624
  tool: TOOL_NAME,
27625
+ alias_used: bool,
27462
27626
  tool_invocation_id: UUID,
27463
27627
  platform: PLATFORM,
27464
27628
  device_kind: DEVICE_KIND,
@@ -27467,6 +27631,7 @@ var ALLOWED = {
27467
27631
  "tool:complete": {
27468
27632
  device_provider: DEVICE_PROVIDER,
27469
27633
  tool: TOOL_NAME,
27634
+ alias_used: bool,
27470
27635
  tool_invocation_id: UUID,
27471
27636
  platform: PLATFORM,
27472
27637
  device_kind: DEVICE_KIND,
@@ -27476,6 +27641,7 @@ var ALLOWED = {
27476
27641
  "tool:fail": {
27477
27642
  device_provider: DEVICE_PROVIDER,
27478
27643
  tool: TOOL_NAME,
27644
+ alias_used: bool,
27479
27645
  tool_invocation_id: UUID,
27480
27646
  platform: PLATFORM,
27481
27647
  device_kind: DEVICE_KIND,
@@ -27494,6 +27660,7 @@ var ALLOWED = {
27494
27660
  },
27495
27661
  "cli:run_fail": {
27496
27662
  tool: TOOL_NAME,
27663
+ alias_used: bool,
27497
27664
  duration_ms: DURATION_MS,
27498
27665
  ...FAILURE_SIGNAL
27499
27666
  },
@@ -27922,29 +28089,29 @@ var SESSION_ID2 = randomUUID5();
27922
28089
 
27923
28090
  // ../telemetry/src/identity.ts
27924
28091
  import * as crypto2 from "node:crypto";
27925
- import * as fs7 from "node:fs";
27926
- import * as path13 from "node:path";
28092
+ import * as fs8 from "node:fs";
28093
+ import * as path14 from "node:path";
27927
28094
 
27928
28095
  // ../telemetry/src/fingerprint.ts
27929
28096
  import { execFileSync as execFileSync2, spawn as spawn2 } from "node:child_process";
27930
28097
 
27931
28098
  // ../native-devtools-ios/src/index.ts
27932
- import * as path14 from "node:path";
27933
- import * as fs8 from "node:fs";
27934
- var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path14.join(__dirname, "..", "dylibs");
27935
- var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path14.join(__dirname, "..", "bin");
27936
- var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path14.join(DYLIB_DIR, "tcp");
27937
- var DYLIB_TVOS_DIR = path14.join(DYLIB_DIR, "tvos");
28099
+ import * as path15 from "node:path";
28100
+ import * as fs9 from "node:fs";
28101
+ var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path15.join(__dirname, "..", "dylibs");
28102
+ var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path15.join(__dirname, "..", "bin");
28103
+ var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path15.join(DYLIB_DIR, "tcp");
28104
+ var DYLIB_TVOS_DIR = path15.join(DYLIB_DIR, "tvos");
27938
28105
 
27939
28106
  // ../telemetry/src/consent.ts
27940
- import * as fs9 from "node:fs";
28107
+ import * as fs10 from "node:fs";
27941
28108
  var cache = /* @__PURE__ */ new Map();
27942
28109
  var sessionOverride = null;
27943
28110
  function readConfigOverrideAt(filePath) {
27944
28111
  const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
27945
28112
  let stats;
27946
28113
  try {
27947
- stats = fs9.lstatSync(filePath);
28114
+ stats = fs10.lstatSync(filePath);
27948
28115
  } catch {
27949
28116
  cache.set(filePath, miss);
27950
28117
  return null;
@@ -27961,7 +28128,7 @@ function readConfigOverrideAt(filePath) {
27961
28128
  }
27962
28129
  let parsedEnabled = null;
27963
28130
  try {
27964
- const raw = fs9.readFileSync(filePath, "utf8");
28131
+ const raw = fs10.readFileSync(filePath, "utf8");
27965
28132
  const json = JSON.parse(raw);
27966
28133
  if (json && typeof json === "object") {
27967
28134
  const t = json.telemetry;
@@ -28205,8 +28372,10 @@ async function flowRunToMcpContent(result, ctx) {
28205
28372
  }
28206
28373
  blocks.push({
28207
28374
  type: "text",
28208
- text: `Running flow "${result.flow}"${result.device ? ` on ${result.device}` : ""} (${result.steps.length} steps)`
28375
+ text: `Running e2e test "${result.flow}"${result.device ? ` on ${result.device}` : ""} (${result.steps.length} steps)`
28209
28376
  });
28377
+ if (typeof result.warning === "string")
28378
+ blocks.push({ type: "text", text: `\u26A0 ${result.warning}` });
28210
28379
  for (let i = 0; i < result.steps.length; i++) {
28211
28380
  const step = result.steps[i];
28212
28381
  const num = step.index !== void 0 ? step.index + 1 : i + 1;
@@ -28235,9 +28404,9 @@ async function flowRunToMcpContent(result, ctx) {
28235
28404
  }
28236
28405
  }
28237
28406
  for (const write of result.baselineWrites ?? []) {
28238
- const { path: path16, error: error2 } = isRecord2(write) ? write : {};
28239
- if (typeof path16 === "string" && typeof error2 === "string") {
28240
- blocks.push({ type: "text", text: `\u2717 baseline not written: ${path16}: ${error2}` });
28407
+ const { path: path17, error: error2 } = isRecord2(write) ? write : {};
28408
+ if (typeof path17 === "string" && typeof error2 === "string") {
28409
+ blocks.push({ type: "text", text: `\u2717 baseline not written: ${path17}: ${error2}` });
28241
28410
  }
28242
28411
  }
28243
28412
  if (result.ok !== void 0) {
@@ -28248,7 +28417,7 @@ async function flowRunToMcpContent(result, ctx) {
28248
28417
  text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped${note}${durationSuffix(result.durationMs)}`
28249
28418
  });
28250
28419
  } else {
28251
- blocks.push({ type: "text", text: `Flow "${result.flow}" complete.` });
28420
+ blocks.push({ type: "text", text: `E2E test "${result.flow}" complete.` });
28252
28421
  }
28253
28422
  return blocks;
28254
28423
  }
@@ -28403,12 +28572,12 @@ function toMcpToolList(tools) {
28403
28572
  }
28404
28573
 
28405
28574
  // ../argent-mcp/src/installed-version.ts
28406
- import * as fs10 from "node:fs";
28407
- import * as path15 from "node:path";
28575
+ import * as fs11 from "node:fs";
28576
+ import * as path16 from "node:path";
28408
28577
  function getInstalledVersion() {
28409
28578
  try {
28410
- const pkgPath = path15.resolve(import.meta.dirname, "..", "package.json");
28411
- const pkg = JSON.parse(fs10.readFileSync(pkgPath, "utf8"));
28579
+ const pkgPath = path16.resolve(import.meta.dirname, "..", "package.json");
28580
+ const pkg = JSON.parse(fs11.readFileSync(pkgPath, "utf8"));
28412
28581
  return pkg.version ?? "unknown";
28413
28582
  } catch {
28414
28583
  return "unknown";
@@ -28552,7 +28721,7 @@ async function startMcpServer(options) {
28552
28721
  async function spyLog(entry) {
28553
28722
  try {
28554
28723
  if (!logDirReady) {
28555
- await mkdir5(dirname9(LOG_FILE2), { recursive: true });
28724
+ await mkdir5(dirname10(LOG_FILE2), { recursive: true });
28556
28725
  logDirReady = true;
28557
28726
  }
28558
28727
  await appendFile(LOG_FILE2, JSON.stringify(entry) + "\n");
@@ -28613,7 +28782,7 @@ async function startMcpServer(options) {
28613
28782
  deviceId: getDeviceIdFromArgs(params.arguments)
28614
28783
  };
28615
28784
  let content;
28616
- if (params.name === "flow-execute" && result && typeof result === "object" && "flow" in result && "steps" in result) {
28785
+ if (canonicalToolId(params.name) === "e2e-execute" && result && typeof result === "object" && "flow" in result && "steps" in result) {
28617
28786
  content = await flowRunToMcpContent(result, ctx);
28618
28787
  } else if (params.name === "screenshot-diff" && isScreenshotDiffResult(result)) {
28619
28788
  content = await screenshotDiffToMcpContent(result, ctx);