@swmansion/argent 0.29.1-next.9 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/bin/argent-android-devtools-0.3.0.apk +0 -0
  3. package/bin/darwin/ax-service +0 -0
  4. package/bin/darwin/simulator-server +0 -0
  5. package/bin/darwin/tvos-ax-service +0 -0
  6. package/bin/darwin/tvos-hid-daemon +0 -0
  7. package/bin/linux/simulator-server +0 -0
  8. package/bin/linux-arm64/simulator-server +0 -0
  9. package/bin/tcp/ax-service +0 -0
  10. package/bin/win32/simulator-server.exe +0 -0
  11. package/dist/cli-cmds.mjs +1186 -865
  12. package/dist/cli.js +3 -2
  13. package/dist/cli.js.map +1 -1
  14. package/dist/client.js +758 -517
  15. package/dist/flow-script-runner.mjs +1 -1
  16. package/dist/installer.mjs +1025 -832
  17. package/dist/mcp-server.mjs +826 -579
  18. package/dist/tool-args.generated.d.ts +53 -39
  19. package/dist/tool-server.cjs +5035 -2797
  20. package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
  21. package/dylibs/libKeyboardPatch.dylib +0 -0
  22. package/dylibs/libNativeDevtoolsIos.dylib +0 -0
  23. package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
  24. package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
  25. package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
  26. package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
  27. package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
  28. package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
  29. package/package.json +7 -7
  30. package/rules/argent.md +10 -10
  31. package/skills/{argent-create-flow → argent-create-e2e}/SKILL.md +16 -16
  32. package/skills/{argent-create-flow/references/flow-yaml.md → argent-create-e2e/references/e2e-yaml.md} +33 -33
  33. package/skills/{argent-create-flow → argent-create-e2e}/references/live-authoring.md +62 -62
  34. package/skills/{argent-create-flow → argent-create-e2e}/references/reliability-and-recovery.md +18 -18
  35. package/skills/argent-device-interact/SKILL.md +10 -8
  36. package/skills/argent-device-interact/references/chromium.md +1 -1
  37. package/skills/argent-ios-device-interact/SKILL.md +1 -1
  38. package/skills/argent-metro-debugger/SKILL.md +1 -1
  39. package/skills/argent-native-profiler/SKILL.md +1 -1
  40. package/skills/{argent-qa-flows → argent-qa-e2e}/SKILL.md +23 -23
  41. package/skills/argent-react-native-optimization/SKILL.md +2 -2
  42. package/skills/argent-react-native-profiler/SKILL.md +3 -3
  43. package/skills/argent-screen-recording/SKILL.md +1 -1
  44. package/skills/argent-test-ui-flow/SKILL.md +4 -4
package/dist/cli-cmds.mjs CHANGED
@@ -124,17 +124,17 @@ var require_visit = __commonJS({
124
124
  visit2.BREAK = BREAK;
125
125
  visit2.SKIP = SKIP;
126
126
  visit2.REMOVE = REMOVE;
127
- function visit_(key, node2, visitor, path24) {
128
- const ctrl = callVisitor(key, node2, visitor, path24);
127
+ function visit_(key, node2, visitor, path25) {
128
+ const ctrl = callVisitor(key, node2, visitor, path25);
129
129
  if (identity2.isNode(ctrl) || identity2.isPair(ctrl)) {
130
- replaceNode(key, path24, ctrl);
131
- return visit_(key, ctrl, visitor, path24);
130
+ replaceNode(key, path25, ctrl);
131
+ return visit_(key, ctrl, visitor, path25);
132
132
  }
133
133
  if (typeof ctrl !== "symbol") {
134
134
  if (identity2.isCollection(node2)) {
135
- path24 = Object.freeze(path24.concat(node2));
135
+ path25 = Object.freeze(path25.concat(node2));
136
136
  for (let i2 = 0; i2 < node2.items.length; ++i2) {
137
- const ci = visit_(i2, node2.items[i2], visitor, path24);
137
+ const ci = visit_(i2, node2.items[i2], visitor, path25);
138
138
  if (typeof ci === "number")
139
139
  i2 = ci - 1;
140
140
  else if (ci === BREAK)
@@ -145,13 +145,13 @@ var require_visit = __commonJS({
145
145
  }
146
146
  }
147
147
  } else if (identity2.isPair(node2)) {
148
- path24 = Object.freeze(path24.concat(node2));
149
- const ck = visit_("key", node2.key, visitor, path24);
148
+ path25 = Object.freeze(path25.concat(node2));
149
+ const ck = visit_("key", node2.key, visitor, path25);
150
150
  if (ck === BREAK)
151
151
  return BREAK;
152
152
  else if (ck === REMOVE)
153
153
  node2.key = null;
154
- const cv = visit_("value", node2.value, visitor, path24);
154
+ const cv = visit_("value", node2.value, visitor, path25);
155
155
  if (cv === BREAK)
156
156
  return BREAK;
157
157
  else if (cv === REMOVE)
@@ -172,17 +172,17 @@ var require_visit = __commonJS({
172
172
  visitAsync.BREAK = BREAK;
173
173
  visitAsync.SKIP = SKIP;
174
174
  visitAsync.REMOVE = REMOVE;
175
- async function visitAsync_(key, node2, visitor, path24) {
176
- const ctrl = await callVisitor(key, node2, visitor, path24);
175
+ async function visitAsync_(key, node2, visitor, path25) {
176
+ const ctrl = await callVisitor(key, node2, visitor, path25);
177
177
  if (identity2.isNode(ctrl) || identity2.isPair(ctrl)) {
178
- replaceNode(key, path24, ctrl);
179
- return visitAsync_(key, ctrl, visitor, path24);
178
+ replaceNode(key, path25, ctrl);
179
+ return visitAsync_(key, ctrl, visitor, path25);
180
180
  }
181
181
  if (typeof ctrl !== "symbol") {
182
182
  if (identity2.isCollection(node2)) {
183
- path24 = Object.freeze(path24.concat(node2));
183
+ path25 = Object.freeze(path25.concat(node2));
184
184
  for (let i2 = 0; i2 < node2.items.length; ++i2) {
185
- const ci = await visitAsync_(i2, node2.items[i2], visitor, path24);
185
+ const ci = await visitAsync_(i2, node2.items[i2], visitor, path25);
186
186
  if (typeof ci === "number")
187
187
  i2 = ci - 1;
188
188
  else if (ci === BREAK)
@@ -193,13 +193,13 @@ var require_visit = __commonJS({
193
193
  }
194
194
  }
195
195
  } else if (identity2.isPair(node2)) {
196
- path24 = Object.freeze(path24.concat(node2));
197
- const ck = await visitAsync_("key", node2.key, visitor, path24);
196
+ path25 = Object.freeze(path25.concat(node2));
197
+ const ck = await visitAsync_("key", node2.key, visitor, path25);
198
198
  if (ck === BREAK)
199
199
  return BREAK;
200
200
  else if (ck === REMOVE)
201
201
  node2.key = null;
202
- const cv = await visitAsync_("value", node2.value, visitor, path24);
202
+ const cv = await visitAsync_("value", node2.value, visitor, path25);
203
203
  if (cv === BREAK)
204
204
  return BREAK;
205
205
  else if (cv === REMOVE)
@@ -226,23 +226,23 @@ var require_visit = __commonJS({
226
226
  }
227
227
  return visitor;
228
228
  }
229
- function callVisitor(key, node2, visitor, path24) {
229
+ function callVisitor(key, node2, visitor, path25) {
230
230
  if (typeof visitor === "function")
231
- return visitor(key, node2, path24);
231
+ return visitor(key, node2, path25);
232
232
  if (identity2.isMap(node2))
233
- return visitor.Map?.(key, node2, path24);
233
+ return visitor.Map?.(key, node2, path25);
234
234
  if (identity2.isSeq(node2))
235
- return visitor.Seq?.(key, node2, path24);
235
+ return visitor.Seq?.(key, node2, path25);
236
236
  if (identity2.isPair(node2))
237
- return visitor.Pair?.(key, node2, path24);
237
+ return visitor.Pair?.(key, node2, path25);
238
238
  if (identity2.isScalar(node2))
239
- return visitor.Scalar?.(key, node2, path24);
239
+ return visitor.Scalar?.(key, node2, path25);
240
240
  if (identity2.isAlias(node2))
241
- return visitor.Alias?.(key, node2, path24);
241
+ return visitor.Alias?.(key, node2, path25);
242
242
  return void 0;
243
243
  }
244
- function replaceNode(key, path24, node2) {
245
- const parent = path24[path24.length - 1];
244
+ function replaceNode(key, path25, node2) {
245
+ const parent = path25[path25.length - 1];
246
246
  if (identity2.isCollection(parent)) {
247
247
  parent.items[key] = node2;
248
248
  } else if (identity2.isPair(parent)) {
@@ -854,10 +854,10 @@ var require_Collection = __commonJS({
854
854
  var createNode = require_createNode();
855
855
  var identity2 = require_identity();
856
856
  var Node = require_Node();
857
- function collectionFromPath(schema, path24, value) {
857
+ function collectionFromPath(schema, path25, value) {
858
858
  let v = value;
859
- for (let i2 = path24.length - 1; i2 >= 0; --i2) {
860
- const k = path24[i2];
859
+ for (let i2 = path25.length - 1; i2 >= 0; --i2) {
860
+ const k = path25[i2];
861
861
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
862
862
  const a2 = [];
863
863
  a2[k] = v;
@@ -876,7 +876,7 @@ var require_Collection = __commonJS({
876
876
  sourceObjects: /* @__PURE__ */ new Map()
877
877
  });
878
878
  }
879
- var isEmptyPath = (path24) => path24 == null || typeof path24 === "object" && !!path24[Symbol.iterator]().next().done;
879
+ var isEmptyPath = (path25) => path25 == null || typeof path25 === "object" && !!path25[Symbol.iterator]().next().done;
880
880
  var Collection = class extends Node.NodeBase {
881
881
  constructor(type, schema) {
882
882
  super(type);
@@ -906,11 +906,11 @@ var require_Collection = __commonJS({
906
906
  * be a Pair instance or a `{ key, value }` object, which may not have a key
907
907
  * that already exists in the map.
908
908
  */
909
- addIn(path24, value) {
910
- if (isEmptyPath(path24))
909
+ addIn(path25, value) {
910
+ if (isEmptyPath(path25))
911
911
  this.add(value);
912
912
  else {
913
- const [key, ...rest] = path24;
913
+ const [key, ...rest] = path25;
914
914
  const node2 = this.get(key, true);
915
915
  if (identity2.isCollection(node2))
916
916
  node2.addIn(rest, value);
@@ -924,8 +924,8 @@ var require_Collection = __commonJS({
924
924
  * Removes a value from the collection.
925
925
  * @returns `true` if the item was found and removed.
926
926
  */
927
- deleteIn(path24) {
928
- const [key, ...rest] = path24;
927
+ deleteIn(path25) {
928
+ const [key, ...rest] = path25;
929
929
  if (rest.length === 0)
930
930
  return this.delete(key);
931
931
  const node2 = this.get(key, true);
@@ -939,8 +939,8 @@ var require_Collection = __commonJS({
939
939
  * scalar values from their surrounding node; to disable set `keepScalar` to
940
940
  * `true` (collections are always returned intact).
941
941
  */
942
- getIn(path24, keepScalar) {
943
- const [key, ...rest] = path24;
942
+ getIn(path25, keepScalar) {
943
+ const [key, ...rest] = path25;
944
944
  const node2 = this.get(key, true);
945
945
  if (rest.length === 0)
946
946
  return !keepScalar && identity2.isScalar(node2) ? node2.value : node2;
@@ -958,8 +958,8 @@ var require_Collection = __commonJS({
958
958
  /**
959
959
  * Checks if the collection includes a value with the key `key`.
960
960
  */
961
- hasIn(path24) {
962
- const [key, ...rest] = path24;
961
+ hasIn(path25) {
962
+ const [key, ...rest] = path25;
963
963
  if (rest.length === 0)
964
964
  return this.has(key);
965
965
  const node2 = this.get(key, true);
@@ -969,8 +969,8 @@ var require_Collection = __commonJS({
969
969
  * Sets a value in this collection. For `!!set`, `value` needs to be a
970
970
  * boolean to add/remove the item from the set.
971
971
  */
972
- setIn(path24, value) {
973
- const [key, ...rest] = path24;
972
+ setIn(path25, value) {
973
+ const [key, ...rest] = path25;
974
974
  if (rest.length === 0) {
975
975
  this.set(key, value);
976
976
  } else {
@@ -1650,8 +1650,8 @@ ${ctx.indent}`;
1650
1650
  const vs0 = valueStr[0];
1651
1651
  const nl0 = valueStr.indexOf("\n");
1652
1652
  const hasNewline = nl0 !== -1;
1653
- const flow2 = ctx.inFlow ?? value.flow ?? value.items.length === 0;
1654
- if (hasNewline || !flow2) {
1653
+ const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
1654
+ if (hasNewline || !flow) {
1655
1655
  let hasPropsLine = false;
1656
1656
  if (hasNewline && (vs0 === "&" || vs0 === "!")) {
1657
1657
  let sp0 = valueStr.indexOf(" ");
@@ -1877,8 +1877,8 @@ var require_stringifyCollection = __commonJS({
1877
1877
  var stringify = require_stringify();
1878
1878
  var stringifyComment = require_stringifyComment();
1879
1879
  function stringifyCollection(collection, ctx, options) {
1880
- const flow2 = ctx.inFlow ?? collection.flow;
1881
- const stringify2 = flow2 ? stringifyFlowCollection : stringifyBlockCollection;
1880
+ const flow = ctx.inFlow ?? collection.flow;
1881
+ const stringify2 = flow ? stringifyFlowCollection : stringifyBlockCollection;
1882
1882
  return stringify2(collection, ctx, options);
1883
1883
  }
1884
1884
  function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
@@ -3485,9 +3485,9 @@ var require_Document = __commonJS({
3485
3485
  this.contents.add(value);
3486
3486
  }
3487
3487
  /** Adds a value to the document. */
3488
- addIn(path24, value) {
3488
+ addIn(path25, value) {
3489
3489
  if (assertCollection(this.contents))
3490
- this.contents.addIn(path24, value);
3490
+ this.contents.addIn(path25, value);
3491
3491
  }
3492
3492
  /**
3493
3493
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -3521,7 +3521,7 @@ var require_Document = __commonJS({
3521
3521
  options = replacer;
3522
3522
  replacer = void 0;
3523
3523
  }
3524
- const { aliasDuplicateObjects, anchorPrefix, flow: flow2, keepUndefined, onTagObj, tag } = options ?? {};
3524
+ const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};
3525
3525
  const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(
3526
3526
  this,
3527
3527
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
@@ -3537,7 +3537,7 @@ var require_Document = __commonJS({
3537
3537
  sourceObjects
3538
3538
  };
3539
3539
  const node2 = createNode.createNode(value, tag, ctx);
3540
- if (flow2 && identity2.isCollection(node2))
3540
+ if (flow && identity2.isCollection(node2))
3541
3541
  node2.flow = true;
3542
3542
  setAnchors();
3543
3543
  return node2;
@@ -3562,14 +3562,14 @@ var require_Document = __commonJS({
3562
3562
  * Removes a value from the document.
3563
3563
  * @returns `true` if the item was found and removed.
3564
3564
  */
3565
- deleteIn(path24) {
3566
- if (Collection.isEmptyPath(path24)) {
3565
+ deleteIn(path25) {
3566
+ if (Collection.isEmptyPath(path25)) {
3567
3567
  if (this.contents == null)
3568
3568
  return false;
3569
3569
  this.contents = null;
3570
3570
  return true;
3571
3571
  }
3572
- return assertCollection(this.contents) ? this.contents.deleteIn(path24) : false;
3572
+ return assertCollection(this.contents) ? this.contents.deleteIn(path25) : false;
3573
3573
  }
3574
3574
  /**
3575
3575
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
3584
3584
  * scalar values from their surrounding node; to disable set `keepScalar` to
3585
3585
  * `true` (collections are always returned intact).
3586
3586
  */
3587
- getIn(path24, keepScalar) {
3588
- if (Collection.isEmptyPath(path24))
3587
+ getIn(path25, keepScalar) {
3588
+ if (Collection.isEmptyPath(path25))
3589
3589
  return !keepScalar && identity2.isScalar(this.contents) ? this.contents.value : this.contents;
3590
- return identity2.isCollection(this.contents) ? this.contents.getIn(path24, keepScalar) : void 0;
3590
+ return identity2.isCollection(this.contents) ? this.contents.getIn(path25, keepScalar) : void 0;
3591
3591
  }
3592
3592
  /**
3593
3593
  * Checks if the document includes a value with the key `key`.
@@ -3598,10 +3598,10 @@ var require_Document = __commonJS({
3598
3598
  /**
3599
3599
  * Checks if the document includes a value at `path`.
3600
3600
  */
3601
- hasIn(path24) {
3602
- if (Collection.isEmptyPath(path24))
3601
+ hasIn(path25) {
3602
+ if (Collection.isEmptyPath(path25))
3603
3603
  return this.contents !== void 0;
3604
- return identity2.isCollection(this.contents) ? this.contents.hasIn(path24) : false;
3604
+ return identity2.isCollection(this.contents) ? this.contents.hasIn(path25) : false;
3605
3605
  }
3606
3606
  /**
3607
3607
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -3618,13 +3618,13 @@ var require_Document = __commonJS({
3618
3618
  * Sets a value in this document. For `!!set`, `value` needs to be a
3619
3619
  * boolean to add/remove the item from the set.
3620
3620
  */
3621
- setIn(path24, value) {
3622
- if (Collection.isEmptyPath(path24)) {
3621
+ setIn(path25, value) {
3622
+ if (Collection.isEmptyPath(path25)) {
3623
3623
  this.contents = value;
3624
3624
  } else if (this.contents == null) {
3625
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path24), value);
3625
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path25), value);
3626
3626
  } else if (assertCollection(this.contents)) {
3627
- this.contents.setIn(path24, value);
3627
+ this.contents.setIn(path25, value);
3628
3628
  }
3629
3629
  }
3630
3630
  /**
@@ -3785,7 +3785,7 @@ ${pointer}
3785
3785
  var require_resolve_props = __commonJS({
3786
3786
  "../../node_modules/yaml/dist/compose/resolve-props.js"(exports) {
3787
3787
  "use strict";
3788
- function resolveProps(tokens, { flow: flow2, indicator, next, offset, onError, parentIndent, startOnNewline }) {
3788
+ function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
3789
3789
  let spaceBefore = false;
3790
3790
  let atNewline = startOnNewline;
3791
3791
  let hasSpace = startOnNewline;
@@ -3814,7 +3814,7 @@ var require_resolve_props = __commonJS({
3814
3814
  }
3815
3815
  switch (token.type) {
3816
3816
  case "space":
3817
- if (!flow2 && (indicator !== "doc-start" || next?.type !== "flow-collection") && token.source.includes(" ")) {
3817
+ if (!flow && (indicator !== "doc-start" || next?.type !== "flow-collection") && token.source.includes(" ")) {
3818
3818
  tab = token;
3819
3819
  }
3820
3820
  hasSpace = true;
@@ -3870,15 +3870,15 @@ var require_resolve_props = __commonJS({
3870
3870
  if (anchor2 || tag)
3871
3871
  onError(token, "BAD_PROP_ORDER", `Anchors and tags must be after the ${token.source} indicator`);
3872
3872
  if (found)
3873
- onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.source} in ${flow2 ?? "collection"}`);
3873
+ onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.source} in ${flow ?? "collection"}`);
3874
3874
  found = token;
3875
3875
  atNewline = indicator === "seq-item-ind" || indicator === "explicit-key-ind";
3876
3876
  hasSpace = false;
3877
3877
  break;
3878
3878
  case "comma":
3879
- if (flow2) {
3879
+ if (flow) {
3880
3880
  if (comma)
3881
- onError(token, "UNEXPECTED_TOKEN", `Unexpected , in ${flow2}`);
3881
+ onError(token, "UNEXPECTED_TOKEN", `Unexpected , in ${flow}`);
3882
3882
  comma = token;
3883
3883
  atNewline = false;
3884
3884
  hasSpace = false;
@@ -5585,9 +5585,9 @@ var require_cst_visit = __commonJS({
5585
5585
  visit2.BREAK = BREAK;
5586
5586
  visit2.SKIP = SKIP;
5587
5587
  visit2.REMOVE = REMOVE;
5588
- visit2.itemAtPath = (cst, path24) => {
5588
+ visit2.itemAtPath = (cst, path25) => {
5589
5589
  let item = cst;
5590
- for (const [field, index] of path24) {
5590
+ for (const [field, index] of path25) {
5591
5591
  const tok = item?.[field];
5592
5592
  if (tok && "items" in tok) {
5593
5593
  item = tok.items[index];
@@ -5596,23 +5596,23 @@ var require_cst_visit = __commonJS({
5596
5596
  }
5597
5597
  return item;
5598
5598
  };
5599
- visit2.parentCollection = (cst, path24) => {
5600
- const parent = visit2.itemAtPath(cst, path24.slice(0, -1));
5601
- const field = path24[path24.length - 1][0];
5599
+ visit2.parentCollection = (cst, path25) => {
5600
+ const parent = visit2.itemAtPath(cst, path25.slice(0, -1));
5601
+ const field = path25[path25.length - 1][0];
5602
5602
  const coll = parent?.[field];
5603
5603
  if (coll && "items" in coll)
5604
5604
  return coll;
5605
5605
  throw new Error("Parent collection not found");
5606
5606
  };
5607
- function _visit(path24, item, visitor) {
5608
- let ctrl = visitor(item, path24);
5607
+ function _visit(path25, item, visitor) {
5608
+ let ctrl = visitor(item, path25);
5609
5609
  if (typeof ctrl === "symbol")
5610
5610
  return ctrl;
5611
5611
  for (const field of ["key", "value"]) {
5612
5612
  const token = item[field];
5613
5613
  if (token && "items" in token) {
5614
5614
  for (let i2 = 0; i2 < token.items.length; ++i2) {
5615
- const ci = _visit(Object.freeze(path24.concat([[field, i2]])), token.items[i2], visitor);
5615
+ const ci = _visit(Object.freeze(path25.concat([[field, i2]])), token.items[i2], visitor);
5616
5616
  if (typeof ci === "number")
5617
5617
  i2 = ci - 1;
5618
5618
  else if (ci === BREAK)
@@ -5623,10 +5623,10 @@ var require_cst_visit = __commonJS({
5623
5623
  }
5624
5624
  }
5625
5625
  if (typeof ctrl === "function" && field === "key")
5626
- ctrl = ctrl(item, path24);
5626
+ ctrl = ctrl(item, path25);
5627
5627
  }
5628
5628
  }
5629
- return typeof ctrl === "function" ? ctrl(item, path24) : ctrl;
5629
+ return typeof ctrl === "function" ? ctrl(item, path25) : ctrl;
5630
5630
  }
5631
5631
  exports.visit = visit2;
5632
5632
  }
@@ -6928,14 +6928,14 @@ var require_parser = __commonJS({
6928
6928
  case "scalar":
6929
6929
  case "single-quoted-scalar":
6930
6930
  case "double-quoted-scalar": {
6931
- const fs18 = this.flowScalar(this.type);
6931
+ const fs19 = this.flowScalar(this.type);
6932
6932
  if (atNextItem || it.value) {
6933
- map2.items.push({ start, key: fs18, sep: [] });
6933
+ map2.items.push({ start, key: fs19, sep: [] });
6934
6934
  this.onKeyLine = true;
6935
6935
  } else if (it.sep) {
6936
- this.stack.push(fs18);
6936
+ this.stack.push(fs19);
6937
6937
  } else {
6938
- Object.assign(it, { key: fs18, sep: [] });
6938
+ Object.assign(it, { key: fs19, sep: [] });
6939
6939
  this.onKeyLine = true;
6940
6940
  }
6941
6941
  return;
@@ -7063,13 +7063,13 @@ var require_parser = __commonJS({
7063
7063
  case "scalar":
7064
7064
  case "single-quoted-scalar":
7065
7065
  case "double-quoted-scalar": {
7066
- const fs18 = this.flowScalar(this.type);
7066
+ const fs19 = this.flowScalar(this.type);
7067
7067
  if (!it || it.value)
7068
- fc.items.push({ start: [], key: fs18, sep: [] });
7068
+ fc.items.push({ start: [], key: fs19, sep: [] });
7069
7069
  else if (it.sep)
7070
- this.stack.push(fs18);
7070
+ this.stack.push(fs19);
7071
7071
  else
7072
- Object.assign(it, { key: fs18, sep: [] });
7072
+ Object.assign(it, { key: fs19, sep: [] });
7073
7073
  return;
7074
7074
  }
7075
7075
  case "flow-map-end":
@@ -7377,322 +7377,395 @@ var require_dist = __commonJS({
7377
7377
  }
7378
7378
  });
7379
7379
 
7380
- // ../../node_modules/dotenv/lib/main.js
7381
- var require_main = __commonJS({
7382
- "../../node_modules/dotenv/lib/main.js"(exports, module) {
7383
- var fs18 = __require("fs");
7384
- var path24 = __require("path");
7385
- var os4 = __require("os");
7386
- var crypto3 = __require("crypto");
7387
- var TIPS = [
7388
- "\u25C8 encrypted .env [www.dotenvx.com]",
7389
- "\u25C8 secrets for agents [www.dotenvx.com]",
7390
- "\u2301 auth for agents [www.vestauth.com]",
7391
- "\u2318 custom filepath { path: '/custom/path/.env' }",
7392
- "\u2318 enable debugging { debug: true }",
7393
- "\u2318 override existing { override: true }",
7394
- "\u2318 suppress logs { quiet: true }",
7395
- "\u2318 multiple files { path: ['.env.local', '.env'] }"
7396
- ];
7397
- function _getRandomTip() {
7398
- return TIPS[Math.floor(Math.random() * TIPS.length)];
7399
- }
7400
- function parseBoolean(value) {
7401
- if (typeof value === "string") {
7402
- return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
7403
- }
7404
- return Boolean(value);
7405
- }
7406
- function supportsAnsi() {
7407
- return process.stdout.isTTY;
7408
- }
7409
- function dim2(text2) {
7410
- return supportsAnsi() ? `\x1B[2m${text2}\x1B[0m` : text2;
7411
- }
7412
- var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
7413
- function parse3(src) {
7414
- const obj = {};
7415
- let lines = src.toString();
7416
- lines = lines.replace(/\r\n?/mg, "\n");
7417
- let match;
7418
- while ((match = LINE.exec(lines)) != null) {
7419
- const key = match[1];
7420
- let value = match[2] || "";
7421
- value = value.trim();
7422
- const maybeQuote = value[0];
7423
- value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
7424
- if (maybeQuote === '"') {
7425
- value = value.replace(/\\n/g, "\n");
7426
- value = value.replace(/\\r/g, "\r");
7427
- }
7428
- obj[key] = value;
7429
- }
7430
- return obj;
7431
- }
7432
- function _parseVault(options) {
7433
- options = options || {};
7434
- const vaultPath = _vaultPath(options);
7435
- options.path = vaultPath;
7436
- const result = DotenvModule.configDotenv(options);
7437
- if (!result.parsed) {
7438
- const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
7439
- err.code = "MISSING_DATA";
7440
- throw err;
7380
+ // ../../node_modules/dotenv/dist/index.cjs
7381
+ var require_dist2 = __commonJS({
7382
+ "../../node_modules/dotenv/dist/index.cjs"(exports, module) {
7383
+ var j = (e, n3) => () => {
7384
+ try {
7385
+ return n3 || e((n3 = { exports: {} }).exports, n3), n3.exports;
7386
+ } catch (t2) {
7387
+ throw n3 = 0, t2;
7441
7388
  }
7442
- const keys = _dotenvKey(options).split(",");
7443
- const length = keys.length;
7444
- let decrypted;
7445
- for (let i2 = 0; i2 < length; i2++) {
7446
- try {
7447
- const key = keys[i2].trim();
7448
- const attrs = _instructions(result, key);
7449
- decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
7450
- break;
7451
- } catch (error63) {
7452
- if (i2 + 1 >= length) {
7453
- throw error63;
7454
- }
7389
+ };
7390
+ var k = j((xe, U2) => {
7391
+ function G(e) {
7392
+ return typeof e == "string" ? !["false", "0", "no", "off", ""].includes(e.toLowerCase()) : !!e;
7393
+ }
7394
+ function Y(e = process.env) {
7395
+ let n3 = {};
7396
+ for (let t2 of ["ENCODING", "PATH", "QUIET", "DEBUG", "OVERRIDE", "FAST"]) {
7397
+ let o = e[`DOTENV_${t2}`] != null ? e[`DOTENV_${t2}`] : e[`DOTENV_CONFIG_${t2}`];
7398
+ o != null && (n3[t2.toLowerCase()] = t2 === "ENCODING" || t2 === "PATH" ? o : G(o));
7455
7399
  }
7400
+ return n3;
7456
7401
  }
7457
- return DotenvModule.parse(decrypted);
7458
- }
7459
- function _warn(message) {
7460
- console.error(`\u26A0 ${message}`);
7461
- }
7462
- function _debug(message) {
7463
- console.log(`\u2506 ${message}`);
7464
- }
7465
- function _log(message) {
7466
- console.log(`\u25C7 ${message}`);
7467
- }
7468
- function _dotenvKey(options) {
7469
- if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
7470
- return options.DOTENV_KEY;
7402
+ U2.exports = { parseBoolean: G, optionsFromEnv: Y };
7403
+ });
7404
+ var N = j((ye, x) => {
7405
+ var z2 = __require("fs"), I2 = __require("path"), Z = __require("os"), { URL: ee, fileURLToPath: te } = __require("url"), { parseBoolean: $, optionsFromEnv: B } = k(), re2 = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg, b = new Uint8Array(256);
7406
+ for (let e = 48; e <= 57; e++) b[e] = 1;
7407
+ for (let e = 65; e <= 90; e++) b[e] = 1;
7408
+ for (let e = 97; e <= 122; e++) b[e] = 1;
7409
+ b[45] = 1;
7410
+ b[46] = 1;
7411
+ b[95] = 1;
7412
+ function ne(e) {
7413
+ let n3 = {}, t2 = e.toString();
7414
+ t2 = t2.replace(/\r\n?/mg, `
7415
+ `);
7416
+ let o;
7417
+ for (; (o = re2.exec(t2)) != null; ) {
7418
+ let r2 = o[1], s = o[2] || "";
7419
+ s = s.trim();
7420
+ let i2 = s[0];
7421
+ s = s.replace(/^(['"`])([\s\S]*)\1$/mg, "$2"), i2 === '"' && (s = s.replace(/\\n/g, `
7422
+ `), s = s.replace(/\\r/g, "\r")), n3[r2] = s;
7423
+ }
7424
+ return n3;
7471
7425
  }
7472
- if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
7473
- return process.env.DOTENV_KEY;
7426
+ function w(e) {
7427
+ return e <= 32 ? e === 32 || e >= 9 && e <= 13 : e >= 160 && (e === 160 || e === 5760 || e >= 8192 && e <= 8202 || e === 8232 || e === 8233 || e === 8239 || e === 8287 || e === 12288 || e === 65279);
7474
7428
  }
7475
- return "";
7476
- }
7477
- function _instructions(result, dotenvKey) {
7478
- let uri;
7479
- try {
7480
- uri = new URL(dotenvKey);
7481
- } catch (error63) {
7482
- if (error63.code === "ERR_INVALID_URL") {
7483
- const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
7484
- err.code = "INVALID_DOTENV_KEY";
7485
- throw err;
7429
+ function q(e) {
7430
+ return e === 10 || e === 8232 || e === 8233;
7431
+ }
7432
+ function oe(e) {
7433
+ let n3 = {}, t2 = typeof e == "string" ? e : e.toString();
7434
+ t2.indexOf("\r") !== -1 && (t2 = t2.replace(/\r\n?/g, `
7435
+ `));
7436
+ let o = t2.length, r2 = 0;
7437
+ for (; r2 < o; ) {
7438
+ let s = t2.charCodeAt(r2);
7439
+ for (; r2 < o && w(s); ) r2++, s = t2.charCodeAt(r2);
7440
+ if (r2 >= o) break;
7441
+ if (s === 35) {
7442
+ for (; r2 < o && !q(t2.charCodeAt(r2)); ) r2++;
7443
+ continue;
7444
+ }
7445
+ let i2 = -1;
7446
+ if (s === 101 && r2 + 6 < o && t2.charCodeAt(r2 + 1) === 120 && t2.charCodeAt(r2 + 2) === 112 && t2.charCodeAt(r2 + 3) === 111 && t2.charCodeAt(r2 + 4) === 114 && t2.charCodeAt(r2 + 5) === 116) {
7447
+ let v = t2.charCodeAt(r2 + 6);
7448
+ if (w(v)) {
7449
+ let u3 = r2 + 7;
7450
+ for (; u3 < o && w(t2.charCodeAt(u3)); ) u3++;
7451
+ b[t2.charCodeAt(u3)] && (i2 = r2 + 6, r2 = u3);
7452
+ } else s = t2.charCodeAt(r2);
7453
+ }
7454
+ let l2 = r2, d = 0;
7455
+ for (; r2 < o && (d = t2.charCodeAt(r2), b[d]); ) r2++;
7456
+ if (r2 === l2) {
7457
+ for (; r2 < o && !q(t2.charCodeAt(r2)); ) r2++;
7458
+ continue;
7459
+ }
7460
+ let h2 = t2.slice(l2, r2), f = r2;
7461
+ if (r2 >= o && (d = 0), w(d)) do
7462
+ r2++, d = r2 < o ? t2.charCodeAt(r2) : 0;
7463
+ while (w(d));
7464
+ if (d === 61) r2++;
7465
+ else if (d === 58 && r2 === f && r2 + 1 < o && w(t2.charCodeAt(r2 + 1))) r2 += 2;
7466
+ else {
7467
+ for (r2 = i2 === -1 ? f : i2; r2 < o && !q(t2.charCodeAt(r2)); ) r2++;
7468
+ continue;
7469
+ }
7470
+ let c2 = r2, a2 = r2;
7471
+ for (; a2 < o && w(t2.charCodeAt(a2)); ) a2++;
7472
+ let g = t2.charCodeAt(a2), p, y2 = false;
7473
+ if (g === 39 || g === 34 || g === 96) {
7474
+ let v = t2[a2], u3 = t2.indexOf(v, a2 + 1), m = -1, C = -1;
7475
+ for (; u3 !== -1; ) {
7476
+ let O = t2.charCodeAt(u3 - 1) === 92, E = u3 + 1;
7477
+ for (; E < o && !q(t2.charCodeAt(E)) && w(t2.charCodeAt(E)); ) E++;
7478
+ if ((E === o || q(t2.charCodeAt(E)) || t2.charCodeAt(E) === 35) && (m = u3, C = E), !O) break;
7479
+ u3 = t2.indexOf(v, u3 + 1);
7480
+ }
7481
+ if (m !== -1) {
7482
+ if (p = t2.slice(a2 + 1, m), r2 = C, t2.charCodeAt(r2) === 35) for (; r2 < o && !q(t2.charCodeAt(r2)); ) r2++;
7483
+ y2 = true;
7484
+ }
7485
+ }
7486
+ if (!y2) {
7487
+ let v = t2.indexOf(`
7488
+ `, c2);
7489
+ v === -1 && (v = o);
7490
+ let u3;
7491
+ if (o < 4096) u3 = t2.indexOf("#", c2), (u3 === -1 || u3 > v) && (u3 = v);
7492
+ else for (u3 = c2; u3 < v && t2.charCodeAt(u3) !== 35; ) u3++;
7493
+ let m = c2, C = u3;
7494
+ for (; m < C && w(t2.charCodeAt(m)); ) m++;
7495
+ for (; C > m && w(t2.charCodeAt(C - 1)); ) C--;
7496
+ let O = t2.charCodeAt(m);
7497
+ if (p = t2.slice(m, C), p.includes("\u2028") || p.includes("\u2029") ? p = p.replace(/^(['"`])([\s\S]*)\1$/mg, "$2") : C - m >= 2 && (O === 39 || O === 34 || O === 96) && t2.charCodeAt(C - 1) === O && (p = t2.slice(m + 1, C - 1)), r2 = u3, u3 < v) for (; r2 < o && !q(t2.charCodeAt(r2)); ) r2++;
7498
+ }
7499
+ g === 34 && (y2 || a2 < r2) && p.indexOf("\\") !== -1 && (p = p.replace(/\\n/g, `
7500
+ `).replace(/\\r/g, "\r")), n3[h2] = p;
7486
7501
  }
7487
- throw error63;
7502
+ return n3;
7488
7503
  }
7489
- const key = uri.password;
7490
- if (!key) {
7491
- const err = new Error("INVALID_DOTENV_KEY: Missing key part");
7492
- err.code = "INVALID_DOTENV_KEY";
7493
- throw err;
7504
+ function se(e, n3) {
7505
+ return n3 && $(n3.fast) ? oe(e) : ne(e);
7494
7506
  }
7495
- const environment = uri.searchParams.get("environment");
7496
- if (!environment) {
7497
- const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
7498
- err.code = "INVALID_DOTENV_KEY";
7499
- throw err;
7507
+ function T(e) {
7508
+ console.log(`\u2506 ${e}`);
7500
7509
  }
7501
- const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
7502
- const ciphertext = result.parsed[environmentKey];
7503
- if (!ciphertext) {
7504
- const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
7505
- err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
7506
- throw err;
7510
+ function ie(e) {
7511
+ console.error(`\u25C7 ${e}`);
7507
7512
  }
7508
- return { ciphertext, key };
7509
- }
7510
- function _vaultPath(options) {
7511
- let possibleVaultPath = null;
7512
- if (options && options.path && options.path.length > 0) {
7513
- if (Array.isArray(options.path)) {
7514
- for (const filepath of options.path) {
7515
- if (fs18.existsSync(filepath)) {
7516
- possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
7517
- }
7513
+ function V(e) {
7514
+ return e[0] === "~" ? I2.join(Z.homedir(), e.slice(1)) : e;
7515
+ }
7516
+ function ce(e = {}) {
7517
+ let n3 = { ...e };
7518
+ for (let t2 of Object.keys(n3)) n3[t2] === void 0 && delete n3[t2];
7519
+ return { ...B(), ...n3 };
7520
+ }
7521
+ function ae(e) {
7522
+ e = ce(e);
7523
+ let n3 = I2.resolve(process.cwd(), ".env"), t2 = "utf8", o = process.env;
7524
+ e && e.processEnv != null && (o = e.processEnv);
7525
+ let r2 = $(e && e.debug);
7526
+ e && e.encoding ? t2 = e.encoding : r2 && T("no encoding is specified (UTF-8 is used by default)");
7527
+ let s = [n3];
7528
+ if (e && e.path) if (!Array.isArray(e.path)) s = [V(e.path)];
7529
+ else {
7530
+ s = [];
7531
+ for (let c2 of e.path) s.push(V(c2));
7532
+ }
7533
+ let i2, l2 = {}, d = { fast: e.fast };
7534
+ for (let c2 of s) try {
7535
+ let a2 = A.parse(z2.readFileSync(c2, { encoding: t2 }), d);
7536
+ A.populate(l2, a2, e);
7537
+ } catch (a2) {
7538
+ r2 && T(`failed to load ${c2} ${a2.message}`), i2 = a2;
7539
+ }
7540
+ let h2 = A.populate(o, l2, e), f = $(Object.prototype.hasOwnProperty.call(e, "quiet") ? e.quiet : B(o).quiet);
7541
+ if (r2 || !f) {
7542
+ let c2 = Object.keys(h2).length, a2 = [];
7543
+ for (let g of s) try {
7544
+ let p = I2.relative(process.cwd(), g instanceof ee ? te(g) : g);
7545
+ a2.push(p);
7546
+ } catch (p) {
7547
+ r2 && T(`failed to load ${g} ${p.message}`), i2 = p;
7518
7548
  }
7519
- } else {
7520
- possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
7549
+ ie(`injected env (${c2}) from ${a2.join(",")}`);
7521
7550
  }
7522
- } else {
7523
- possibleVaultPath = path24.resolve(process.cwd(), ".env.vault");
7551
+ return i2 ? { parsed: l2, error: i2 } : { parsed: l2 };
7524
7552
  }
7525
- if (fs18.existsSync(possibleVaultPath)) {
7526
- return possibleVaultPath;
7553
+ function le(e) {
7554
+ return A.configDotenv(e);
7527
7555
  }
7528
- return null;
7529
- }
7530
- function _resolveHome(envPath) {
7531
- return envPath[0] === "~" ? path24.join(os4.homedir(), envPath.slice(1)) : envPath;
7532
- }
7533
- function _configVault(options) {
7534
- const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
7535
- const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
7536
- if (debug || !quiet) {
7537
- _log("loading env from encrypted .env.vault");
7538
- }
7539
- const parsed = DotenvModule._parseVault(options);
7540
- let processEnv = process.env;
7541
- if (options && options.processEnv != null) {
7542
- processEnv = options.processEnv;
7543
- }
7544
- DotenvModule.populate(processEnv, parsed, options);
7545
- return { parsed };
7546
- }
7547
- function configDotenv(options) {
7548
- const dotenvPath = path24.resolve(process.cwd(), ".env");
7549
- let encoding = "utf8";
7550
- let processEnv = process.env;
7551
- if (options && options.processEnv != null) {
7552
- processEnv = options.processEnv;
7553
- }
7554
- let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
7555
- let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
7556
- if (options && options.encoding) {
7557
- encoding = options.encoding;
7558
- } else {
7559
- if (debug) {
7560
- _debug("no encoding is specified (UTF-8 is used by default)");
7556
+ function fe(e, n3, t2 = {}) {
7557
+ let o = $(t2 && t2.debug), r2 = $(t2 && t2.override), s = {};
7558
+ if (e === null || typeof e != "object" || n3 === null || typeof n3 != "object") {
7559
+ let i2 = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
7560
+ throw i2.code = "OBJECT_REQUIRED", i2;
7561
7561
  }
7562
+ for (let i2 of Object.keys(n3)) Object.prototype.hasOwnProperty.call(e, i2) ? (r2 === true && (e[i2] = n3[i2], s[i2] = n3[i2]), o && T(r2 === true ? `"${i2}" is already defined and WAS overwritten` : `"${i2}" is already defined and was NOT overwritten`)) : (e[i2] = n3[i2], s[i2] = n3[i2]);
7563
+ return s;
7562
7564
  }
7563
- let optionPaths = [dotenvPath];
7564
- if (options && options.path) {
7565
- if (!Array.isArray(options.path)) {
7566
- optionPaths = [_resolveHome(options.path)];
7567
- } else {
7568
- optionPaths = [];
7569
- for (const filepath of options.path) {
7570
- optionPaths.push(_resolveHome(filepath));
7565
+ var A = { configDotenv: ae, config: le, parse: se, populate: fe };
7566
+ x.exports.configDotenv = A.configDotenv;
7567
+ x.exports.config = A.config;
7568
+ x.exports.parse = A.parse;
7569
+ x.exports.populate = A.populate;
7570
+ x.exports = A;
7571
+ });
7572
+ var M = j((Te, W2) => {
7573
+ var _ = __require("child_process"), ue = __require("fs"), L = __require("path");
7574
+ function de(e) {
7575
+ let n3 = ['"'], t2 = 0;
7576
+ for (let o of e) {
7577
+ if (o === "\\") {
7578
+ t2++;
7579
+ continue;
7571
7580
  }
7581
+ o === '"' ? n3.push("\\".repeat(t2 * 2 + 1), '"') : n3.push("\\".repeat(t2), o), t2 = 0;
7572
7582
  }
7583
+ return n3.push("\\".repeat(t2 * 2), '"'), n3.join("");
7573
7584
  }
7574
- let lastError;
7575
- const parsedAll = {};
7576
- for (const path25 of optionPaths) {
7577
- try {
7578
- const parsed = DotenvModule.parse(fs18.readFileSync(path25, { encoding }));
7579
- DotenvModule.populate(parsedAll, parsed, options);
7580
- } catch (e) {
7581
- if (debug) {
7582
- _debug(`failed to load ${path25} ${e.message}`);
7585
+ function H(e, n3 = 1) {
7586
+ for (let t2 = 0; t2 < n3; t2++) {
7587
+ let o = [];
7588
+ for (let r2 of e) {
7589
+ let s = r2.charCodeAt(0), i2 = s >= 48 && s <= 57 || s >= 65 && s <= 90 || s >= 97 && s <= 122, l2 = "\\/:._-".includes(r2);
7590
+ !i2 && !l2 && s < 128 && o.push("^"), o.push(r2);
7583
7591
  }
7584
- lastError = e;
7592
+ e = o.join("");
7585
7593
  }
7594
+ return e;
7595
+ }
7596
+ function P(e, n3) {
7597
+ let t2 = Object.keys(e).reverse().find((o) => o.toUpperCase() === n3);
7598
+ return t2 === void 0 ? void 0 : e[t2];
7586
7599
  }
7587
- const populated = DotenvModule.populate(processEnv, parsedAll, options);
7588
- debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
7589
- quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
7590
- if (debug || !quiet) {
7591
- const keysCount = Object.keys(populated).length;
7592
- const shortPaths = [];
7593
- for (const filePath of optionPaths) {
7600
+ function pe(e, n3, t2) {
7601
+ let o = (P(n3, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean), s = o.some((l2) => e.toLowerCase().endsWith(l2.toLowerCase())) ? ["", ...o] : [...o, ""], i2 = /[\\/]/.test(e) ? [t2] : [t2, ...(P(n3, "PATH") || "").split(";")];
7602
+ for (let l2 of i2) for (let d of s) {
7603
+ let h2 = L.resolve(t2, l2.replace(/^"|"$/g, ""), e + d);
7594
7604
  try {
7595
- const relative3 = path24.relative(process.cwd(), filePath);
7596
- shortPaths.push(relative3);
7597
- } catch (e) {
7598
- if (debug) {
7599
- _debug(`failed to load ${filePath} ${e.message}`);
7600
- }
7601
- lastError = e;
7605
+ if (ue.statSync(h2).isFile()) return h2;
7606
+ } catch {
7602
7607
  }
7603
7608
  }
7604
- _log(`injected env (${keysCount}) from ${shortPaths.join(",")} ${dim2(`// tip: ${_getRandomTip()}`)}`);
7605
- }
7606
- if (lastError) {
7607
- return { parsed: parsedAll, error: lastError };
7608
- } else {
7609
- return { parsed: parsedAll };
7610
7609
  }
7611
- }
7612
- function config3(options) {
7613
- if (_dotenvKey(options).length === 0) {
7614
- return DotenvModule.configDotenv(options);
7610
+ function he(e, n3, t2) {
7611
+ if (process.platform !== "win32") return _.spawn(e, n3, t2);
7612
+ let o = t2.env || process.env, r2 = pe(e, o, t2.cwd || process.cwd());
7613
+ if (r2 && /\.(?:exe|com)$/i.test(r2)) return _.spawn(r2, n3, t2);
7614
+ let s = /\.(?:bat|cmd)$/i.test(r2 || e), i2 = [H(L.normalize(r2 || e))];
7615
+ for (let d of n3) i2.push(H(de(d), s ? 2 : 1));
7616
+ let l2 = i2.join(" ");
7617
+ return _.spawn(P(o, "COMSPEC") || "cmd.exe", ["/d", "/v:off", "/s", "/c", `"${l2}"`], { ...t2, windowsVerbatimArguments: true });
7615
7618
  }
7616
- const vaultPath = _vaultPath(options);
7617
- if (!vaultPath) {
7618
- _warn(`you set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}`);
7619
- return DotenvModule.configDotenv(options);
7619
+ W2.exports = he;
7620
+ });
7621
+ var X = j(($e, F) => {
7622
+ var ge = __require("fs"), me = __require("os"), Q = __require("path"), ve = __require("child_process"), Ce = M(), R2 = N(), { optionsFromEnv: J } = k();
7623
+ function D() {
7624
+ console.log(["Usage: dotenv run [--help] [-q|--quiet] [--debug] [--override] [--fast] [-f|--file <paths>] [--] <command> [args...]", "", "Run a command with environment variables from a .env file.", "Place dotenv options before the command; all following arguments go to the command.", "", "Options:", " -f, --file <paths> .env paths, comma-separated or repeated (default: .env)", " -q, --quiet suppress the injected env message", " --debug enable debug logging", " --override override existing environment variables", " --fast use the faster character-scanner parser", "", "Environment variables (DOTENV_CONFIG_* names remain as fallbacks):", " DOTENV_PATH, DOTENV_ENCODING, DOTENV_QUIET,", " DOTENV_DEBUG, DOTENV_OVERRIDE,", " DOTENV_FAST"].join(`
7625
+ `));
7620
7626
  }
7621
- return DotenvModule._configVault(options);
7622
- }
7623
- function decrypt(encrypted, keyStr) {
7624
- const key = Buffer.from(keyStr.slice(-64), "hex");
7625
- let ciphertext = Buffer.from(encrypted, "base64");
7626
- const nonce = ciphertext.subarray(0, 12);
7627
- const authTag = ciphertext.subarray(-16);
7628
- ciphertext = ciphertext.subarray(12, -16);
7629
- try {
7630
- const aesgcm = crypto3.createDecipheriv("aes-256-gcm", key, nonce);
7631
- aesgcm.setAuthTag(authTag);
7632
- return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
7633
- } catch (error63) {
7634
- const isRange = error63 instanceof RangeError;
7635
- const invalidKeyLength = error63.message === "Invalid key length";
7636
- const decryptionFailed = error63.message === "Unsupported state or unable to authenticate data";
7637
- if (isRange || invalidKeyLength) {
7638
- const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
7639
- err.code = "INVALID_DOTENV_KEY";
7640
- throw err;
7641
- } else if (decryptionFailed) {
7642
- const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
7643
- err.code = "DECRYPTION_FAILED";
7644
- throw err;
7645
- } else {
7646
- throw error63;
7627
+ function we(e) {
7628
+ let n3 = [], t2 = false, o, r2, s, i2, l2 = -1;
7629
+ for (let h2 = 0; h2 < e.length; h2++) {
7630
+ let f = e[h2];
7631
+ if (f === "--") {
7632
+ l2 = h2 + 1;
7633
+ break;
7634
+ }
7635
+ if (f === "--help" || f === "-h") return { help: true };
7636
+ if (f === "--quiet" || f === "-q") {
7637
+ o = true;
7638
+ continue;
7639
+ }
7640
+ if (f === "--debug") {
7641
+ r2 = true;
7642
+ continue;
7643
+ }
7644
+ if (f === "--override") {
7645
+ s = true;
7646
+ continue;
7647
+ }
7648
+ if (f === "--fast") {
7649
+ i2 = true;
7650
+ continue;
7651
+ }
7652
+ if (f === "-f" || f === "--file" || f.startsWith("-f=") || f.startsWith("--file=")) {
7653
+ let c2 = f.indexOf("="), a2 = c2 === -1 ? f : f.slice(0, c2), g = c2 === -1 ? e[++h2] : f.slice(c2 + 1);
7654
+ if (!g || g === "--") return { error: `${a2} requires a path` };
7655
+ let p = g.split(",").map((y2) => y2.trim()).filter(Boolean);
7656
+ if (p.length === 0) return { error: `${a2} requires a path` };
7657
+ n3.push(...p), t2 = true;
7658
+ continue;
7659
+ }
7660
+ if (f.startsWith("-")) return { error: `unknown option: ${f}` };
7661
+ l2 = h2;
7662
+ break;
7647
7663
  }
7664
+ let d = l2 === -1 ? [] : e.slice(l2);
7665
+ return { paths: n3, pathSet: t2, quiet: o, debug: r2, override: s, fast: i2, command: d };
7648
7666
  }
7649
- }
7650
- function populate(processEnv, parsed, options = {}) {
7651
- const debug = Boolean(options && options.debug);
7652
- const override = Boolean(options && options.override);
7653
- const populated = {};
7654
- if (typeof parsed !== "object") {
7655
- const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
7656
- err.code = "OBJECT_REQUIRED";
7657
- throw err;
7667
+ function Ae(e) {
7668
+ return e[0] === "~" ? Q.join(me.homedir(), e.slice(1)) : e;
7669
+ }
7670
+ function Ee(e) {
7671
+ let n3 = J(), t2 = { encoding: n3.encoding || "utf8", quiet: n3.quiet, debug: n3.debug === true, override: n3.override === true, fast: n3.fast === true, paths: [".env"], defaultPath: true };
7672
+ return n3.path != null && (t2.paths = [n3.path], t2.defaultPath = false), e.pathSet && (t2.paths = e.paths, t2.defaultPath = false), e.quiet != null && (t2.quiet = e.quiet), e.debug != null && (t2.debug = e.debug), e.override != null && (t2.override = e.override), e.fast != null && (t2.fast = e.fast), t2;
7658
7673
  }
7659
- for (const key of Object.keys(parsed)) {
7660
- if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
7661
- if (override === true) {
7662
- processEnv[key] = parsed[key];
7663
- populated[key] = parsed[key];
7674
+ function be(e) {
7675
+ let n3 = {}, t2 = [], o = { override: e.override, debug: e.debug };
7676
+ for (let s of e.paths) {
7677
+ let i2 = Q.resolve(process.cwd(), Ae(s));
7678
+ try {
7679
+ let l2 = R2.parse(ge.readFileSync(i2, { encoding: e.encoding }), { fast: e.fast });
7680
+ R2.populate(n3, l2, o), t2.push(s);
7681
+ } catch (l2) {
7682
+ if (e.debug && console.log(`\u2506 failed to load ${s} ${l2.message}`), !(e.defaultPath && l2.code === "ENOENT")) throw l2;
7664
7683
  }
7665
- if (debug) {
7666
- if (override === true) {
7667
- _debug(`"${key}" is already defined and WAS overwritten`);
7668
- } else {
7669
- _debug(`"${key}" is already defined and was NOT overwritten`);
7684
+ }
7685
+ return { injected: R2.populate(process.env, n3, o), loadedPaths: t2 };
7686
+ }
7687
+ function K(e) {
7688
+ let n3 = e[0];
7689
+ if (n3 === "--help" || n3 === "-h") {
7690
+ D();
7691
+ return;
7692
+ }
7693
+ if (n3 !== "run") {
7694
+ D(), process.exitCode = 1;
7695
+ return;
7696
+ }
7697
+ let t2 = we(e.slice(1));
7698
+ if (t2.help) {
7699
+ D();
7700
+ return;
7701
+ }
7702
+ if (t2.error) {
7703
+ console.error(`dotenv: ${t2.error}`), D(), process.exitCode = 1;
7704
+ return;
7705
+ }
7706
+ if (t2.command.length === 0) {
7707
+ D(), process.exitCode = 1;
7708
+ return;
7709
+ }
7710
+ let o = Ee(t2);
7711
+ try {
7712
+ let c2 = be(o);
7713
+ if (!(o.quiet == null ? J().quiet : o.quiet)) {
7714
+ let g = `\u25C7 injected env (${Object.keys(c2.injected).length})`;
7715
+ c2.loadedPaths.length > 0 && (g += ` from ${c2.loadedPaths.join(", ")}`), console.error(g);
7716
+ }
7717
+ } catch (c2) {
7718
+ console.error(`dotenv: ${c2.message}`), process.exitCode = 1;
7719
+ return;
7720
+ }
7721
+ let r2 = !!process.stdin.isTTY, s = process.platform !== "win32" && !r2, i2 = Ce(t2.command[0], t2.command.slice(1), { stdio: "inherit", detached: s }), l2 = /* @__PURE__ */ new Map(), d = 0;
7722
+ function h2(c2) {
7723
+ if (!(!i2.pid || i2.exitCode !== null || i2.signalCode !== null)) {
7724
+ if (process.platform === "win32") {
7725
+ ve.spawnSync("taskkill", ["/pid", String(i2.pid), "/T", "/F"], { stdio: "ignore" });
7726
+ return;
7727
+ }
7728
+ try {
7729
+ process.kill(s ? -i2.pid : i2.pid, c2);
7730
+ } catch (a2) {
7731
+ if (a2.code !== "ESRCH") throw a2;
7670
7732
  }
7671
7733
  }
7672
- } else {
7673
- processEnv[key] = parsed[key];
7674
- populated[key] = parsed[key];
7675
7734
  }
7735
+ function f() {
7736
+ for (let [c2, a2] of l2) process.removeListener(c2, a2);
7737
+ }
7738
+ for (let c2 of ["SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"]) {
7739
+ let a2 = () => {
7740
+ if (c2 === "SIGINT") {
7741
+ if (d++, r2 && process.platform !== "win32" && d === 1) return;
7742
+ if (d > 1) {
7743
+ h2(d === 2 ? "SIGTERM" : "SIGKILL");
7744
+ return;
7745
+ }
7746
+ }
7747
+ h2(c2);
7748
+ };
7749
+ l2.set(c2, a2), process.on(c2, a2);
7750
+ }
7751
+ i2.on("error", function(c2) {
7752
+ f(), console.error(`dotenv: ${c2.message}`), process.exitCode = 1;
7753
+ }), i2.on("exit", function(c2, a2) {
7754
+ f(), typeof c2 == "number" ? process.exit(c2) : (setInterval(() => {
7755
+ }, 1e3), process.kill(process.pid, a2));
7756
+ });
7676
7757
  }
7677
- return populated;
7678
- }
7679
- var DotenvModule = {
7680
- configDotenv,
7681
- _configVault,
7682
- _parseVault,
7683
- config: config3,
7684
- decrypt,
7685
- parse: parse3,
7686
- populate
7687
- };
7688
- module.exports.configDotenv = DotenvModule.configDotenv;
7689
- module.exports._configVault = DotenvModule._configVault;
7690
- module.exports._parseVault = DotenvModule._parseVault;
7691
- module.exports.config = DotenvModule.config;
7692
- module.exports.decrypt = DotenvModule.decrypt;
7693
- module.exports.parse = DotenvModule.parse;
7694
- module.exports.populate = DotenvModule.populate;
7695
- module.exports = DotenvModule;
7758
+ F.exports = K;
7759
+ __require.main === F && K(process.argv.slice(2));
7760
+ });
7761
+ var S = N();
7762
+ var qe = X();
7763
+ module.exports = S;
7764
+ module.exports.config = S.config;
7765
+ module.exports.configDotenv = S.configDotenv;
7766
+ module.exports.parse = S.parse;
7767
+ module.exports.populate = S.populate;
7768
+ __require.main === module && qe(process.argv.slice(2));
7696
7769
  }
7697
7770
  });
7698
7771
 
@@ -8843,8 +8916,8 @@ var require_src = __commonJS({
8843
8916
  });
8844
8917
 
8845
8918
  // ../argent-cli/src/run.ts
8846
- import * as fs11 from "node:fs";
8847
- import * as path16 from "node:path";
8919
+ import * as fs12 from "node:fs";
8920
+ import * as path17 from "node:path";
8848
8921
 
8849
8922
  // ../argent-tools-client/src/launcher.ts
8850
8923
  import * as net from "node:net";
@@ -8885,7 +8958,7 @@ function generateAuthToken() {
8885
8958
  return generateToken();
8886
8959
  }
8887
8960
  function findFreePort() {
8888
- return new Promise((resolve12, reject) => {
8961
+ return new Promise((resolve13, reject) => {
8889
8962
  const srv = net.createServer();
8890
8963
  srv.listen(0, "127.0.0.1", () => {
8891
8964
  const addr = srv.address();
@@ -8896,7 +8969,7 @@ function findFreePort() {
8896
8969
  const port = addr.port;
8897
8970
  srv.close((err) => {
8898
8971
  if (err) reject(err);
8899
- else resolve12(port);
8972
+ else resolve13(port);
8900
8973
  });
8901
8974
  });
8902
8975
  srv.on("error", reject);
@@ -8997,7 +9070,7 @@ function killSpawnedChild(child, pid) {
8997
9070
  }
8998
9071
  }
8999
9072
  function spawnToolsServer(paths, port, options = {}) {
9000
- return new Promise((resolve12, reject) => {
9073
+ return new Promise((resolve13, reject) => {
9001
9074
  let logFd;
9002
9075
  try {
9003
9076
  fs.mkdirSync(STATE_DIR, { recursive: true });
@@ -9043,7 +9116,7 @@ function spawnToolsServer(paths, port, options = {}) {
9043
9116
  rl.close();
9044
9117
  child.stdout?.resume();
9045
9118
  child.stdout?.unref?.();
9046
- settle2(() => resolve12({ port: actualPort, pid }));
9119
+ settle2(() => resolve13({ port: actualPort, pid }));
9047
9120
  }
9048
9121
  });
9049
9122
  child.on("error", (err) => {
@@ -9357,10 +9430,11 @@ async function ensureToolsServer(paths) {
9357
9430
  }
9358
9431
 
9359
9432
  // ../argent-tools-client/src/tools-client.ts
9360
- import * as path6 from "node:path";
9433
+ import * as path7 from "node:path";
9361
9434
 
9362
9435
  // ../registry/src/types.ts
9363
9436
  var LINKED_CALL_HEADER = "x-argent-linked";
9437
+ var E2E_DIR_CLIENT_HEADER = "x-argent-e2e-dir";
9364
9438
 
9365
9439
  // ../registry/src/artifacts.ts
9366
9440
  import { stat } from "node:fs/promises";
@@ -9398,19 +9472,98 @@ function toolStepFiles(specs, args) {
9398
9472
  }
9399
9473
  return files;
9400
9474
  }
9401
- function isClientFileArgument({ spec, path: path24 }) {
9402
- return spec.kind === "file" && spec.path === `\${${spec.target}}` && path24.startsWith("/") && hasToolFileExtension(path24);
9475
+ function isClientFileArgument({ spec, path: path25 }) {
9476
+ return spec.kind === "file" && spec.path === `\${${spec.target}}` && path25.startsWith("/") && hasToolFileExtension(path25);
9403
9477
  }
9404
9478
 
9405
9479
  // ../registry/src/flow-file-refs.ts
9480
+ import * as fs3 from "node:fs/promises";
9481
+ import * as path3 from "node:path";
9482
+
9483
+ // ../registry/src/e2e-dirs.ts
9406
9484
  import * as fs2 from "node:fs/promises";
9407
9485
  import * as path2 from "node:path";
9486
+ var E2E_DIR = path2.join(".argent", "e2e");
9487
+ var LEGACY_E2E_DIRS = Object.freeze([path2.join(".argent", "flows")]);
9488
+ var E2E_DIRS = Object.freeze([E2E_DIR, ...LEGACY_E2E_DIRS]);
9489
+ function e2eDirFor(projectRoot) {
9490
+ return path2.join(projectRoot, E2E_DIR);
9491
+ }
9492
+ function e2eDirsFor(projectRoot) {
9493
+ return E2E_DIRS.map((dir) => path2.join(projectRoot, dir));
9494
+ }
9495
+ function e2eFileCandidates(projectRoot, name) {
9496
+ return e2eDirsFor(projectRoot).map((dir) => path2.join(dir, `${name}.yaml`));
9497
+ }
9498
+ async function exists(file2) {
9499
+ return fs2.stat(file2).then(
9500
+ () => true,
9501
+ () => false
9502
+ );
9503
+ }
9504
+ async function pickE2eFile(candidates) {
9505
+ for (let i2 = 0; i2 < candidates.length; i2++) {
9506
+ if (!await exists(candidates[i2])) continue;
9507
+ let shadowed;
9508
+ for (const later of candidates.slice(i2 + 1)) {
9509
+ if (await exists(later)) {
9510
+ shadowed = later;
9511
+ break;
9512
+ }
9513
+ }
9514
+ return {
9515
+ path: candidates[i2],
9516
+ exists: true,
9517
+ legacy: i2 > 0,
9518
+ ...shadowed === void 0 ? {} : { shadowed }
9519
+ };
9520
+ }
9521
+ return { path: candidates[0], exists: false, legacy: false };
9522
+ }
9523
+ function resolveE2eFile(projectRoot, name) {
9524
+ return pickE2eFile(e2eFileCandidates(projectRoot, name));
9525
+ }
9526
+ function e2eShadowWarning(used, shadowed) {
9527
+ return `${shadowed} is not used: ${used} has the same name and is read first.`;
9528
+ }
9529
+ var E2E_DIR_NAMES = E2E_DIRS.map((dir) => path2.basename(dir));
9530
+ function e2eDirProject(dir) {
9531
+ const trimmed = dir.length > 1 ? dir.replace(/[\\/]+$/, "") : dir;
9532
+ const argent = path2.dirname(trimmed);
9533
+ if (!E2E_DIR_NAMES.includes(path2.basename(trimmed)) || path2.basename(argent) !== ".argent") {
9534
+ return null;
9535
+ }
9536
+ return path2.dirname(argent);
9537
+ }
9538
+ function e2eRunFallbackDirs(anchorDir, target) {
9539
+ if (target.includes("/") || target.includes("\\")) return [];
9540
+ const project = e2eDirProject(anchorDir);
9541
+ if (project === null) return [];
9542
+ const anchor2 = path2.resolve(anchorDir);
9543
+ return e2eDirsFor(project).filter((dir) => path2.resolve(dir) !== anchor2);
9544
+ }
9545
+
9546
+ // ../registry/src/tool-ids.ts
9547
+ var TOOL_ID_ALIASES = Object.freeze({
9548
+ "flow-start-recording": "e2e-start-recording",
9549
+ "flow-add-step": "e2e-add-step",
9550
+ "flow-add-echo": "e2e-add-echo",
9551
+ "flow-add-script": "e2e-add-script",
9552
+ "flow-finish-recording": "e2e-finish-recording",
9553
+ "flow-read-prerequisite": "e2e-read-prerequisite",
9554
+ "flow-execute": "e2e-execute"
9555
+ });
9556
+ function canonicalToolId(id) {
9557
+ return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
9558
+ }
9559
+
9560
+ // ../registry/src/flow-file-refs.ts
9408
9561
  async function canonicalFlowPath(p) {
9409
9562
  try {
9410
- return await fs2.realpath(p);
9563
+ return await fs3.realpath(p);
9411
9564
  } catch {
9412
9565
  try {
9413
- return path2.join(await fs2.realpath(path2.dirname(p)), path2.basename(p));
9566
+ return path3.join(await fs3.realpath(path3.dirname(p)), path3.basename(p));
9414
9567
  } catch {
9415
9568
  return p;
9416
9569
  }
@@ -9419,7 +9572,7 @@ async function canonicalFlowPath(p) {
9419
9572
  function completeRunExtension(value) {
9420
9573
  if (value.endsWith(".yaml")) return value;
9421
9574
  const candidate = `${value}.yaml`;
9422
- return FLOW_FILE_NAME_PATTERN.test(path2.posix.basename(candidate)) ? candidate : value;
9575
+ return FLOW_FILE_NAME_PATTERN.test(path3.posix.basename(candidate)) ? candidate : value;
9423
9576
  }
9424
9577
  var MAX_RUN_DEPTH = 20;
9425
9578
  var MAX_BLOCK_NESTING = 64;
@@ -9438,16 +9591,16 @@ function collectFlowRequests(doc) {
9438
9591
  for (const step of steps) {
9439
9592
  if (!isRecord(step)) continue;
9440
9593
  const run2 = step.run;
9441
- if (typeof run2 === "string" && !run2.includes("\\") && !path2.posix.isAbsolute(run2) && !/^[A-Za-z]:/.test(run2)) {
9594
+ if (typeof run2 === "string" && !run2.includes("\\") && !path3.posix.isAbsolute(run2) && !/^[A-Za-z]:/.test(run2)) {
9442
9595
  const target = completeRunExtension(run2);
9443
- if (FLOW_FILE_NAME_PATTERN.test(path2.posix.basename(target))) runTargets.add(target);
9596
+ if (FLOW_FILE_NAME_PATTERN.test(path3.posix.basename(target))) runTargets.add(target);
9444
9597
  }
9445
9598
  const snapshot = isRecord(step.snapshot) ? step.snapshot.name : step.snapshot;
9446
9599
  if (typeof snapshot === "string" && FLOW_NAME_PATTERN.test(snapshot)) snapshots.add(snapshot);
9447
9600
  if (typeof step.tool === "string") {
9448
9601
  const args = isRecord(step.args) ? step.args : {};
9449
9602
  toolSteps.push({ tool: step.tool, args });
9450
- const target = step.tool === "flow-execute" ? nestedFlowTarget(args) : void 0;
9603
+ const target = canonicalToolId(step.tool) === "e2e-execute" ? nestedFlowTarget(args) : void 0;
9451
9604
  if (target !== void 0) nested.push({ target, args });
9452
9605
  }
9453
9606
  visit2(step.steps, depth + 1);
@@ -9457,14 +9610,14 @@ function collectFlowRequests(doc) {
9457
9610
  return { runTargets: [...runTargets], snapshots: [...snapshots], toolSteps, nested };
9458
9611
  }
9459
9612
  function baselineKeyFor(canonicalPath, flowName) {
9460
- const stem = path2.basename(canonicalPath, ".yaml");
9613
+ const stem = path3.basename(canonicalPath, ".yaml");
9461
9614
  return FLOW_NAME_PATTERN.test(stem) ? stem : flowName;
9462
9615
  }
9463
9616
  function flowMemberKey(anchorDir, target) {
9464
9617
  return `${anchorDir}\0${target}`;
9465
9618
  }
9466
9619
  async function classifyOnDiskSpelling(dir, base, addressable = FLOW_FILE_NAME_PATTERN) {
9467
- const entries = await fs2.readdir(dir).catch(() => null);
9620
+ const entries = await fs3.readdir(dir).catch(() => null);
9468
9621
  if (entries === null || entries.includes(base)) return { state: "listed" };
9469
9622
  const actual = entries.find((entry) => entry.toLowerCase() === base.toLowerCase());
9470
9623
  if (actual === void 0) return { state: "absent" };
@@ -9476,19 +9629,15 @@ function nestedFlowTarget(args) {
9476
9629
  if (flowPath === void 0) {
9477
9630
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
9478
9631
  if (!isResolvedAbsolute(projectRoot)) return void 0;
9479
- return {
9480
- kind: "name",
9481
- projectRoot,
9482
- name,
9483
- path: path2.join(projectRoot, ".argent", "flows", `${name}.yaml`)
9484
- };
9632
+ const paths = e2eFileCandidates(projectRoot, name);
9633
+ return { kind: "name", projectRoot, name, path: paths[0], paths };
9485
9634
  }
9486
9635
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
9487
- if (!FLOW_FILE_NAME_PATTERN.test(path2.basename(flowPath))) return void 0;
9636
+ if (!FLOW_FILE_NAME_PATTERN.test(path3.basename(flowPath))) return void 0;
9488
9637
  return { kind: "flow_path", path: flowPath };
9489
9638
  }
9490
9639
  function isResolvedAbsolute(value) {
9491
- return typeof value === "string" && path2.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
9640
+ return typeof value === "string" && path3.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
9492
9641
  }
9493
9642
 
9494
9643
  // ../registry/src/failure-codes.ts
@@ -9608,6 +9757,11 @@ var FAILURE_CODES = {
9608
9757
  // a device that is not foldable, no hinge route, a remote simulator.
9609
9758
  IOS_FOLD_FAILED: "IOS_FOLD_FAILED",
9610
9759
  IOS_FOLD_UNSUPPORTED: "IOS_FOLD_UNSUPPORTED",
9760
+ // The hinge of a foldable Android emulator: the console refused the move or
9761
+ // the guest never committed the state vs. nothing to fold — a phone profile,
9762
+ // a physical device.
9763
+ ANDROID_FOLD_FAILED: "ANDROID_FOLD_FAILED",
9764
+ ANDROID_FOLD_UNSUPPORTED: "ANDROID_FOLD_UNSUPPORTED",
9611
9765
  PASTE_CLIPBOARD_SET_FAILED: "PASTE_CLIPBOARD_SET_FAILED",
9612
9766
  PASTE_CLIPBOARD_UNSUPPORTED: "PASTE_CLIPBOARD_UNSUPPORTED",
9613
9767
  SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
@@ -10665,10 +10819,10 @@ function mergeDefs(...defs) {
10665
10819
  function cloneDef(schema) {
10666
10820
  return mergeDefs(schema._zod.def);
10667
10821
  }
10668
- function getElementAtPath(obj, path24) {
10669
- if (!path24)
10822
+ function getElementAtPath(obj, path25) {
10823
+ if (!path25)
10670
10824
  return obj;
10671
- return path24.reduce((acc, key) => acc?.[key], obj);
10825
+ return path25.reduce((acc, key) => acc?.[key], obj);
10672
10826
  }
10673
10827
  function promiseAllObject(promisesObj) {
10674
10828
  const keys = Object.keys(promisesObj);
@@ -11008,11 +11162,11 @@ function explicitlyAborted(x, startIndex = 0) {
11008
11162
  }
11009
11163
  return false;
11010
11164
  }
11011
- function prefixIssues(path24, issues) {
11165
+ function prefixIssues(path25, issues) {
11012
11166
  return issues.map((iss) => {
11013
11167
  var _a3;
11014
11168
  (_a3 = iss).path ?? (_a3.path = []);
11015
- iss.path.unshift(path24);
11169
+ iss.path.unshift(path25);
11016
11170
  return iss;
11017
11171
  });
11018
11172
  }
@@ -11474,16 +11628,16 @@ function flattenError(error63, mapper = (issue2) => issue2.message) {
11474
11628
  }
11475
11629
  function formatError(error63, mapper = (issue2) => issue2.message) {
11476
11630
  const fieldErrors = { _errors: [] };
11477
- const processError = (error64, path24 = []) => {
11631
+ const processError = (error64, path25 = []) => {
11478
11632
  for (const issue2 of error64.issues) {
11479
11633
  if (issue2.code === "invalid_union" && issue2.errors.length) {
11480
- issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
11634
+ issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
11481
11635
  } else if (issue2.code === "invalid_key") {
11482
- processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11636
+ processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
11483
11637
  } else if (issue2.code === "invalid_element") {
11484
- processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11638
+ processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
11485
11639
  } else {
11486
- const fullpath = [...path24, ...issue2.path];
11640
+ const fullpath = [...path25, ...issue2.path];
11487
11641
  if (fullpath.length === 0) {
11488
11642
  fieldErrors._errors.push(mapper(issue2));
11489
11643
  } else {
@@ -11522,17 +11676,17 @@ function formatError(error63, mapper = (issue2) => issue2.message) {
11522
11676
  }
11523
11677
  function treeifyError(error63, mapper = (issue2) => issue2.message) {
11524
11678
  const result = { errors: [] };
11525
- const processError = (error64, path24 = []) => {
11679
+ const processError = (error64, path25 = []) => {
11526
11680
  var _a3;
11527
11681
  for (const issue2 of error64.issues) {
11528
11682
  if (issue2.code === "invalid_union" && issue2.errors.length) {
11529
- issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
11683
+ issue2.errors.map((issues) => processError({ issues }, [...path25, ...issue2.path]));
11530
11684
  } else if (issue2.code === "invalid_key") {
11531
- processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11685
+ processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
11532
11686
  } else if (issue2.code === "invalid_element") {
11533
- processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11687
+ processError({ issues: issue2.issues }, [...path25, ...issue2.path]);
11534
11688
  } else {
11535
- const fullpath = [...path24, ...issue2.path];
11689
+ const fullpath = [...path25, ...issue2.path];
11536
11690
  if (fullpath.length === 0) {
11537
11691
  result.errors.push(mapper(issue2));
11538
11692
  continue;
@@ -11571,8 +11725,8 @@ function treeifyError(error63, mapper = (issue2) => issue2.message) {
11571
11725
  }
11572
11726
  function toDotPath(_path) {
11573
11727
  const segs = [];
11574
- const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11575
- for (const seg of path24) {
11728
+ const path25 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11729
+ for (const seg of path25) {
11576
11730
  if (typeof seg === "number")
11577
11731
  segs.push(`[${seg}]`);
11578
11732
  else if (typeof seg === "symbol")
@@ -14915,7 +15069,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
14915
15069
  var NONE = 0;
14916
15070
  var ASSUMED = 1;
14917
15071
  var PROVEN = 2;
14918
- function isRecursive(inst, stack, resolve12) {
15072
+ function isRecursive(inst, stack, resolve13) {
14919
15073
  const cached3 = recursive.get(inst);
14920
15074
  if (cached3 !== void 0)
14921
15075
  return cached3 ? PROVEN : NONE;
@@ -14925,7 +15079,7 @@ function isRecursive(inst, stack, resolve12) {
14925
15079
  let result = NONE;
14926
15080
  const check2 = (child) => {
14927
15081
  if (result !== PROVEN && child?._zod) {
14928
- const answer = isRecursive(child, stack, resolve12);
15082
+ const answer = isRecursive(child, stack, resolve13);
14929
15083
  if (answer > result)
14930
15084
  result = answer;
14931
15085
  }
@@ -14936,7 +15090,7 @@ function isRecursive(inst, stack, resolve12) {
14936
15090
  const desc = Object.getOwnPropertyDescriptor(sh, key);
14937
15091
  if (spread && !desc.enumerable)
14938
15092
  continue;
14939
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve12) : NONE;
15093
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve13) : NONE;
14940
15094
  if (child > answer)
14941
15095
  answer = child;
14942
15096
  }
@@ -15000,7 +15154,7 @@ function isRecursive(inst, stack, resolve12) {
15000
15154
  break;
15001
15155
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
15002
15156
  case "lazy": {
15003
- const inner = def._cachedInner ?? (resolve12 ? inst._zod.innerType : void 0);
15157
+ const inner = def._cachedInner ?? (resolve13 ? inst._zod.innerType : void 0);
15004
15158
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
15005
15159
  break;
15006
15160
  }
@@ -28710,13 +28864,13 @@ function resolveRef(ref, ctx) {
28710
28864
  if (!ref.startsWith("#")) {
28711
28865
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
28712
28866
  }
28713
- const path24 = ref.slice(1).split("/").filter(Boolean);
28714
- if (path24.length === 0) {
28867
+ const path25 = ref.slice(1).split("/").filter(Boolean);
28868
+ if (path25.length === 0) {
28715
28869
  return ctx.rootSchema;
28716
28870
  }
28717
28871
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
28718
- if (path24[0] === defsKey) {
28719
- const key = path24[1] === void 0 ? void 0 : decodeJSONPointerSegment(path24[1]);
28872
+ if (path25[0] === defsKey) {
28873
+ const key = path25[1] === void 0 ? void 0 : decodeJSONPointerSegment(path25[1]);
28720
28874
  if (!key || !ctx.defs[key]) {
28721
28875
  throw new Error(`Reference not found: ${ref}`);
28722
28876
  }
@@ -29569,9 +29723,9 @@ function date4(params) {
29569
29723
  import { randomUUID as randomUUID2 } from "node:crypto";
29570
29724
  import { AsyncLocalStorage } from "node:async_hooks";
29571
29725
  var resolvedDuringInvocation = new AsyncLocalStorage();
29572
- function valueAtPath(root, path24) {
29726
+ function valueAtPath(root, path25) {
29573
29727
  let current = root;
29574
- for (const key of path24) {
29728
+ for (const key of path25) {
29575
29729
  if (current === null || typeof current !== "object") return void 0;
29576
29730
  if (!Object.hasOwn(current, key)) return void 0;
29577
29731
  current = current[key];
@@ -29629,11 +29783,11 @@ function describeParamIssues(error63, params) {
29629
29783
  }
29630
29784
 
29631
29785
  // ../argent-tools-client/src/link-config.ts
29632
- import * as path3 from "node:path";
29786
+ import * as path4 from "node:path";
29633
29787
  import { homedir as homedir2 } from "node:os";
29634
29788
  import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2, chmod as chmod2 } from "node:fs/promises";
29635
- var LINK_DIR = path3.join(homedir2(), ".argent");
29636
- var LINK_FILE = path3.join(LINK_DIR, "link.json");
29789
+ var LINK_DIR = path4.join(homedir2(), ".argent");
29790
+ var LINK_FILE = path4.join(LINK_DIR, "link.json");
29637
29791
  async function readLinkConfig() {
29638
29792
  try {
29639
29793
  const raw = await readFile2(LINK_FILE, "utf8");
@@ -29731,8 +29885,8 @@ function parseLinkTarget(input2) {
29731
29885
  const host = u3.hostname.startsWith("[") ? u3.hostname.slice(1, -1) : u3.hostname;
29732
29886
  if (!host) throw new Error(`URL "${input2}" is missing a host.`);
29733
29887
  const port = u3.port ? Number(u3.port) : u3.protocol === "https:" ? 443 : 80;
29734
- const path24 = u3.pathname === "/" ? "" : u3.pathname.replace(/\/+$/, "");
29735
- const url2 = `${u3.protocol}//${u3.host}${path24}`;
29888
+ const path25 = u3.pathname === "/" ? "" : u3.pathname.replace(/\/+$/, "");
29889
+ const url2 = `${u3.protocol}//${u3.host}${path25}`;
29736
29890
  const token = u3.username ? decodeURIComponent(u3.username) : void 0;
29737
29891
  return { url: url2, host, port, ...token ? { token } : {} };
29738
29892
  }
@@ -29748,22 +29902,22 @@ import {
29748
29902
  realpath as realpath2,
29749
29903
  rename as rename2,
29750
29904
  rm as rm2,
29751
- stat as stat2,
29905
+ stat as stat3,
29752
29906
  writeFile as writeFile3
29753
29907
  } from "node:fs/promises";
29754
29908
  import { constants, tmpdir } from "node:os";
29755
- import * as path4 from "node:path";
29909
+ import * as path5 from "node:path";
29756
29910
 
29757
29911
  // ../archive/src/index.ts
29758
29912
  import { execFile } from "node:child_process";
29759
29913
  import { rm, readdir as readdir3 } from "node:fs/promises";
29760
- import { basename as basename3, dirname as dirname3, join as join4, posix as posix2, resolve as resolve2, sep as sep2 } from "node:path";
29914
+ import { basename as basename4, dirname as dirname4, join as join5, posix as posix2, resolve as resolve3, sep as sep2 } from "node:path";
29761
29915
  import { promisify } from "node:util";
29762
29916
  var execFileAsync = promisify(execFile);
29763
29917
  var ArchiveError = class extends Error {
29764
29918
  };
29765
29919
  function createTarGzArgs(sourcePath, target) {
29766
- return ["-czf", target, "-C", dirname3(sourcePath), basename3(sourcePath)];
29920
+ return ["-czf", target, "-C", dirname4(sourcePath), basename4(sourcePath)];
29767
29921
  }
29768
29922
  async function createTarGzFile(sourcePath, tarPath) {
29769
29923
  try {
@@ -29785,8 +29939,8 @@ function isSafeTarMember(memberPath, destDir) {
29785
29939
  if (relative3 === ".." || relative3.startsWith("../") || relative3.split("/").includes("..")) {
29786
29940
  return false;
29787
29941
  }
29788
- const root = resolve2(destDir);
29789
- const resolved = resolve2(destDir, relative3);
29942
+ const root = resolve3(destDir);
29943
+ const resolved = resolve3(destDir, relative3);
29790
29944
  return resolved === root || resolved.startsWith(root + sep2);
29791
29945
  }
29792
29946
  async function listTarMembers(tarPath) {
@@ -29840,7 +29994,7 @@ async function assertSafeArchive(tarPath, destDir) {
29840
29994
  async function resolveMember(destDir, expectedName) {
29841
29995
  const entries = await readdir3(destDir);
29842
29996
  if (entries.includes(expectedName)) {
29843
- return join4(destDir, expectedName);
29997
+ return join5(destDir, expectedName);
29844
29998
  }
29845
29999
  const real = entries.filter((e) => !e.startsWith("._"));
29846
30000
  if (real.length !== 1) {
@@ -29848,7 +30002,7 @@ async function resolveMember(destDir, expectedName) {
29848
30002
  `Could not identify the extracted member (expected "${expectedName}", found ${real.length} entries).`
29849
30003
  );
29850
30004
  }
29851
- return join4(destDir, real[0]);
30005
+ return join5(destDir, real[0]);
29852
30006
  }
29853
30007
  async function safeExtractTarGz(tarPath, destDir, expectedName) {
29854
30008
  await assertSafeArchive(tarPath, destDir);
@@ -29886,6 +30040,16 @@ function interpolatePath(template, args) {
29886
30040
  });
29887
30041
  return missing ? null : out;
29888
30042
  }
30043
+ async function specPath(spec, args) {
30044
+ if (spec.kind !== "file" || !spec.paths?.length) return interpolatePath(spec.path, args);
30045
+ const candidates = [];
30046
+ for (const template of spec.paths) {
30047
+ const filled = interpolatePath(template, args);
30048
+ if (filled === null) return null;
30049
+ candidates.push(filled);
30050
+ }
30051
+ return (await pickE2eFile(candidates)).path;
30052
+ }
29889
30053
  var pendingArchives = /* @__PURE__ */ new Set();
29890
30054
  var ARCHIVE_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
29891
30055
  function removePendingArchives() {
@@ -29921,9 +30085,9 @@ function untrackArchive(archive) {
29921
30085
  process.removeListener("exit", removePendingArchives);
29922
30086
  }
29923
30087
  function sha256File(filePath) {
29924
- return new Promise((resolve12, reject) => {
30088
+ return new Promise((resolve13, reject) => {
29925
30089
  const hash2 = createHash2("sha256");
29926
- createReadStream(filePath).on("data", (chunk) => hash2.update(chunk)).on("end", () => resolve12(hash2.digest("hex"))).on("error", reject);
30090
+ createReadStream(filePath).on("data", (chunk) => hash2.update(chunk)).on("end", () => resolve13(hash2.digest("hex"))).on("error", reject);
29927
30091
  });
29928
30092
  }
29929
30093
  function toolServerError(text2) {
@@ -29950,7 +30114,7 @@ function uploadFailure(url2, res, text2, bytes) {
29950
30114
  });
29951
30115
  }
29952
30116
  async function uploadTar(tarPath, endpoint, signal) {
29953
- const { size } = await stat2(tarPath);
30117
+ const { size } = await stat3(tarPath);
29954
30118
  const init2 = {
29955
30119
  method: "POST",
29956
30120
  headers: {
@@ -29974,7 +30138,7 @@ async function uploadTar(tarPath, endpoint, signal) {
29974
30138
  return json2.uploadId;
29975
30139
  }
29976
30140
  async function uploadFile(sourcePath, endpoint, signal) {
29977
- const tarPath = path4.join(tmpdir(), `argent-upload-${randomUUID3()}.tar.gz`);
30141
+ const tarPath = path5.join(tmpdir(), `argent-upload-${randomUUID3()}.tar.gz`);
29978
30142
  trackArchive(tarPath);
29979
30143
  try {
29980
30144
  await createTarGzFile(await realpath2(sourcePath), tarPath);
@@ -29989,7 +30153,7 @@ async function uploadFile(sourcePath, endpoint, signal) {
29989
30153
  async function readFileInputWire(filePath, opts) {
29990
30154
  let st;
29991
30155
  try {
29992
- st = await stat2(filePath);
30156
+ st = await stat3(filePath);
29993
30157
  } catch {
29994
30158
  return null;
29995
30159
  }
@@ -30017,7 +30181,7 @@ async function prepareFileInputs(specs, args, opts) {
30017
30181
  for (const spec of specs) {
30018
30182
  if (spec.skipWhenSet && record2[spec.skipWhenSet] !== void 0) continue;
30019
30183
  if (spec.target in record2 && typeof record2[spec.target] !== "string") continue;
30020
- const filePath = interpolatePath(spec.path, record2);
30184
+ const filePath = await specPath(spec, record2);
30021
30185
  if (filePath === null) continue;
30022
30186
  if (spec.target in record2 && record2[spec.target] !== filePath) continue;
30023
30187
  const wire = { [FILE_INPUT_MARKER2]: true, path: filePath };
@@ -30035,13 +30199,13 @@ async function prepareFileInputs(specs, args, opts) {
30035
30199
  wire.members = await opts.collectStepMembers(record2, opts);
30036
30200
  }
30037
30201
  if (spec.kind === "tar-upload") {
30038
- const st = await stat2(filePath).catch(() => null);
30202
+ const st = await stat3(filePath).catch(() => null);
30039
30203
  if (st) {
30040
30204
  wire.size = st.size;
30041
30205
  wire.mtimeMs = st.mtimeMs;
30042
30206
  }
30043
30207
  if (opts.uploadEndpoint && st) {
30044
- process.stderr.write(`Uploading ${path4.basename(filePath)} to the remote tool-server...
30208
+ process.stderr.write(`Uploading ${path5.basename(filePath)} to the remote tool-server...
30045
30209
  `);
30046
30210
  Object.assign(wire, await uploadFile(filePath, opts.uploadEndpoint, opts.signal));
30047
30211
  }
@@ -30052,18 +30216,18 @@ async function prepareFileInputs(specs, args, opts) {
30052
30216
  return out ?? args;
30053
30217
  }
30054
30218
  function isAllowedClientFilePath(p) {
30055
- if (!path4.isAbsolute(p)) return false;
30219
+ if (!path5.isAbsolute(p)) return false;
30056
30220
  const segments = p.split(/[\\/]+/);
30057
30221
  if (segments.includes("..")) return false;
30058
30222
  const file2 = segments[segments.length - 1] ?? "";
30059
30223
  if (!FLOW_FILE_NAME_PATTERN.test(file2)) return false;
30060
- return segments[segments.length - 3] === ".argent" && segments[segments.length - 2] === "flows";
30224
+ return e2eDirProject(segments.slice(0, -1).join("/")) !== null;
30061
30225
  }
30062
30226
  function isClientFileDirective2(value) {
30063
30227
  return !!value && typeof value === "object" && value[CLIENT_FILE_MARKER2] === true && typeof value.path === "string" && typeof value.content === "string";
30064
30228
  }
30065
30229
  async function replaceFile(target, bytes, mode) {
30066
- const temp = path4.join(path4.dirname(target), `.baseline-${randomUUID3()}.tmp`);
30230
+ const temp = path5.join(path5.dirname(target), `.baseline-${randomUUID3()}.tmp`);
30067
30231
  try {
30068
30232
  await writeFile3(temp, bytes, { flag: "wx" });
30069
30233
  if (mode !== void 0) await chmod3(temp, mode & 511);
@@ -30074,27 +30238,27 @@ async function replaceFile(target, bytes, mode) {
30074
30238
  }
30075
30239
  }
30076
30240
  async function writeBaselineFile(file2, bytes, allowedDirs) {
30077
- if (!path4.isAbsolute(file2) || path4.normalize(file2) !== file2 || file2.split(/[\\/]/).includes("..") || !file2.endsWith(".png") || !allowedDirs.includes(path4.dirname(file2))) {
30241
+ if (!path5.isAbsolute(file2) || path5.normalize(file2) !== file2 || file2.split(/[\\/]/).includes("..") || !file2.endsWith(".png") || !allowedDirs.includes(path5.dirname(file2))) {
30078
30242
  return allowedDirs.length === 0 ? "this call writes no baselines" : `${file2} is not a baseline of this call (${allowedDirs.map((d) => `${d}/<name>.png`).join(", ")})`;
30079
30243
  }
30080
30244
  if (bytes.length > MAX_CONTENT_BYTES) {
30081
30245
  return `${file2}: the baseline is larger than the 32 MiB cap on a file this client writes`;
30082
30246
  }
30083
- const dir = path4.dirname(file2);
30247
+ const dir = path5.dirname(file2);
30084
30248
  await mkdir3(dir, { recursive: true });
30085
30249
  const link2 = await lstat(file2).catch(() => null);
30086
30250
  const real = link2 === null ? null : await realpath2(file2).catch(() => null);
30087
30251
  if (link2 !== null && real === null) return `${file2} is a symbolic link to a missing file`;
30088
30252
  if (real !== null) {
30089
30253
  if (!real.endsWith(".png")) return `${file2} links to a file that is not a PNG file`;
30090
- if (path4.dirname(real) !== await realpath2(dir)) {
30254
+ if (path5.dirname(real) !== await realpath2(dir)) {
30091
30255
  return `${file2} links outside its baseline directory`;
30092
30256
  }
30093
30257
  }
30094
- const existing = real === null ? null : await stat2(real);
30258
+ const existing = real === null ? null : await stat3(real);
30095
30259
  if (existing !== null && !existing.isFile()) return `${file2} is not a regular file`;
30096
30260
  await replaceFile(
30097
- real ?? path4.join(await realpath2(dir), path4.basename(file2)),
30261
+ real ?? path5.join(await realpath2(dir), path5.basename(file2)),
30098
30262
  bytes,
30099
30263
  existing?.mode
30100
30264
  );
@@ -30120,7 +30284,7 @@ async function applyClientFileDirectives(result, opts = {}) {
30120
30284
  if (isClientFileDirective2(value)) {
30121
30285
  if (!isAllowedClientFilePath(value.path)) return null;
30122
30286
  try {
30123
- await mkdir3(path4.dirname(value.path), { recursive: true });
30287
+ await mkdir3(path5.dirname(value.path), { recursive: true });
30124
30288
  await writeFile3(value.path, value.content, "utf8");
30125
30289
  written.push(value.path);
30126
30290
  return value.path;
@@ -30148,12 +30312,14 @@ async function applyClientFileDirectives(result, opts = {}) {
30148
30312
 
30149
30313
  // ../argent-tools-client/src/flow-files.ts
30150
30314
  var import_yaml = __toESM(require_dist(), 1);
30151
- import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat3 } from "node:fs/promises";
30152
- import * as path5 from "node:path";
30315
+ import { readdir as readdir4, readFile as readFile4, realpath as realpath3, stat as stat4 } from "node:fs/promises";
30316
+ import * as path6 from "node:path";
30153
30317
  var INLINE_MEMBERS_BYTES = 256 * 1024;
30154
- var FLOW_FILES_LOG_ENV = "ARGENT_FLOW_FILES_LOG";
30318
+ function filesLogEnabled() {
30319
+ return (process.env.ARGENT_E2E_FILES_LOG ?? process.env.ARGENT_FLOW_FILES_LOG) === "1";
30320
+ }
30155
30321
  function isWithin(inner, outer) {
30156
- return inner === outer || inner.startsWith(outer.endsWith(path5.sep) ? outer : outer + path5.sep);
30322
+ return inner === outer || inner.startsWith(outer.endsWith(path6.sep) ? outer : outer + path6.sep);
30157
30323
  }
30158
30324
  function printable(text2) {
30159
30325
  return [...text2].map(
@@ -30161,23 +30327,21 @@ function printable(text2) {
30161
30327
  ).join("");
30162
30328
  }
30163
30329
  function isResolvedAbsolute2(value) {
30164
- return typeof value === "string" && path5.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
30330
+ return typeof value === "string" && path6.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
30165
30331
  }
30166
30332
  function namesValidFlow(args) {
30167
30333
  const { project_root, flow_path, name } = args;
30168
30334
  if (!isResolvedAbsolute2(project_root)) return false;
30169
30335
  if (name === void 0) {
30170
- return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path5.basename(flow_path));
30336
+ return isResolvedAbsolute2(flow_path) && FLOW_FILE_NAME_PATTERN.test(path6.basename(flow_path));
30171
30337
  }
30172
30338
  return flow_path === void 0 && typeof name === "string" && FLOW_NAME_PATTERN.test(name);
30173
30339
  }
30174
30340
  function savedFlowProject(file2) {
30175
- if (!path5.isAbsolute(file2)) return null;
30176
- const parts = file2.split(path5.sep);
30177
- for (let i2 = parts.length - 3; i2 >= 0; i2--) {
30178
- if (parts[i2] === ".argent" && parts[i2 + 1] === "flows") {
30179
- return parts.slice(0, i2).join(path5.sep) || path5.sep;
30180
- }
30341
+ if (!path6.isAbsolute(file2)) return null;
30342
+ for (let dir = path6.dirname(file2); dir !== path6.dirname(dir); dir = path6.dirname(dir)) {
30343
+ const project = e2eDirProject(dir);
30344
+ if (project !== null) return project;
30181
30345
  }
30182
30346
  return null;
30183
30347
  }
@@ -30190,11 +30354,11 @@ async function landing(spelled) {
30190
30354
  const canonical = await canonicalFlowPath(spelled);
30191
30355
  let at = spelled;
30192
30356
  for (; ; ) {
30193
- const parent = path5.dirname(at);
30357
+ const parent = path6.dirname(at);
30194
30358
  if (parent === at) return { canonical, fence: spelled, ...failure2 };
30195
30359
  const real = await realpath3(parent).catch(() => null);
30196
30360
  if (real !== null) {
30197
- return { canonical, fence: path5.join(real, path5.basename(at)), ...failure2 };
30361
+ return { canonical, fence: path6.join(real, path6.basename(at)), ...failure2 };
30198
30362
  }
30199
30363
  at = parent;
30200
30364
  }
@@ -30202,10 +30366,10 @@ async function landing(spelled) {
30202
30366
  }
30203
30367
  async function closureRoots(rootPath, rootCanonical, projectRoot) {
30204
30368
  const candidates = [];
30205
- if (typeof projectRoot === "string" && path5.isAbsolute(projectRoot)) {
30206
- candidates.push(projectRoot, path5.join(projectRoot, ".argent", "flows"));
30369
+ if (typeof projectRoot === "string" && path6.isAbsolute(projectRoot)) {
30370
+ candidates.push(projectRoot, ...e2eDirsFor(projectRoot));
30207
30371
  }
30208
- candidates.push(path5.dirname(rootPath), path5.dirname(rootCanonical));
30372
+ candidates.push(path6.dirname(rootPath), path6.dirname(rootCanonical));
30209
30373
  for (const file2 of [rootPath, rootCanonical]) {
30210
30374
  const project = savedFlowProject(file2);
30211
30375
  if (project !== null) candidates.push(project);
@@ -30218,11 +30382,11 @@ async function closureRoots(rootPath, rootCanonical, projectRoot) {
30218
30382
  return real.filter((root) => !real.some((other) => other !== root && isWithin(root, other)));
30219
30383
  }
30220
30384
  async function readFlowMember(anchorDir, target, roots, budget, opts) {
30221
- const spelled = anchorDir + path5.sep + target;
30385
+ const spelled = anchorDir + path6.sep + target;
30222
30386
  const { canonical, fence, missing, error: error63 } = await landing(spelled);
30223
30387
  const spelling = await classifyOnDiskSpelling(
30224
- path5.dirname(spelled),
30225
- path5.posix.basename(target),
30388
+ path6.dirname(spelled),
30389
+ path6.posix.basename(target),
30226
30390
  FLOW_FILE_NAME_PATTERN
30227
30391
  );
30228
30392
  const member = {
@@ -30241,13 +30405,13 @@ async function readFlowMember(anchorDir, target, roots, budget, opts) {
30241
30405
  }
30242
30406
  if (error63 !== void 0) return refuse(error63);
30243
30407
  if (missing) return { member: { ...member, state: "missing" }, sent: "missing" };
30244
- const st = await stat3(canonical).catch((err) => err);
30408
+ const st = await stat4(canonical).catch((err) => err);
30245
30409
  if (st instanceof Error) {
30246
30410
  if (st.code !== "ENOENT") return refuse(st.message);
30247
30411
  return { member: { ...member, state: "missing" }, sent: "missing" };
30248
30412
  }
30249
30413
  if (st.isDirectory()) return refuse("EISDIR: illegal operation on a directory, read");
30250
- if (!/\.ya?ml$/i.test(path5.basename(canonical))) {
30414
+ if (!/\.ya?ml$/i.test(path6.basename(canonical))) {
30251
30415
  return refuse(`${target} links to a file that is not a YAML file`);
30252
30416
  }
30253
30417
  const sent = await sendBytes(member, canonical, budget, opts);
@@ -30266,7 +30430,7 @@ async function readToolMember(file2, roots, budget, opts) {
30266
30430
  if (!hasToolFileExtension(canonical)) {
30267
30431
  return refuse(`${file2} links to a file that is not one of ${TOOL_FILE_EXTENSIONS.join(", ")}`);
30268
30432
  }
30269
- const st = await stat3(canonical).catch((err) => err);
30433
+ const st = await stat4(canonical).catch((err) => err);
30270
30434
  if (st instanceof Error) {
30271
30435
  if (st.code === "ENOENT" || st.code === "ENOTDIR") {
30272
30436
  return { member: { ...member, state: "missing" }, sent: "missing" };
@@ -30290,7 +30454,7 @@ async function baselineEntry(file2, roots, forWrite) {
30290
30454
  };
30291
30455
  }
30292
30456
  if (error63 !== void 0) return { state: "refused", error: error63 };
30293
- const st = await stat3(canonical).catch((err) => err);
30457
+ const st = await stat4(canonical).catch((err) => err);
30294
30458
  if (st instanceof Error) {
30295
30459
  if (st.code !== "ENOENT") return { state: "refused", error: st.message };
30296
30460
  return forWrite ? { state: "refused", error: `${file2} is a symbolic link to a missing file` } : { state: "missing" };
@@ -30340,7 +30504,7 @@ function memberCollector(roots, opts) {
30340
30504
  const runs = /* @__PURE__ */ new Set();
30341
30505
  const baselineDirs = /* @__PURE__ */ new Map();
30342
30506
  const budget = { inline: 0 };
30343
- const logging = process.env[FLOW_FILES_LOG_ENV] === "1";
30507
+ const logging = filesLogEnabled();
30344
30508
  const log2 = opts.log ?? ((line) => void process.stderr.write(`${line}
30345
30509
  `));
30346
30510
  const emit = (member, sent) => {
@@ -30348,18 +30512,19 @@ function memberCollector(roots, opts) {
30348
30512
  const subject = member.role === "flow" ? member.canonical : member.key;
30349
30513
  if (logging) log2(printable(`[flow-files] ${member.role} ${subject}: ${sent}`));
30350
30514
  };
30351
- async function flow2(anchorDir, target) {
30515
+ async function flow(anchorDir, target, onlyPresent) {
30352
30516
  const key = flowMemberKey(anchorDir, target);
30353
30517
  const known = flows.get(key);
30354
- if (known !== void 0) return known;
30518
+ if (known !== void 0) return onlyPresent && known.text === void 0 ? void 0 : known;
30355
30519
  const { member, text: text2, sent } = await readFlowMember(anchorDir, target, roots, budget, opts);
30520
+ if (onlyPresent && text2 === void 0) return void 0;
30356
30521
  const entry = { member, ...text2 === void 0 ? {} : { text: text2 } };
30357
30522
  flows.set(key, entry);
30358
30523
  emit(member, sent);
30359
30524
  return entry;
30360
30525
  }
30361
30526
  async function toolFiles(step) {
30362
- if (step.tool === "flow-execute") return;
30527
+ if (canonicalToolId(step.tool) === "e2e-execute") return;
30363
30528
  for (const file2 of toolStepFiles(opts.toolFileInputs?.(step.tool), step.args)) {
30364
30529
  const { unwrapWhenSet } = file2.spec;
30365
30530
  if (unwrapWhenSet !== void 0 && step.args[unwrapWhenSet] !== void 0) continue;
@@ -30369,11 +30534,31 @@ function memberCollector(roots, opts) {
30369
30534
  emit(read.member, read.sent);
30370
30535
  }
30371
30536
  }
30537
+ async function savedTest(target) {
30538
+ for (const candidate of target.paths) {
30539
+ const found = await flow(path6.dirname(candidate), path6.basename(candidate), true);
30540
+ if (found !== void 0) return found;
30541
+ }
30542
+ let first;
30543
+ for (const candidate of target.paths) {
30544
+ first ??= await flow(path6.dirname(candidate), path6.basename(candidate));
30545
+ }
30546
+ return first;
30547
+ }
30372
30548
  async function nestedRun(target, hop, updates, platform) {
30373
- const { member, text: text2 } = await flow2(path5.dirname(target.path), `${target.name}.yaml`);
30549
+ const { member, text: text2 } = await savedTest(target);
30374
30550
  if (text2 === void 0 || hop >= MAX_RUN_DEPTH) return void 0;
30375
30551
  return { canonical: member.canonical, text: text2, flowName: target.name, hop, updates, platform };
30376
30552
  }
30553
+ async function runTarget(anchorDir, target) {
30554
+ const found = await flow(anchorDir, target);
30555
+ if (found.member.spelling?.state !== "absent") return found;
30556
+ for (const dir of e2eRunFallbackDirs(anchorDir, target)) {
30557
+ const other = await flow(dir, target, true);
30558
+ if (other !== void 0) return other;
30559
+ }
30560
+ return found;
30561
+ }
30377
30562
  async function walk(start) {
30378
30563
  const queue = [...start];
30379
30564
  for (let run2 = queue.shift(); run2 !== void 0; run2 = queue.shift()) {
@@ -30393,12 +30578,12 @@ function memberCollector(roots, opts) {
30393
30578
  const requests = collectFlowRequests(doc);
30394
30579
  for (const name of requests.snapshots) snapshots.add(name);
30395
30580
  for (const step of requests.toolSteps) await toolFiles(step);
30396
- const anchorDir = path5.dirname(file2.canonical);
30581
+ const anchorDir = path6.dirname(file2.canonical);
30397
30582
  for (const target of requests.runTargets) {
30398
30583
  const key = flowMemberKey(anchorDir, target);
30399
30584
  if (visited.has(key)) continue;
30400
30585
  visited.add(key);
30401
- const { member, text: text2 } = await flow2(anchorDir, target);
30586
+ const { member, text: text2 } = await runTarget(anchorDir, target);
30402
30587
  if (text2 !== void 0 && file2.hop + 1 < MAX_RUN_DEPTH) {
30403
30588
  files.push({ canonical: member.canonical, text: text2, hop: file2.hop + 1 });
30404
30589
  }
@@ -30415,8 +30600,8 @@ function memberCollector(roots, opts) {
30415
30600
  }
30416
30601
  }
30417
30602
  if (snapshots.size === 0) continue;
30418
- const dir = path5.join(
30419
- path5.dirname(run2.canonical),
30603
+ const dir = path6.join(
30604
+ path6.dirname(run2.canonical),
30420
30605
  "__baselines__",
30421
30606
  baselineKeyFor(run2.canonical, run2.flowName)
30422
30607
  );
@@ -30440,7 +30625,7 @@ function memberCollector(roots, opts) {
30440
30625
  if (!name.endsWith(".png")) continue;
30441
30626
  const compared = [...prefixes].some((prefix) => name.startsWith(prefix));
30442
30627
  if (!updates && !compared) continue;
30443
- const file2 = path5.join(dir, name);
30628
+ const file2 = path6.join(dir, name);
30444
30629
  if (tools2.has(file2)) continue;
30445
30630
  const member = { role: "baseline", key: file2, path: file2 };
30446
30631
  const entry = await baselineEntry(file2, roots, updates && !compared);
@@ -30457,14 +30642,14 @@ function memberCollector(roots, opts) {
30457
30642
  }
30458
30643
  }
30459
30644
  }
30460
- return { members: members2, flow: flow2, toolFiles, nestedRun, walk, sendBaselines };
30645
+ return { members: members2, flow, toolFiles, nestedRun, walk, sendBaselines };
30461
30646
  }
30462
30647
  async function collectFlowMembers(rootPath, rootBytes, args, opts) {
30463
30648
  if (!namesValidFlow(args)) return {};
30464
30649
  const canonical = await canonicalFlowPath(rootPath);
30465
30650
  const spelling = await classifyOnDiskSpelling(
30466
- path5.dirname(rootPath),
30467
- path5.basename(rootPath),
30651
+ path6.dirname(rootPath),
30652
+ path6.basename(rootPath),
30468
30653
  FLOW_FILE_NAME_PATTERN
30469
30654
  );
30470
30655
  const collector = memberCollector(
@@ -30475,7 +30660,7 @@ async function collectFlowMembers(rootPath, rootBytes, args, opts) {
30475
30660
  {
30476
30661
  canonical,
30477
30662
  text: rootBytes.toString("utf8"),
30478
- flowName: path5.basename(rootPath, ".yaml"),
30663
+ flowName: path6.basename(rootPath, ".yaml"),
30479
30664
  hop: 0,
30480
30665
  updates: args.updateBaselines === true,
30481
30666
  platform: callPlatform(args)
@@ -30498,33 +30683,37 @@ function recordedStep(args) {
30498
30683
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
30499
30684
  return { tool: command, args: parsed };
30500
30685
  }
30501
- async function collectStepMembers(args, opts) {
30686
+ async function collectStepMembers(args, opts, recordingDirFor = e2eDirFor) {
30502
30687
  const { name, project_root: projectRoot } = args;
30503
30688
  const step = recordedStep(args);
30504
- if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path5.isAbsolute(projectRoot) || step === void 0) {
30689
+ if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name) || typeof projectRoot !== "string" || !path6.isAbsolute(projectRoot) || step === void 0) {
30505
30690
  return [];
30506
30691
  }
30507
- const recording = path5.join(projectRoot, ".argent", "flows", `${name}.yaml`);
30692
+ const recording = path6.join(recordingDirFor(projectRoot), `${name}.yaml`);
30508
30693
  const collector = memberCollector(
30509
30694
  await closureRoots(recording, (await landing(recording)).canonical, projectRoot),
30510
30695
  opts
30511
30696
  );
30512
30697
  await collector.toolFiles(step);
30513
- if (step.tool === "flow-execute") {
30514
- const self2 = await collector.flow(path5.dirname(recording), path5.basename(recording));
30698
+ if (canonicalToolId(step.tool) === "e2e-execute") {
30699
+ const self2 = await collector.flow(path6.dirname(recording), path6.basename(recording));
30515
30700
  let runArgs = step.args;
30516
30701
  const named = nestedFlowTarget(runArgs);
30517
30702
  if (named?.kind === "flow_path") {
30518
- const stem = path5.basename(named.path, ".yaml");
30519
- if (path5.resolve(path5.dirname(named.path)) === path5.resolve(path5.dirname(recording))) {
30520
- await collector.flow(path5.dirname(recording), path5.basename(named.path));
30703
+ const stem = path6.basename(named.path, ".yaml");
30704
+ const base = path6.basename(named.path);
30705
+ const dir = path6.resolve(path6.dirname(named.path));
30706
+ const recordingDir = path6.dirname(recording);
30707
+ const dirs = [recordingDir, ...e2eRunFallbackDirs(recordingDir, base)];
30708
+ if (dirs.some((d) => path6.resolve(d) === dir)) {
30709
+ await collector.flow(path6.dirname(named.path), base);
30521
30710
  runArgs = { ...runArgs, name: stem };
30522
30711
  delete runArgs.flow_path;
30523
30712
  }
30524
30713
  }
30525
30714
  const target = nestedFlowTarget(runArgs);
30526
30715
  if (target?.kind === "name") {
30527
- await collector.flow(path5.dirname(self2.member.canonical), `${target.name}.yaml`);
30716
+ await collector.flow(path6.dirname(self2.member.canonical), `${target.name}.yaml`);
30528
30717
  const run2 = await collector.nestedRun(
30529
30718
  target,
30530
30719
  0,
@@ -30537,6 +30726,43 @@ async function collectStepMembers(args, opts) {
30537
30726
  await collector.sendBaselines();
30538
30727
  return collector.members;
30539
30728
  }
30729
+ async function nameToE2ePathForOlderServer(tool, fileInputs, args) {
30730
+ const id = canonicalToolId(tool);
30731
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return args;
30732
+ const spec = fileInputs?.find((s) => s.target === "flow_file");
30733
+ if (spec === void 0 || spec.kind !== "file" || spec.paths?.length) return args;
30734
+ const target = nestedFlowTarget(args);
30735
+ if (target?.kind !== "name") return args;
30736
+ const picked = await pickE2eFile(target.paths);
30737
+ if (!picked.exists || picked.legacy) return args;
30738
+ const { name: _name, ...rest } = args;
30739
+ return { ...rest, flow_path: picked.path };
30740
+ }
30741
+ async function stepForOlderServer(args, listedId) {
30742
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
30743
+ const record2 = args;
30744
+ if (typeof record2.command !== "string") return args;
30745
+ const command = listedId(record2.command) ?? record2.command;
30746
+ const step = recordedStep({ ...record2, command });
30747
+ const target = step && canonicalToolId(step.tool) === "e2e-execute" && nestedFlowTarget(step.args);
30748
+ if (target && target.kind === "name") {
30749
+ const picked = await pickE2eFile(target.paths);
30750
+ if (picked.exists && !picked.legacy) {
30751
+ throw new Error(
30752
+ `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.`
30753
+ );
30754
+ }
30755
+ }
30756
+ return command === record2.command ? args : { ...record2, command };
30757
+ }
30758
+ async function e2eShadowWarningFor(tool, args) {
30759
+ const id = canonicalToolId(tool);
30760
+ if (id !== "e2e-execute" && id !== "e2e-read-prerequisite") return void 0;
30761
+ const target = nestedFlowTarget(args);
30762
+ if (target?.kind !== "name") return void 0;
30763
+ const picked = await pickE2eFile(target.paths);
30764
+ return picked.shadowed === void 0 ? void 0 : e2eShadowWarning(picked.path, picked.shadowed);
30765
+ }
30540
30766
 
30541
30767
  // ../argent-tools-client/src/tools-client.ts
30542
30768
  function authHeaders2(token) {
@@ -30614,6 +30840,10 @@ function errorBodyMessage(body) {
30614
30840
  if (Array.isArray(body.issues) && typeof body.message === "string") return body.message;
30615
30841
  return body.error ?? body.message;
30616
30842
  }
30843
+ function findTool(tools2, name) {
30844
+ const id = canonicalToolId(name);
30845
+ return tools2.find((t2) => t2.name === name) ?? tools2.find((t2) => canonicalToolId(t2.name) === id) ?? null;
30846
+ }
30617
30847
  function assertRequiredPresent(meta3, args) {
30618
30848
  const record2 = typeof args === "object" && args !== null ? args : {};
30619
30849
  const schema = meta3.inputSchema;
@@ -30689,26 +30919,33 @@ function createToolsClient(options = {}) {
30689
30919
  return json2.tools;
30690
30920
  }
30691
30921
  async function fetchTool(name, opts) {
30692
- const tools2 = await fetchTools(opts);
30693
- return tools2.find((t2) => t2.name === name) ?? null;
30922
+ return findTool(await fetchTools(opts), name);
30694
30923
  }
30695
30924
  async function callTool(name, args, opts) {
30696
30925
  opts?.signal?.throwIfAborted();
30697
30926
  const { url: url2, token, remote } = await route();
30698
30927
  let finalArgs = args;
30699
30928
  const tools2 = await fetchTools({ signal: opts?.signal });
30700
- const meta3 = tools2.find((t2) => t2.name === name) ?? null;
30929
+ const meta3 = findTool(tools2, name);
30930
+ const olderServer = meta3 !== null && !tools2.some((t2) => t2.name === canonicalToolId(meta3.name));
30931
+ if (meta3) {
30932
+ finalArgs = await nameToE2ePathForOlderServer(meta3.name, meta3.fileInputs, args);
30933
+ }
30934
+ if (olderServer && canonicalToolId(meta3.name) === "e2e-add-step") {
30935
+ finalArgs = await stepForOlderServer(finalArgs, (tool) => findTool(tools2, tool)?.name);
30936
+ }
30937
+ const shadowWarning = await e2eShadowWarningFor(name, args);
30701
30938
  const baselineDirs = [];
30702
30939
  if (meta3?.fileInputs?.length) {
30703
- if (remote) assertRequiredPresent(meta3, args);
30704
- finalArgs = await prepareFileInputs(meta3.fileInputs, args ?? {}, {
30940
+ if (remote) assertRequiredPresent(meta3, finalArgs);
30941
+ finalArgs = await prepareFileInputs(meta3.fileInputs, finalArgs ?? {}, {
30705
30942
  includeContent: remote,
30706
30943
  uploadEndpoint: remote ? { url: url2, token } : void 0,
30707
30944
  log: diagnose,
30708
30945
  baselineDirs,
30709
30946
  collectMembers: collectFlowMembers,
30710
- collectStepMembers,
30711
- toolFileInputs: (tool) => tools2.find((t2) => t2.name === tool)?.fileInputs,
30947
+ collectStepMembers: olderServer ? (record2, o) => collectStepMembers(record2, o, (root) => path7.join(root, LEGACY_E2E_DIRS[0])) : collectStepMembers,
30948
+ toolFileInputs: (tool) => findTool(tools2, tool)?.fileInputs,
30712
30949
  signal: opts?.signal
30713
30950
  });
30714
30951
  }
@@ -30717,19 +30954,23 @@ function createToolsClient(options = {}) {
30717
30954
  for (const { path: file2, error: error63 } of applied.failed) {
30718
30955
  diagnose(`The baseline ${file2} was not written on this client: ${error63}`);
30719
30956
  }
30720
- if (process.env.ARGENT_FLOW_FILES_LOG === "1") {
30957
+ if (filesLogEnabled()) {
30721
30958
  for (const file2 of applied.written) {
30722
- if (baselineDirs.includes(path6.dirname(file2))) {
30959
+ if (baselineDirs.includes(path7.dirname(file2))) {
30723
30960
  diagnose(`[flow-files] baseline ${file2}: written`);
30724
30961
  }
30725
30962
  }
30726
30963
  }
30727
- return applied.result;
30964
+ const result = applied.result;
30965
+ if (shadowWarning === void 0 || typeof result !== "object" || result === null || Array.isArray(result) || typeof result.warning === "string") {
30966
+ return result;
30967
+ }
30968
+ return { ...result, warning: shadowWarning };
30728
30969
  };
30729
30970
  const stream = opts?.onProgress !== void 0 || carriesMembers(finalArgs);
30730
30971
  const sentOnce = carriesUpload(finalArgs);
30731
30972
  const res = await doFetch(
30732
- `${url2}/tools/${encodeURIComponent(name)}`,
30973
+ `${url2}/tools/${encodeURIComponent(meta3?.name ?? name)}`,
30733
30974
  {
30734
30975
  method: "POST",
30735
30976
  headers: {
@@ -30737,6 +30978,9 @@ function createToolsClient(options = {}) {
30737
30978
  // Tells the tool-server the call came over a link, a link to
30738
30979
  // 127.0.0.1 included, which nothing else in the request shows.
30739
30980
  ...remote ? { [LINKED_CALL_HEADER]: "1" } : {},
30981
+ // Tells the tool-server this client writes recordings under
30982
+ // `.argent/e2e/`; an older client writes only `.argent/flows/`.
30983
+ [E2E_DIR_CLIENT_HEADER]: "1",
30740
30984
  // A proxy that compresses the stream holds each line until its buffer
30741
30985
  // fills. `identity` keeps the stream uncompressed end to end.
30742
30986
  ...stream ? { "Accept": "application/x-ndjson", "Accept-Encoding": "identity" } : {},
@@ -30794,15 +31038,15 @@ function createToolsClient(options = {}) {
30794
31038
  }
30795
31039
 
30796
31040
  // ../argent-tools-client/src/artifacts.ts
30797
- import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
31041
+ import { copyFile, mkdir as mkdir4, readFile as readFile5, realpath as realpath4, rm as rm3, stat as stat5, writeFile as writeFile4 } from "node:fs/promises";
30798
31042
  import { constants as fsConstants } from "node:fs";
30799
31043
  import { tmpdir as tmpdir2 } from "node:os";
30800
- 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";
31044
+ 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";
30801
31045
  import { createHash as createHash3 } from "node:crypto";
30802
31046
 
30803
31047
  // ../configuration-core/src/flags.ts
30804
- import * as fs3 from "node:fs";
30805
- import * as path7 from "node:path";
31048
+ import * as fs4 from "node:fs";
31049
+ import * as path8 from "node:path";
30806
31050
  import { homedir as homedir3 } from "node:os";
30807
31051
  var FLAG_REGISTRY = [
30808
31052
  {
@@ -30844,31 +31088,31 @@ function getFlagDefinition(name, registry2 = FLAG_REGISTRY) {
30844
31088
  }
30845
31089
  var PROJECT_MARKERS = [".argent", ".git", "package.json"];
30846
31090
  function findProjectRoot(startDir) {
30847
- let current = path7.resolve(startDir);
31091
+ let current = path8.resolve(startDir);
30848
31092
  while (true) {
30849
31093
  for (const marker of PROJECT_MARKERS) {
30850
- if (fs3.existsSync(path7.join(current, marker))) return current;
31094
+ if (fs4.existsSync(path8.join(current, marker))) return current;
30851
31095
  }
30852
- const parent = path7.dirname(current);
31096
+ const parent = path8.dirname(current);
30853
31097
  if (parent === current) return null;
30854
31098
  current = parent;
30855
31099
  }
30856
31100
  }
30857
31101
  function resolveProjectRoot(startDir) {
30858
- return findProjectRoot(startDir) ?? path7.resolve(startDir);
31102
+ return findProjectRoot(startDir) ?? path8.resolve(startDir);
30859
31103
  }
30860
31104
  function getFlagsPath(scope, options = {}) {
30861
31105
  const home = options.homeDir ?? homedir3();
30862
31106
  if (scope === "global") {
30863
- return path7.join(home, ".argent", "flags.json");
31107
+ return path8.join(home, ".argent", "flags.json");
30864
31108
  }
30865
31109
  const cwd = options.cwd ?? process.cwd();
30866
- return path7.join(resolveProjectRoot(cwd), ".argent", "flags.json");
31110
+ return path8.join(resolveProjectRoot(cwd), ".argent", "flags.json");
30867
31111
  }
30868
31112
  function readFlagsFile(filePath) {
30869
31113
  let raw;
30870
31114
  try {
30871
- raw = fs3.readFileSync(filePath, "utf8");
31115
+ raw = fs4.readFileSync(filePath, "utf8");
30872
31116
  } catch {
30873
31117
  return {};
30874
31118
  }
@@ -30889,20 +31133,20 @@ function readFlagsFile(filePath) {
30889
31133
  }
30890
31134
  function writeFlagsFile(filePath, flags2) {
30891
31135
  if (Object.keys(flags2).length === 0) {
30892
- if (fs3.existsSync(filePath)) fs3.rmSync(filePath, { force: true });
30893
- const parent = path7.dirname(filePath);
31136
+ if (fs4.existsSync(filePath)) fs4.rmSync(filePath, { force: true });
31137
+ const parent = path8.dirname(filePath);
30894
31138
  try {
30895
- if (fs3.existsSync(parent) && fs3.readdirSync(parent).length === 0) {
30896
- fs3.rmdirSync(parent);
31139
+ if (fs4.existsSync(parent) && fs4.readdirSync(parent).length === 0) {
31140
+ fs4.rmdirSync(parent);
30897
31141
  }
30898
31142
  } catch {
30899
31143
  }
30900
31144
  return;
30901
31145
  }
30902
- fs3.mkdirSync(path7.dirname(filePath), { recursive: true });
31146
+ fs4.mkdirSync(path8.dirname(filePath), { recursive: true });
30903
31147
  const tmp = `${filePath}.${process.pid}.tmp`;
30904
- fs3.writeFileSync(tmp, JSON.stringify({ flags: flags2 }, null, 2) + "\n");
30905
- fs3.renameSync(tmp, filePath);
31148
+ fs4.writeFileSync(tmp, JSON.stringify({ flags: flags2 }, null, 2) + "\n");
31149
+ fs4.renameSync(tmp, filePath);
30906
31150
  }
30907
31151
  function readFlags(scope, options = {}) {
30908
31152
  return readFlagsFile(getFlagsPath(scope, options));
@@ -30931,7 +31175,7 @@ function isFlagEnabled(name, options = {}) {
30931
31175
 
30932
31176
  // ../configuration-core/src/paths.ts
30933
31177
  import * as os from "node:os";
30934
- import * as path8 from "node:path";
31178
+ import * as path9 from "node:path";
30935
31179
  function nonEmpty(value) {
30936
31180
  if (value == void 0) return null;
30937
31181
  const trimmed = value.trim();
@@ -30942,26 +31186,26 @@ function resolveHomeDir(options = {}) {
30942
31186
  return process.platform === "win32" ? nonEmpty(process.env.USERPROFILE) ?? os.homedir() : nonEmpty(process.env.HOME) ?? os.homedir();
30943
31187
  }
30944
31188
  function argentHomeDir() {
30945
- return path8.join(resolveHomeDir(), ".argent");
31189
+ return path9.join(resolveHomeDir(), ".argent");
30946
31190
  }
30947
31191
  function configDir(scope = "global", options = {}) {
30948
31192
  if (scope === "global") {
30949
- return path8.join(resolveHomeDir(options), ".argent");
31193
+ return path9.join(resolveHomeDir(options), ".argent");
30950
31194
  }
30951
31195
  const cwd = options.cwd ?? process.cwd();
30952
- return path8.join(resolveProjectRoot(cwd), ".argent");
31196
+ return path9.join(resolveProjectRoot(cwd), ".argent");
30953
31197
  }
30954
31198
  function configFilePath(scope = "global", options = {}) {
30955
- return path8.join(configDir(scope, options), "config.json");
31199
+ return path9.join(configDir(scope, options), "config.json");
30956
31200
  }
30957
31201
 
30958
31202
  // ../configuration-core/src/config.ts
30959
31203
  import * as crypto from "node:crypto";
30960
- import * as fs4 from "node:fs";
30961
- import * as path9 from "node:path";
31204
+ import * as fs5 from "node:fs";
31205
+ import * as path10 from "node:path";
30962
31206
  function readConfigObject(scope = "global", options = {}) {
30963
31207
  try {
30964
- const raw = fs4.readFileSync(configFilePath(scope, options), "utf8");
31208
+ const raw = fs5.readFileSync(configFilePath(scope, options), "utf8");
30965
31209
  const json2 = JSON.parse(raw);
30966
31210
  if (json2 && typeof json2 === "object" && !Array.isArray(json2)) {
30967
31211
  return json2;
@@ -31037,9 +31281,9 @@ function acquireConfigLock(finalPath) {
31037
31281
  const deadline = Date.now() + LOCK_MAX_WAIT_MS;
31038
31282
  for (; ; ) {
31039
31283
  try {
31040
- const fd = fs4.openSync(lockPath, "wx", 384);
31284
+ const fd = fs5.openSync(lockPath, "wx", 384);
31041
31285
  try {
31042
- fs4.writeSync(fd, `${process.pid}
31286
+ fs5.writeSync(fd, `${process.pid}
31043
31287
  `);
31044
31288
  } catch {
31045
31289
  }
@@ -31047,8 +31291,8 @@ function acquireConfigLock(finalPath) {
31047
31291
  } catch (err) {
31048
31292
  if (err.code !== "EEXIST") return null;
31049
31293
  try {
31050
- if (Date.now() - fs4.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
31051
- fs4.unlinkSync(lockPath);
31294
+ if (Date.now() - fs5.statSync(lockPath).mtimeMs > LOCK_STALE_MS2) {
31295
+ fs5.unlinkSync(lockPath);
31052
31296
  continue;
31053
31297
  }
31054
31298
  } catch {
@@ -31060,35 +31304,35 @@ function acquireConfigLock(finalPath) {
31060
31304
  }
31061
31305
  function releaseConfigLock(lock) {
31062
31306
  try {
31063
- fs4.closeSync(lock.fd);
31307
+ fs5.closeSync(lock.fd);
31064
31308
  } catch {
31065
31309
  }
31066
31310
  try {
31067
- fs4.unlinkSync(lock.lockPath);
31311
+ fs5.unlinkSync(lock.lockPath);
31068
31312
  } catch {
31069
31313
  }
31070
31314
  }
31071
31315
  function updateConfig(mutate, scope = "global", options = {}) {
31072
31316
  const dir = configDir(scope, options);
31073
- fs4.mkdirSync(dir, { recursive: true });
31317
+ fs5.mkdirSync(dir, { recursive: true });
31074
31318
  const finalPath = configFilePath(scope, options);
31075
31319
  const lock = acquireConfigLock(finalPath);
31076
31320
  try {
31077
31321
  const next = readConfigObject(scope, options);
31078
31322
  mutate(next);
31079
- const tmpPath = path9.join(dir, `.config.tmp.${process.pid}.${crypto.randomUUID()}`);
31080
- const fd = fs4.openSync(tmpPath, "wx", 384);
31323
+ const tmpPath = path10.join(dir, `.config.tmp.${process.pid}.${crypto.randomUUID()}`);
31324
+ const fd = fs5.openSync(tmpPath, "wx", 384);
31081
31325
  try {
31082
- fs4.writeSync(fd, JSON.stringify(next, null, 2) + "\n");
31083
- fs4.fsyncSync(fd);
31326
+ fs5.writeSync(fd, JSON.stringify(next, null, 2) + "\n");
31327
+ fs5.fsyncSync(fd);
31084
31328
  } finally {
31085
- fs4.closeSync(fd);
31329
+ fs5.closeSync(fd);
31086
31330
  }
31087
31331
  try {
31088
- fs4.renameSync(tmpPath, finalPath);
31332
+ fs5.renameSync(tmpPath, finalPath);
31089
31333
  } catch (err) {
31090
31334
  try {
31091
- fs4.unlinkSync(tmpPath);
31335
+ fs5.unlinkSync(tmpPath);
31092
31336
  } catch {
31093
31337
  }
31094
31338
  throw err;
@@ -31099,9 +31343,9 @@ function updateConfig(mutate, scope = "global", options = {}) {
31099
31343
  }
31100
31344
 
31101
31345
  // ../configuration-core/src/secrets.ts
31102
- var import_dotenv = __toESM(require_main(), 1);
31103
- import * as fs5 from "node:fs";
31104
- import * as path10 from "node:path";
31346
+ var import_dotenv = __toESM(require_dist2(), 1);
31347
+ import * as fs6 from "node:fs";
31348
+ import * as path11 from "node:path";
31105
31349
  var SECRET_ENV_PREFIX = "ARGENT_SECRET_";
31106
31350
  var SECRETS_FILE_NAME = "secrets.env";
31107
31351
  var SHARED_ENV_FILES = [".env.local", ".env"];
@@ -31130,10 +31374,10 @@ function fileSource(filePath, exposure) {
31130
31374
  names: [],
31131
31375
  values: /* @__PURE__ */ new Map()
31132
31376
  };
31133
- if (!fs5.statSync(filePath, { throwIfNoEntry: false })) return absent;
31377
+ if (!fs6.statSync(filePath, { throwIfNoEntry: false })) return absent;
31134
31378
  let content;
31135
31379
  try {
31136
- content = fs5.readFileSync(filePath, "utf8");
31380
+ content = fs6.readFileSync(filePath, "utf8");
31137
31381
  } catch {
31138
31382
  return absent;
31139
31383
  }
@@ -31163,20 +31407,20 @@ function secretSources(options = {}) {
31163
31407
  const filePaths = [];
31164
31408
  if (projectRoot) {
31165
31409
  filePaths.push({
31166
- path: path10.join(projectRoot, ".argent", SECRETS_FILE_NAME),
31410
+ path: path11.join(projectRoot, ".argent", SECRETS_FILE_NAME),
31167
31411
  exposure: "dedicated"
31168
31412
  });
31169
31413
  for (const name of SHARED_ENV_FILES) {
31170
- filePaths.push({ path: path10.join(projectRoot, name), exposure: "shared" });
31414
+ filePaths.push({ path: path11.join(projectRoot, name), exposure: "shared" });
31171
31415
  }
31172
31416
  }
31173
31417
  filePaths.push({
31174
- path: path10.join(resolveHomeDir(options), ".argent", SECRETS_FILE_NAME),
31418
+ path: path11.join(resolveHomeDir(options), ".argent", SECRETS_FILE_NAME),
31175
31419
  exposure: "dedicated"
31176
31420
  });
31177
31421
  const seen = /* @__PURE__ */ new Set();
31178
31422
  for (const entry of filePaths) {
31179
- const resolved = path10.resolve(entry.path);
31423
+ const resolved = path11.resolve(entry.path);
31180
31424
  if (seen.has(resolved)) continue;
31181
31425
  seen.add(resolved);
31182
31426
  sources.push(fileSource(resolved, entry.exposure));
@@ -31344,7 +31588,7 @@ var CONFIG_SCHEMA = [
31344
31588
  // nominal here — the project scope of a global-only key is never read.
31345
31589
  {
31346
31590
  key: "scripts.maxTimeoutMs",
31347
- 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.`,
31591
+ 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.`,
31348
31592
  scopes: ["global"],
31349
31593
  parse: (raw) => {
31350
31594
  const value = asPositiveInteger(raw);
@@ -31357,7 +31601,7 @@ var CONFIG_SCHEMA = [
31357
31601
  },
31358
31602
  {
31359
31603
  key: "scripts.heapLimitMb",
31360
- 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.`,
31604
+ 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.`,
31361
31605
  scopes: ["global"],
31362
31606
  parse: (raw) => {
31363
31607
  const value = asPositiveInteger(raw);
@@ -31374,7 +31618,7 @@ function getConfigDefinition(key, registry2 = CONFIG_SCHEMA) {
31374
31618
  }
31375
31619
 
31376
31620
  // ../configuration-core/src/config-access.ts
31377
- import * as path11 from "node:path";
31621
+ import * as path12 from "node:path";
31378
31622
  function readScopeValue(def, scope, options) {
31379
31623
  if (!def.scopes.includes(scope)) return void 0;
31380
31624
  const raw = getAtPath(readConfigObject(scope, options), def.key);
@@ -31521,20 +31765,20 @@ function sanitizeSegment(segment) {
31521
31765
  function projectSlug() {
31522
31766
  const cwd = process.cwd();
31523
31767
  const hash2 = createHash3("sha1").update(cwd).digest("hex").slice(0, 6);
31524
- const name = sanitizeSegment(basename6(cwd)) || "root";
31768
+ const name = sanitizeSegment(basename7(cwd)) || "root";
31525
31769
  return `${name}-${hash2}`;
31526
31770
  }
31527
31771
  function artifactsRoot() {
31528
- return process.env.ARGENT_ARTIFACTS_DIR ?? join11(tmpdir2(), "argent-artifacts");
31772
+ return process.env.ARGENT_ARTIFACTS_DIR ?? join13(tmpdir2(), "argent-artifacts");
31529
31773
  }
31530
31774
  function artifactDir(deviceId) {
31531
31775
  const parts = [artifactsRoot(), projectSlug(), sessionId()];
31532
31776
  if (deviceId) parts.push(sanitizeSegment(deviceId));
31533
- return join11(...parts);
31777
+ return join13(...parts);
31534
31778
  }
31535
31779
  function durableBaseDir() {
31536
31780
  const projectRoot = findProjectRoot(process.cwd());
31537
- return projectRoot ?? dirname8(argentHomeDir());
31781
+ return projectRoot ?? dirname9(argentHomeDir());
31538
31782
  }
31539
31783
  var ALLOWED_SAVE_DIRS = /* @__PURE__ */ new Set([normalize2(".argent/recordings")]);
31540
31784
  var RECORDINGS_SAVE_DIR = normalize2(".argent/recordings");
@@ -31548,9 +31792,9 @@ function configuredRecordingsDir() {
31548
31792
  if (typeof value !== "string") return null;
31549
31793
  const trimmed = value.trim();
31550
31794
  if (trimmed === "") return null;
31551
- const home = dirname8(argentHomeDir());
31552
- const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join11(home, trimmed.slice(2)) : trimmed;
31553
- return resolve7(durableBaseDir(), expanded);
31795
+ const home = dirname9(argentHomeDir());
31796
+ const expanded = trimmed === "~" ? home : trimmed.startsWith("~/") || trimmed.startsWith(`~${sep4}`) ? join13(home, trimmed.slice(2)) : trimmed;
31797
+ return resolve8(durableBaseDir(), expanded);
31554
31798
  }
31555
31799
  var MAX_DURABLE_BYTES = 2 * 1024 * 1024 * 1024;
31556
31800
  async function readCapped(res, cap) {
@@ -31583,10 +31827,10 @@ async function writeDurableUnique(dir, filename, write) {
31583
31827
  const stem = filename.slice(0, filename.length - ext.length);
31584
31828
  for (let i2 = 1; i2 <= 1e3; i2++) {
31585
31829
  const candidate = i2 === 1 ? filename : `${stem} (${i2})${ext}`;
31586
- const path24 = join11(dir, candidate);
31830
+ const path25 = join13(dir, candidate);
31587
31831
  try {
31588
- await write(path24);
31589
- return path24;
31832
+ await write(path25);
31833
+ return path25;
31590
31834
  } catch (err) {
31591
31835
  if (err?.code === "EEXIST") continue;
31592
31836
  throw err;
@@ -31606,21 +31850,21 @@ function durableSaveTarget(handle) {
31606
31850
  if (configured) {
31607
31851
  return {
31608
31852
  dir: configured,
31609
- path: join11(configured, sanitizeSegment(handle.filename)),
31853
+ path: join13(configured, sanitizeSegment(handle.filename)),
31610
31854
  base: configured,
31611
31855
  rel: ""
31612
31856
  };
31613
31857
  }
31614
31858
  }
31615
31859
  const base = durableBaseDir();
31616
- const dir = join11(base, rel);
31617
- return { dir, path: join11(dir, sanitizeSegment(handle.filename)), base, rel };
31860
+ const dir = join13(base, rel);
31861
+ return { dir, path: join13(dir, sanitizeSegment(handle.filename)), base, rel };
31618
31862
  }
31619
31863
  async function confineToRealBase(dir, base, rel) {
31620
31864
  try {
31621
31865
  const realDir = await realpath4(dir);
31622
31866
  const realBase = await realpath4(base);
31623
- return realDir === join11(realBase, rel);
31867
+ return realDir === join13(realBase, rel);
31624
31868
  } catch {
31625
31869
  return false;
31626
31870
  }
@@ -31628,7 +31872,7 @@ async function confineToRealBase(dir, base, rel) {
31628
31872
  async function resolveLocalFile(handle) {
31629
31873
  if (!handle.hostPath) return null;
31630
31874
  try {
31631
- const st = await stat4(handle.hostPath);
31875
+ const st = await stat5(handle.hostPath);
31632
31876
  if (handle.archive) {
31633
31877
  return st.isDirectory() ? handle.hostPath : null;
31634
31878
  }
@@ -31643,7 +31887,7 @@ async function resolveLocalFile(handle) {
31643
31887
  }
31644
31888
  }
31645
31889
  async function downloadAndExtractArchive(handle, data, dir) {
31646
- const tarball = join11(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
31890
+ const tarball = join13(dir, `${sanitizeSegment(handle.filename)}.tar.gz`);
31647
31891
  try {
31648
31892
  await writeFile4(tarball, data);
31649
31893
  return await safeExtractTarGz(tarball, dir, handle.filename);
@@ -31671,7 +31915,7 @@ async function materializeArtifacts(result, ctx) {
31671
31915
  const localPath = await resolveLocalFile(value);
31672
31916
  const saveTarget = durableSaveTarget(value);
31673
31917
  if (saveTarget) {
31674
- const filename = basename6(saveTarget.path);
31918
+ const filename = basename7(saveTarget.path);
31675
31919
  try {
31676
31920
  await mkdir4(saveTarget.dir, { recursive: true });
31677
31921
  if (!await confineToRealBase(saveTarget.dir, saveTarget.base, saveTarget.rel)) {
@@ -31735,7 +31979,7 @@ async function materializeArtifacts(result, ctx) {
31735
31979
  return await downloadAndExtractArchive(value, data, dir);
31736
31980
  }
31737
31981
  if (value.size > 0 && data.length !== value.size) return null;
31738
- const downloadedPath = join11(dir, sanitizeSegment(value.filename));
31982
+ const downloadedPath = join13(dir, sanitizeSegment(value.filename));
31739
31983
  await writeFile4(downloadedPath, data);
31740
31984
  if (value.mimeType.startsWith("image/")) {
31741
31985
  images.push({ localPath: downloadedPath, data, mimeType: value.mimeType });
@@ -32072,7 +32316,7 @@ function getStringFromEnv(key) {
32072
32316
  }
32073
32317
 
32074
32318
  // ../../node_modules/@opentelemetry/core/build/esm/version.js
32075
- var VERSION2 = "2.11.0";
32319
+ var VERSION2 = "2.12.0";
32076
32320
 
32077
32321
  // ../../node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js
32078
32322
  var ATTR_EXCEPTION_MESSAGE = "exception.message";
@@ -32192,8 +32436,8 @@ var Deferred = class {
32192
32436
  _resolve;
32193
32437
  _reject;
32194
32438
  constructor() {
32195
- this._promise = new Promise((resolve12, reject) => {
32196
- this._resolve = resolve12;
32439
+ this._promise = new Promise((resolve13, reject) => {
32440
+ this._resolve = resolve13;
32197
32441
  this._reject = reject;
32198
32442
  });
32199
32443
  }
@@ -32878,7 +33122,7 @@ var LoggerMetrics = class {
32878
33122
  };
32879
33123
 
32880
33124
  // ../../node_modules/@opentelemetry/sdk-logs/build/esm/version.js
32881
- var VERSION3 = "0.222.0";
33125
+ var VERSION3 = "0.223.0";
32882
33126
 
32883
33127
  // ../../node_modules/@opentelemetry/sdk-logs/build/esm/internal/LoggerProviderSharedState.js
32884
33128
  var DEFAULT_LOGGER_CONFIG = {
@@ -33086,8 +33330,8 @@ var ExportOperation = class {
33086
33330
  _metrics;
33087
33331
  _exportScheduledResolve;
33088
33332
  constructor(exporter, logRecords, exportTimeoutMillis, metrics) {
33089
- this._exportScheduledPromise = new Promise((resolve12) => {
33090
- this._exportScheduledResolve = resolve12;
33333
+ this._exportScheduledPromise = new Promise((resolve13) => {
33334
+ this._exportScheduledResolve = resolve13;
33091
33335
  });
33092
33336
  this._exportCompleted = this._executeExport(exporter, logRecords, exportTimeoutMillis);
33093
33337
  this._metrics = metrics;
@@ -33112,7 +33356,7 @@ var ExportOperation = class {
33112
33356
  }
33113
33357
  }
33114
33358
  async _exportWithTimeout(exporter, logRecords, exportTimeoutMillis) {
33115
- return new Promise((resolve12, reject) => {
33359
+ return new Promise((resolve13, reject) => {
33116
33360
  const timer = setTimeout(() => {
33117
33361
  reject(new Error("Timeout"));
33118
33362
  }, exportTimeoutMillis);
@@ -33120,7 +33364,7 @@ var ExportOperation = class {
33120
33364
  this._metrics.finishLogs(logRecords.length, result.error);
33121
33365
  clearTimeout(timer);
33122
33366
  if (result.code === ExportResultCode.SUCCESS) {
33123
- resolve12();
33367
+ resolve13();
33124
33368
  } else {
33125
33369
  reject(result.error ?? new Error("BatchLogRecordProcessor: log record export failed"));
33126
33370
  }
@@ -33527,7 +33771,7 @@ var ATTR_SERVER_PORT = "server.port";
33527
33771
  var ATTR_ERROR_TYPE2 = "error.type";
33528
33772
 
33529
33773
  // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/version.js
33530
- var VERSION4 = "0.222.0";
33774
+ var VERSION4 = "0.223.0";
33531
33775
 
33532
33776
  // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/ExporterMetrics.js
33533
33777
  var componentCounter2 = /* @__PURE__ */ new Map();
@@ -33901,7 +34145,7 @@ function parseRetryAfterToMills(retryAfter) {
33901
34145
  var DEFAULT_USER_AGENT = `OTel-OTLP-Exporter-JavaScript/${VERSION4}`;
33902
34146
  var MAX_RESPONSE_BODY_SIZE = 4 * 1024 * 1024;
33903
34147
  function sendWithHttp(request, url2, headers, compression, userAgent, agent, data, timeoutMillis) {
33904
- return new Promise((resolve12) => {
34148
+ return new Promise((resolve13) => {
33905
34149
  const parsedUrl = new URL(url2);
33906
34150
  if (userAgent) {
33907
34151
  headers["User-Agent"] = `${userAgent} ${DEFAULT_USER_AGENT}`;
@@ -33920,7 +34164,7 @@ function sendWithHttp(request, url2, headers, compression, userAgent, agent, dat
33920
34164
  responseSize += chunk.length;
33921
34165
  if (responseSize > MAX_RESPONSE_BODY_SIZE) {
33922
34166
  const sizeError = new Error(`OTLP export response body exceeded size limit of ${MAX_RESPONSE_BODY_SIZE} bytes`);
33923
- resolve12({ status: "failure", error: sizeError });
34167
+ resolve13({ status: "failure", error: sizeError });
33924
34168
  res.destroy();
33925
34169
  return;
33926
34170
  }
@@ -33928,18 +34172,18 @@ function sendWithHttp(request, url2, headers, compression, userAgent, agent, dat
33928
34172
  });
33929
34173
  res.on("end", () => {
33930
34174
  if (res.statusCode && res.statusCode <= 299) {
33931
- resolve12({
34175
+ resolve13({
33932
34176
  status: "success",
33933
34177
  data: Buffer.concat(responseData)
33934
34178
  });
33935
34179
  } else if (res.statusCode && isExportHTTPErrorRetryable(res.statusCode)) {
33936
- resolve12({
34180
+ resolve13({
33937
34181
  status: "retryable",
33938
34182
  retryInMillis: parseRetryAfterToMills(res.headers["retry-after"])
33939
34183
  });
33940
34184
  } else {
33941
34185
  const error63 = new OTLPExporterError(res.statusMessage, res.statusCode, Buffer.concat(responseData).toString());
33942
- resolve12({
34186
+ resolve13({
33943
34187
  status: "failure",
33944
34188
  error: error63
33945
34189
  });
@@ -33947,17 +34191,17 @@ function sendWithHttp(request, url2, headers, compression, userAgent, agent, dat
33947
34191
  });
33948
34192
  res.on("error", (error63) => {
33949
34193
  if (res.statusCode && res.statusCode <= 299) {
33950
- resolve12({
34194
+ resolve13({
33951
34195
  status: "success"
33952
34196
  });
33953
34197
  } else if (res.statusCode && isExportHTTPErrorRetryable(res.statusCode)) {
33954
- resolve12({
34198
+ resolve13({
33955
34199
  status: "retryable",
33956
34200
  error: error63,
33957
34201
  retryInMillis: parseRetryAfterToMills(res.headers["retry-after"])
33958
34202
  });
33959
34203
  } else {
33960
- resolve12({
34204
+ resolve13({
33961
34205
  status: "failure",
33962
34206
  error: error63
33963
34207
  });
@@ -33966,26 +34210,26 @@ function sendWithHttp(request, url2, headers, compression, userAgent, agent, dat
33966
34210
  });
33967
34211
  req.setTimeout(timeoutMillis, () => {
33968
34212
  req.destroy();
33969
- resolve12({
34213
+ resolve13({
33970
34214
  status: "retryable",
33971
34215
  error: new Error("Request timed out")
33972
34216
  });
33973
34217
  });
33974
34218
  req.on("error", (error63) => {
33975
34219
  if (isHttpTransportNetworkErrorRetryable(error63)) {
33976
- resolve12({
34220
+ resolve13({
33977
34221
  status: "retryable",
33978
34222
  error: error63
33979
34223
  });
33980
34224
  } else {
33981
- resolve12({
34225
+ resolve13({
33982
34226
  status: "failure",
33983
34227
  error: error63
33984
34228
  });
33985
34229
  }
33986
34230
  });
33987
34231
  compressAndSend(req, compression, data, (error63) => {
33988
- resolve12({
34232
+ resolve13({
33989
34233
  status: "failure",
33990
34234
  error: error63
33991
34235
  });
@@ -34075,9 +34319,9 @@ var RetryingTransport = class {
34075
34319
  this._transport = transport;
34076
34320
  }
34077
34321
  retry(data, timeoutMillis, inMillis) {
34078
- return new Promise((resolve12, reject) => {
34322
+ return new Promise((resolve13, reject) => {
34079
34323
  setTimeout(() => {
34080
- this._transport.send(data, timeoutMillis).then(resolve12, reject);
34324
+ this._transport.send(data, timeoutMillis).then(resolve13, reject);
34081
34325
  }, inMillis);
34082
34326
  });
34083
34327
  }
@@ -34190,8 +34434,8 @@ function getSharedConfigurationFromEnvironment(signalIdentifier) {
34190
34434
  init_esm();
34191
34435
 
34192
34436
  // ../../node_modules/@opentelemetry/otlp-exporter-base/build/esm/configuration/otlp-node-http-env-configuration.js
34193
- import * as fs6 from "fs";
34194
- import * as path12 from "path";
34437
+ import * as fs7 from "fs";
34438
+ import * as path13 from "path";
34195
34439
  init_esm();
34196
34440
  function getStaticHeadersFromEnv(signalIdentifier) {
34197
34441
  const signalSpecificRawHeaders = getStringFromEnv(`OTEL_EXPORTER_OTLP_${signalIdentifier}_HEADERS`);
@@ -34212,7 +34456,7 @@ function appendRootPathToUrlIfNeeded(url2) {
34212
34456
  return void 0;
34213
34457
  }
34214
34458
  }
34215
- function appendResourcePathToUrl(url2, path24) {
34459
+ function appendResourcePathToUrl(url2, path25) {
34216
34460
  try {
34217
34461
  new URL(url2);
34218
34462
  } catch {
@@ -34222,11 +34466,11 @@ function appendResourcePathToUrl(url2, path24) {
34222
34466
  if (!url2.endsWith("/")) {
34223
34467
  url2 = url2 + "/";
34224
34468
  }
34225
- url2 += path24;
34469
+ url2 += path25;
34226
34470
  try {
34227
34471
  new URL(url2);
34228
34472
  } catch {
34229
- diag2.warn(`Configuration: Provided URL appended with '${path24}' is not a valid URL, using 'undefined' instead of '${url2}'`);
34473
+ diag2.warn(`Configuration: Provided URL appended with '${path25}' is not a valid URL, using 'undefined' instead of '${url2}'`);
34230
34474
  return void 0;
34231
34475
  }
34232
34476
  return url2;
@@ -34251,7 +34495,7 @@ function readFileFromEnv(signalSpecificEnvVar, nonSignalSpecificEnvVar, warningM
34251
34495
  const filePath = signalSpecificPath ?? nonSignalSpecificPath;
34252
34496
  if (filePath != null) {
34253
34497
  try {
34254
- return fs6.readFileSync(path12.resolve(process.cwd(), filePath));
34498
+ return fs7.readFileSync(path13.resolve(process.cwd(), filePath));
34255
34499
  } catch {
34256
34500
  diag2.warn(warningMessage);
34257
34501
  return void 0;
@@ -34337,15 +34581,15 @@ var OTLPLogExporter = class extends OTLPExporterBase {
34337
34581
  init_esm();
34338
34582
 
34339
34583
  // ../telemetry/src/debug.ts
34340
- import * as fs7 from "node:fs";
34584
+ import * as fs8 from "node:fs";
34341
34585
 
34342
34586
  // ../telemetry/src/paths.ts
34343
- import * as path13 from "node:path";
34587
+ import * as path14 from "node:path";
34344
34588
  function identityFilePath() {
34345
- return path13.join(argentHomeDir(), "telemetry-id");
34589
+ return path14.join(argentHomeDir(), "telemetry-id");
34346
34590
  }
34347
34591
  function debugLogPath() {
34348
- return path13.join(argentHomeDir(), "telemetry-debug.log");
34592
+ return path14.join(argentHomeDir(), "telemetry-debug.log");
34349
34593
  }
34350
34594
 
34351
34595
  // ../telemetry/src/debug.ts
@@ -34375,8 +34619,8 @@ function emitDebugPayload(payload) {
34375
34619
  } catch {
34376
34620
  }
34377
34621
  try {
34378
- fs7.mkdirSync(argentHomeDir(), { recursive: true });
34379
- fs7.appendFileSync(debugLogPath(), line + "\n");
34622
+ fs8.mkdirSync(argentHomeDir(), { recursive: true });
34623
+ fs8.appendFileSync(debugLogPath(), line + "\n");
34380
34624
  } catch {
34381
34625
  }
34382
34626
  }
@@ -34747,6 +34991,7 @@ var ALLOWED = {
34747
34991
  "tool:invoke": {
34748
34992
  device_provider: DEVICE_PROVIDER,
34749
34993
  tool: TOOL_NAME,
34994
+ alias_used: bool,
34750
34995
  tool_invocation_id: UUID,
34751
34996
  platform: PLATFORM,
34752
34997
  device_kind: DEVICE_KIND,
@@ -34755,6 +35000,7 @@ var ALLOWED = {
34755
35000
  "tool:complete": {
34756
35001
  device_provider: DEVICE_PROVIDER,
34757
35002
  tool: TOOL_NAME,
35003
+ alias_used: bool,
34758
35004
  tool_invocation_id: UUID,
34759
35005
  platform: PLATFORM,
34760
35006
  device_kind: DEVICE_KIND,
@@ -34764,6 +35010,7 @@ var ALLOWED = {
34764
35010
  "tool:fail": {
34765
35011
  device_provider: DEVICE_PROVIDER,
34766
35012
  tool: TOOL_NAME,
35013
+ alias_used: bool,
34767
35014
  tool_invocation_id: UUID,
34768
35015
  platform: PLATFORM,
34769
35016
  device_kind: DEVICE_KIND,
@@ -34782,6 +35029,7 @@ var ALLOWED = {
34782
35029
  },
34783
35030
  "cli:run_fail": {
34784
35031
  tool: TOOL_NAME,
35032
+ alias_used: bool,
34785
35033
  duration_ms: DURATION_MS,
34786
35034
  ...FAILURE_SIGNAL
34787
35035
  },
@@ -34878,9 +35126,9 @@ function isReplitAgent(env) {
34878
35126
  }
34879
35127
  var DEVIN_MARKER_PATH = "/opt/.devin";
34880
35128
  var JULES_MARKER_PATH = "/opt/environment_summary.sh";
34881
- function safeExists(fileExists, path24) {
35129
+ function safeExists(fileExists, path25) {
34882
35130
  try {
34883
- return fileExists(path24);
35131
+ return fileExists(path25);
34884
35132
  } catch {
34885
35133
  return false;
34886
35134
  }
@@ -35301,7 +35549,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
35301
35549
  var SESSION_ID2 = randomUUID5();
35302
35550
  function readCliVersion() {
35303
35551
  if (true) {
35304
- return "0.29.1-next.9";
35552
+ return "0.30.0";
35305
35553
  }
35306
35554
  return "0.0.0";
35307
35555
  }
@@ -35334,8 +35582,8 @@ function getBaseProps(runtime) {
35334
35582
 
35335
35583
  // ../telemetry/src/identity.ts
35336
35584
  import * as crypto2 from "node:crypto";
35337
- import * as fs8 from "node:fs";
35338
- import * as path14 from "node:path";
35585
+ import * as fs9 from "node:fs";
35586
+ import * as path15 from "node:path";
35339
35587
  var FINGERPRINT_PATTERN = /^[0-9a-f]{64}$/;
35340
35588
  var cached2 = null;
35341
35589
  var fingerprintResolved = null;
@@ -35431,66 +35679,66 @@ function resolveFingerprintOnce(resolveFingerprint) {
35431
35679
  function isCorruptIdFile(filePath) {
35432
35680
  let isRegularFile;
35433
35681
  try {
35434
- isRegularFile = fs8.lstatSync(filePath).isFile();
35682
+ isRegularFile = fs9.lstatSync(filePath).isFile();
35435
35683
  } catch {
35436
35684
  return false;
35437
35685
  }
35438
35686
  return isRegularFile && tryReadId(filePath) === null;
35439
35687
  }
35440
35688
  function writeIdFileAtomic(finalPath, id) {
35441
- fs8.mkdirSync(argentHomeDir(), { recursive: true });
35689
+ fs9.mkdirSync(argentHomeDir(), { recursive: true });
35442
35690
  let occupant;
35443
35691
  try {
35444
- occupant = fs8.lstatSync(finalPath);
35692
+ occupant = fs9.lstatSync(finalPath);
35445
35693
  } catch (err) {
35446
35694
  if (err.code !== "ENOENT") throw err;
35447
35695
  }
35448
35696
  if (occupant && !occupant.isFile()) {
35449
35697
  throw new Error("telemetry: refusing to replace a non-regular file at the identity path");
35450
35698
  }
35451
- const tmpPath = path14.join(
35699
+ const tmpPath = path15.join(
35452
35700
  argentHomeDir(),
35453
35701
  `.telemetry-id.tmp.${process.pid}.${crypto2.randomUUID()}`
35454
35702
  );
35455
- const fd = fs8.openSync(tmpPath, "wx", 384);
35703
+ const fd = fs9.openSync(tmpPath, "wx", 384);
35456
35704
  try {
35457
35705
  try {
35458
- fs8.writeSync(fd, id);
35459
- fs8.fsyncSync(fd);
35706
+ fs9.writeSync(fd, id);
35707
+ fs9.fsyncSync(fd);
35460
35708
  } finally {
35461
- fs8.closeSync(fd);
35709
+ fs9.closeSync(fd);
35462
35710
  }
35463
- fs8.renameSync(tmpPath, finalPath);
35711
+ fs9.renameSync(tmpPath, finalPath);
35464
35712
  } finally {
35465
35713
  try {
35466
- fs8.unlinkSync(tmpPath);
35714
+ fs9.unlinkSync(tmpPath);
35467
35715
  } catch {
35468
35716
  }
35469
35717
  }
35470
35718
  }
35471
35719
  function mintRandomId(finalPath) {
35472
- fs8.mkdirSync(argentHomeDir(), { recursive: true });
35720
+ fs9.mkdirSync(argentHomeDir(), { recursive: true });
35473
35721
  let value = crypto2.randomUUID();
35474
35722
  for (let attempt = 0; attempt < 3; attempt++) {
35475
- const tmpPath = path14.join(
35723
+ const tmpPath = path15.join(
35476
35724
  argentHomeDir(),
35477
35725
  `.telemetry-id.tmp.${process.pid}.${crypto2.randomUUID()}`
35478
35726
  );
35479
35727
  let fd;
35480
35728
  try {
35481
- fd = fs8.openSync(tmpPath, "wx", 384);
35729
+ fd = fs9.openSync(tmpPath, "wx", 384);
35482
35730
  } catch (err) {
35483
35731
  if (err.code === "EEXIST") continue;
35484
35732
  throw err;
35485
35733
  }
35486
35734
  try {
35487
35735
  try {
35488
- fs8.writeSync(fd, value);
35489
- fs8.fsyncSync(fd);
35736
+ fs9.writeSync(fd, value);
35737
+ fs9.fsyncSync(fd);
35490
35738
  } finally {
35491
- fs8.closeSync(fd);
35739
+ fs9.closeSync(fd);
35492
35740
  }
35493
- fs8.linkSync(tmpPath, finalPath);
35741
+ fs9.linkSync(tmpPath, finalPath);
35494
35742
  cached2 = { path: finalPath, id: value };
35495
35743
  return value;
35496
35744
  } catch (err) {
@@ -35509,7 +35757,7 @@ function mintRandomId(finalPath) {
35509
35757
  throw err;
35510
35758
  } finally {
35511
35759
  try {
35512
- fs8.unlinkSync(tmpPath);
35760
+ fs9.unlinkSync(tmpPath);
35513
35761
  } catch {
35514
35762
  }
35515
35763
  }
@@ -35517,12 +35765,12 @@ function mintRandomId(finalPath) {
35517
35765
  throw new Error("telemetry: failed to create identity after retries");
35518
35766
  }
35519
35767
  function claimCorruptOccupant(finalPath) {
35520
- const claimed = path14.join(
35768
+ const claimed = path15.join(
35521
35769
  argentHomeDir(),
35522
35770
  `.telemetry-id.corrupt.${process.pid}.${crypto2.randomUUID()}`
35523
35771
  );
35524
35772
  try {
35525
- fs8.renameSync(finalPath, claimed);
35773
+ fs9.renameSync(finalPath, claimed);
35526
35774
  } catch {
35527
35775
  return null;
35528
35776
  }
@@ -35531,7 +35779,7 @@ function claimCorruptOccupant(finalPath) {
35531
35779
  grabbed = tryReadId(claimed);
35532
35780
  } finally {
35533
35781
  try {
35534
- fs8.unlinkSync(claimed);
35782
+ fs9.unlinkSync(claimed);
35535
35783
  } catch {
35536
35784
  }
35537
35785
  }
@@ -35543,9 +35791,9 @@ function peekAnonId() {
35543
35791
  function tryReadId(filePath) {
35544
35792
  let raw;
35545
35793
  try {
35546
- const stats = fs8.lstatSync(filePath);
35794
+ const stats = fs9.lstatSync(filePath);
35547
35795
  if (!stats.isFile()) return null;
35548
- raw = fs8.readFileSync(filePath, "utf8");
35796
+ raw = fs9.readFileSync(filePath, "utf8");
35549
35797
  } catch (err) {
35550
35798
  if (err.code === "ENOENT") return null;
35551
35799
  return null;
@@ -35559,12 +35807,12 @@ function tryReadId(filePath) {
35559
35807
  import { execFileSync as execFileSync2, spawn as spawn2 } from "node:child_process";
35560
35808
 
35561
35809
  // ../native-devtools-ios/src/index.ts
35562
- import * as path15 from "node:path";
35563
- import * as fs9 from "node:fs";
35564
- var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path15.join(__dirname, "..", "dylibs");
35565
- var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path15.join(__dirname, "..", "bin");
35566
- var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path15.join(DYLIB_DIR, "tcp");
35567
- var DYLIB_TVOS_DIR = path15.join(DYLIB_DIR, "tvos");
35810
+ import * as path16 from "node:path";
35811
+ import * as fs10 from "node:fs";
35812
+ var DYLIB_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_DIR ?? path16.join(__dirname, "..", "dylibs");
35813
+ var BIN_DIR = process.env.ARGENT_SIMULATOR_SERVER_DIR ?? path16.join(__dirname, "..", "bin");
35814
+ var DYLIB_TCP_DIR = process.env.ARGENT_NATIVE_DEVTOOLS_TCP_DIR ?? path16.join(DYLIB_DIR, "tcp");
35815
+ var DYLIB_TVOS_DIR = path16.join(DYLIB_DIR, "tvos");
35568
35816
  function hostPlatformKey() {
35569
35817
  if (process.platform === "linux" && process.arch === "arm64") {
35570
35818
  return "linux-arm64";
@@ -35575,14 +35823,14 @@ function simulatorServerBinaryName() {
35575
35823
  return process.platform === "win32" ? "simulator-server.exe" : "simulator-server";
35576
35824
  }
35577
35825
  function platformBinDir() {
35578
- return path15.join(BIN_DIR, hostPlatformKey());
35826
+ return path16.join(BIN_DIR, hostPlatformKey());
35579
35827
  }
35580
35828
  function simulatorServerBinaryPath() {
35581
35829
  const binaryName = simulatorServerBinaryName();
35582
- const p = path15.join(platformBinDir(), binaryName);
35583
- if (!fs9.existsSync(p)) {
35584
- const flat = path15.join(BIN_DIR, binaryName);
35585
- const migrationHint = fs9.existsSync(flat) ? ` Found a binary at the old flat path ${flat}; move it to ${p} or update ARGENT_SIMULATOR_SERVER_DIR to point at the parent of the platform subdirectory.` : "";
35830
+ const p = path16.join(platformBinDir(), binaryName);
35831
+ if (!fs10.existsSync(p)) {
35832
+ const flat = path16.join(BIN_DIR, binaryName);
35833
+ const migrationHint = fs10.existsSync(flat) ? ` Found a binary at the old flat path ${flat}; move it to ${p} or update ARGENT_SIMULATOR_SERVER_DIR to point at the parent of the platform subdirectory.` : "";
35586
35834
  throw new Error(
35587
35835
  `simulator-server binary not found for platform "${hostPlatformKey()}" at ${p}. Supported hosts today: darwin, linux (x86_64 and arm64), win32.${migrationHint}`
35588
35836
  );
@@ -35611,12 +35859,12 @@ function resolveHostFingerprint() {
35611
35859
  }
35612
35860
  }
35613
35861
  function resolveHostFingerprintAsync() {
35614
- return new Promise((resolve12) => {
35862
+ return new Promise((resolve13) => {
35615
35863
  let binary;
35616
35864
  try {
35617
35865
  binary = simulatorServerBinaryPath();
35618
35866
  } catch {
35619
- resolve12(null);
35867
+ resolve13(null);
35620
35868
  return;
35621
35869
  }
35622
35870
  let settled = false;
@@ -35629,7 +35877,7 @@ function resolveHostFingerprintAsync() {
35629
35877
  child?.kill("SIGKILL");
35630
35878
  } catch {
35631
35879
  }
35632
- resolve12(value);
35880
+ resolve13(value);
35633
35881
  };
35634
35882
  const watchdog = setTimeout(() => finish(null), FINGERPRINT_TIMEOUT_MS);
35635
35883
  watchdog.unref?.();
@@ -35662,14 +35910,14 @@ function resolveHostFingerprintAsync() {
35662
35910
  }
35663
35911
 
35664
35912
  // ../telemetry/src/consent.ts
35665
- import * as fs10 from "node:fs";
35913
+ import * as fs11 from "node:fs";
35666
35914
  var cache = /* @__PURE__ */ new Map();
35667
35915
  var sessionOverride = null;
35668
35916
  function readConfigOverrideAt(filePath) {
35669
35917
  const miss = { mtimeMs: null, fingerprint: null, enabledOverride: null };
35670
35918
  let stats;
35671
35919
  try {
35672
- stats = fs10.lstatSync(filePath);
35920
+ stats = fs11.lstatSync(filePath);
35673
35921
  } catch {
35674
35922
  cache.set(filePath, miss);
35675
35923
  return null;
@@ -35686,7 +35934,7 @@ function readConfigOverrideAt(filePath) {
35686
35934
  }
35687
35935
  let parsedEnabled = null;
35688
35936
  try {
35689
- const raw = fs10.readFileSync(filePath, "utf8");
35937
+ const raw = fs11.readFileSync(filePath, "utf8");
35690
35938
  const json2 = JSON.parse(raw);
35691
35939
  if (json2 && typeof json2 === "object") {
35692
35940
  const t2 = json2.telemetry;
@@ -35843,7 +36091,7 @@ var DRAIN_GRACE_MS = 250;
35843
36091
  async function raceDrain(client2, timeoutMs) {
35844
36092
  await Promise.race([
35845
36093
  client2.shutdown(timeoutMs),
35846
- new Promise((resolve12) => setTimeout(resolve12, timeoutMs + DRAIN_GRACE_MS).unref())
36094
+ new Promise((resolve13) => setTimeout(resolve13, timeoutMs + DRAIN_GRACE_MS).unref())
35847
36095
  ]);
35848
36096
  }
35849
36097
  async function shutdown(timeoutMs = SHORT_FLUSH_TIMEOUT_MS) {
@@ -36267,13 +36515,13 @@ function splitOptions(argv) {
36267
36515
  return { json: json2, outPath, argvForFlags: rest };
36268
36516
  }
36269
36517
  async function readStdin() {
36270
- return new Promise((resolve12, reject) => {
36518
+ return new Promise((resolve13, reject) => {
36271
36519
  let data = "";
36272
36520
  process.stdin.setEncoding("utf8");
36273
36521
  process.stdin.on("data", (chunk) => {
36274
36522
  data += chunk;
36275
36523
  });
36276
- process.stdin.on("end", () => resolve12(data));
36524
+ process.stdin.on("end", () => resolve13(data));
36277
36525
  process.stdin.on("error", reject);
36278
36526
  });
36279
36527
  }
@@ -36305,8 +36553,8 @@ async function fetchImageToFile(result, outPath) {
36305
36553
  const res = await fetch(url2);
36306
36554
  if (!res.ok) throw new Error(`Failed to download image: ${res.status} ${res.statusText}`);
36307
36555
  const buf = Buffer.from(await res.arrayBuffer());
36308
- fs11.mkdirSync(path16.dirname(path16.resolve(outPath)), { recursive: true });
36309
- fs11.writeFileSync(outPath, buf);
36556
+ fs12.mkdirSync(path17.dirname(path17.resolve(outPath)), { recursive: true });
36557
+ fs12.writeFileSync(outPath, buf);
36310
36558
  }
36311
36559
  function renderResult(result, outputHint, images, json2) {
36312
36560
  if (json2) return JSON.stringify(result, null, 2);
@@ -36324,8 +36572,10 @@ function safeToolName(toolName) {
36324
36572
  return toolName && SAFE_TOOL_RE.test(toolName) ? toolName : "unknown";
36325
36573
  }
36326
36574
  async function trackRunFailure(toolName, startedAt, signal) {
36575
+ const tool = toolName ? canonicalToolId(toolName) : toolName;
36327
36576
  track("cli:run_fail", {
36328
- tool: safeToolName(toolName),
36577
+ tool: safeToolName(tool),
36578
+ ...tool !== toolName ? { alias_used: true } : {},
36329
36579
  duration_ms: performance.now() - startedAt,
36330
36580
  ...signal
36331
36581
  });
@@ -36500,8 +36750,8 @@ Examples:
36500
36750
  if (outPath && meta3.outputHint === "image") {
36501
36751
  try {
36502
36752
  if (images.length > 0) {
36503
- fs11.mkdirSync(path16.dirname(path16.resolve(outPath)), { recursive: true });
36504
- fs11.writeFileSync(outPath, images[0].data);
36753
+ fs12.mkdirSync(path17.dirname(path17.resolve(outPath)), { recursive: true });
36754
+ fs12.writeFileSync(outPath, images[0].data);
36505
36755
  } else if (result && typeof result === "object") {
36506
36756
  await fetchImageToFile(result, outPath);
36507
36757
  }
@@ -36523,11 +36773,11 @@ Examples:
36523
36773
  }
36524
36774
  }
36525
36775
 
36526
- // ../argent-cli/src/flow.ts
36776
+ // ../argent-cli/src/e2e.ts
36527
36777
  import * as fsp from "node:fs/promises";
36528
36778
  import { constants as fsConstants2 } from "node:fs";
36529
36779
  import { createHash as createHash5 } from "node:crypto";
36530
- import * as path17 from "node:path";
36780
+ import * as path18 from "node:path";
36531
36781
 
36532
36782
  // ../argent-cli/src/command-args.ts
36533
36783
  var UsageError = class extends Error {
@@ -36599,7 +36849,7 @@ function parseCommandArgs(argv, specs) {
36599
36849
  return { positionals, options };
36600
36850
  }
36601
36851
 
36602
- // ../argent-cli/src/flow.ts
36852
+ // ../argent-cli/src/e2e.ts
36603
36853
  var STATUS_GLYPH = {
36604
36854
  pass: "\u2713",
36605
36855
  fail: "\u2717",
@@ -36620,93 +36870,96 @@ function durationSuffix(ms) {
36620
36870
  }
36621
36871
  function printHelp(toStderr = false) {
36622
36872
  const print = toStderr ? console.error : console.log;
36623
- print(`Usage: argent flow <subcommand> [options]
36873
+ print(`Usage: argent e2e <subcommand> [options]
36624
36874
 
36625
- Run a YAML flow without an LLM in the loop. \`run\` takes any of these forms:
36875
+ Run a YAML e2e test without an LLM in the loop. \`run\` takes any of these forms:
36626
36876
 
36627
- a name A flow saved under .argent/flows \u2014 "checkout" runs
36628
- .argent/flows/checkout.yaml, resolved from the current directory
36877
+ a name An e2e test saved under .argent/e2e or .argent/flows, resolved
36878
+ from the current directory. "checkout" runs
36879
+ .argent/e2e/checkout.yaml, or .argent/flows/checkout.yaml when only
36880
+ that one exists
36629
36881
  a path Any .yaml file on the local filesystem, resolved from the current
36630
36882
  directory. It must not contain ".." segments (pass the resolved
36631
- path instead); a path is what reaches flows kept elsewhere, and
36632
- what \`argent flow list\` prints for nested ones
36633
- a dir Every flow in that directory, run sequentially
36883
+ path instead); a path is what reaches e2e tests kept elsewhere, and
36884
+ what \`argent e2e list\` prints for nested ones
36885
+ a dir Every e2e test in that directory, run sequentially
36634
36886
 
36635
36887
  For a name and for a file path alike, the
36636
36888
  filename (minus .yaml) names the run's report and artifacts, so it must
36637
36889
  contain only letters, numbers, "_", or "-" \u2014 the same charset a name must
36638
- match. A flow is e2e when its first non-\`echo\`/\`script\` step is \`launch\`.
36639
- Other flows are fragments and use the device's current state. Exception: a fragment whose first step \`run:\`s a chromium e2e
36640
- flow boots that flow's app before step 1 \u2014 when that launch is unambiguously
36890
+ match. A test is standalone when its first non-\`echo\`/\`script\` step is \`launch\`.
36891
+ Other tests are fragments and use the device's current state. Exception: a fragment whose first step \`run:\`s a chromium standalone
36892
+ test boots that test's app before step 1 \u2014 when that launch is unambiguously
36641
36893
  chromium (a lone \`{ chromium: ... }\` target, or --platform chromium); a
36642
36894
  multi-platform launch auto-detects a device instead. Pass --device to attach to
36643
36895
  a running instance.
36644
36896
 
36645
36897
  A directory run prints only the steps that need attention (each failure, each
36646
- warning, and each script step's output), then its outcome. After the last flow
36647
- it lists every failed flow with its reason and a command that re-runs that flow
36648
- alone, then a final flow summary; --recursive walks subdirectories too
36649
- (dot-directories and node_modules are skipped). A flow that fails its steps
36898
+ warning, and each script step's output), then its outcome. After the last test
36899
+ it lists every failed test with its reason and a command that re-runs that test
36900
+ alone, then a final summary; --recursive walks subdirectories too
36901
+ (dot-directories and node_modules are skipped). A test that fails its steps
36650
36902
  keeps the batch running, as does one the server rejects up front \u2014 an invalid
36651
36903
  file, or a device it cannot resolve. A transport failure, a rejection the server
36652
36904
  does not mark as validation, or a reply that is not a report stops the batch and
36653
- counts the remaining flows skipped.
36905
+ counts the remaining tests skipped.
36654
36906
 
36655
36907
  The CLI sends a run to its tool-server: the local one that starts
36656
36908
  automatically, or the one that \`argent link\` or ARGENT_TOOLS_URL names. Over
36657
36909
  a link, the CLI uploads these files and writes the new baselines that the run
36658
36910
  returns:
36659
- - the flow file and the run: fragments that it reaches
36660
- - each flow that a tool: flow-execute step names with name (a nested flow)
36911
+ - the e2e test file and the run: fragments that it reaches
36912
+ - each e2e test that a tool: e2e-execute step names with name (a nested test)
36661
36913
  - the snapshot baselines of each run
36662
36914
  - each .png or .yaml file that a tool: step takes as a file argument by an
36663
36915
  absolute path
36664
- The tool-server rejects the flow before the first step when the flow, a
36665
- fragment or a nested flow has one of these steps:
36916
+ The tool-server rejects the test before the first step when the test, a
36917
+ fragment or a nested test has one of these steps:
36666
36918
  - a script: step
36667
- - a tool: flow-execute step that does not name its flow with name and an
36919
+ - a tool: e2e-execute step that does not name its test with name and an
36668
36920
  absolute project_root that has no .. segment
36669
- - a tool: step that records a flow
36921
+ - a tool: step that records an e2e test
36670
36922
  - a tool: step that takes a directory, an app or an output directory
36671
36923
  - a tool: step whose tool builds a file path from several arguments
36672
36924
  - a tool: step that names a relative path or a file other than .png or .yaml
36673
36925
  Without a link, all step kinds run.
36674
36926
 
36675
36927
  Subcommands:
36676
- run <flow|flow.yaml|dir> Run a saved flow by name, a YAML file by path, or
36677
- every flow in a directory, and report pass/fail
36928
+ run <test|test.yaml|dir> Run a saved e2e test by name, a YAML file by path,
36929
+ or every test in a directory, and report pass/fail
36678
36930
  (exit reflects result)
36679
- list List runnable YAML paths in .argent/flows
36931
+ list List runnable YAML paths in .argent/e2e and
36932
+ .argent/flows (legacy); notes go to stderr
36680
36933
 
36681
36934
  Options (run):
36682
36935
  --device <id> Device id to run against (auto-detected when omitted)
36683
36936
  --platform <p> ios | android | chromium | vega | ios-remote \u2014 narrow
36684
36937
  auto-detection (ios never picks a remote simulator)
36685
36938
  --update-baselines Write/refresh screenshot baselines instead of diffing,
36686
- also those of flows that tool: flow-execute steps run,
36939
+ also those of tests that tool: e2e-execute steps run,
36687
36940
  unless such a step sets updateBaselines
36688
36941
  --output <dir> Also write failed snapshot images (baseline/current/diff)
36689
36942
  and failed-step screenshots (step-<n>-screen.png)
36690
- under <dir>/<flow>/ \u2014 a stable path for CI artifact
36691
- upload; a directory run keys nested flows as
36692
- <dir>/<subdir>/<flow>/. A different flow file with the
36693
- same filename sharing <dir> exports to <flow>-<pathhash>/
36694
- instead (with a warning), so no flow's evidence is
36943
+ under <dir>/<test>/ \u2014 a stable path for CI artifact
36944
+ upload; a directory run keys nested tests as
36945
+ <dir>/<subdir>/<test>/. A different test file with the
36946
+ same filename sharing <dir> exports to <test>-<pathhash>/
36947
+ instead (with a warning), so no test's evidence is
36695
36948
  overwritten
36696
- -r, --recursive With a directory path, also run flows in subdirectories
36697
- --json Print the flow's JSON report, or a directory run's JSON
36949
+ -r, --recursive With a directory path, also run tests in subdirectories
36950
+ --json Print the test's JSON report, or a directory run's JSON
36698
36951
  aggregate
36699
36952
  --json-stream Print each step and the final report as NDJSON (single
36700
- flow only, never with --json)
36953
+ test only, never with --json)
36701
36954
  --help, -h Show this help
36702
- -- End of options \u2014 only needed for a flow whose name
36703
- starts with "-" (\`argent flow run -- -nightly\`)
36955
+ -- End of options \u2014 only needed for a test whose name
36956
+ starts with "-" (\`argent e2e run -- -nightly\`)
36704
36957
 
36705
36958
  Examples:
36706
- argent flow run checkout --platform ios
36707
- argent flow run .argent/flows/checkout.yaml --output flow-artifacts --json
36708
- argent flow run ~/shared-flows/checkout.yaml --device <UDID> --update-baselines
36709
- argent flow run .argent/flows --recursive
36959
+ argent e2e run checkout --platform ios
36960
+ argent e2e run .argent/e2e/checkout.yaml --output e2e-artifacts --json
36961
+ argent e2e run ~/shared-e2e/checkout.yaml --device <UDID> --update-baselines
36962
+ argent e2e run .argent/e2e --recursive
36710
36963
  `);
36711
36964
  }
36712
36965
  var RUN_OPTIONS = {
@@ -36729,7 +36982,7 @@ function parseRunArgs(argv) {
36729
36982
  const { positionals, options } = parsed;
36730
36983
  if (positionals.length > 1) {
36731
36984
  throw new FlagParseException(
36732
- `unexpected argument ${JSON.stringify(positionals[1])}; flow run accepts one flow name, YAML file path, or directory path`
36985
+ `unexpected argument ${JSON.stringify(positionals[1])}; e2e run accepts one e2e test name, YAML file path, or directory path`
36733
36986
  );
36734
36987
  }
36735
36988
  const out = {
@@ -36829,7 +37082,7 @@ function renderFailedSteps(report) {
36829
37082
  return lines;
36830
37083
  }
36831
37084
  function renderBatchSummary(counts, durationMs) {
36832
- return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} flow${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped${durationSuffix(durationMs)}`;
37085
+ return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} e2e test${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped${durationSuffix(durationMs)}`;
36833
37086
  }
36834
37087
  function summarizeFailure(report) {
36835
37088
  let n3 = 0;
@@ -36856,34 +37109,33 @@ function renderFailedFlows(failed) {
36856
37109
  if (failed.length === 0) return [];
36857
37110
  return [
36858
37111
  "",
36859
- `Failed flows (${failed.length})`,
37112
+ `Failed e2e tests (${failed.length})`,
36860
37113
  ...failed.flatMap((f) => ["", ...renderFailedFlow(f)])
36861
37114
  ];
36862
37115
  }
36863
37116
  var SAFE_ARTIFACT_NAME = FLOW_NAME_PATTERN;
36864
37117
  var SAFE_FLOW_NAME = FLOW_NAME_PATTERN;
36865
- var FLOWS_DIR = path17.join(".argent", "flows");
36866
37118
  var SHELL_SAFE_ARG = /^(?!=)[A-Za-z0-9_@%+=:,./-]+$/;
36867
37119
  function shellQuoteArg(arg) {
36868
37120
  if (SHELL_SAFE_ARG.test(arg)) return arg;
36869
37121
  return `'${arg.replaceAll("'", "'\\''")}'`;
36870
37122
  }
36871
37123
  function rerunCommand(flowPath, rel, projectRoot, args) {
36872
- const pathArg = (p) => shellQuoteArg(p.startsWith("-") ? `.${path17.sep}${p}` : p);
36873
- const fromCwd = path17.relative(projectRoot, flowPath);
36874
- const shown = path17.isAbsolute(fromCwd) || fromCwd.split(/[\\/]+/).includes("..") ? flowPath : fromCwd;
36875
- const parts = ["argent flow run", pathArg(shown)];
37124
+ const pathArg = (p) => shellQuoteArg(p.startsWith("-") ? `.${path18.sep}${p}` : p);
37125
+ const fromCwd = path18.relative(projectRoot, flowPath);
37126
+ const shown = path18.isAbsolute(fromCwd) || fromCwd.split(/[\\/]+/).includes("..") ? flowPath : fromCwd;
37127
+ const parts = ["argent e2e run", pathArg(shown)];
36876
37128
  if (args.device) parts.push("--device", shellQuoteArg(args.device));
36877
37129
  if (args.platform) parts.push("--platform", shellQuoteArg(args.platform));
36878
37130
  if (args.updateBaselines) parts.push("--update-baselines");
36879
- if (args.output) parts.push("--output", pathArg(path17.join(args.output, path17.dirname(rel))));
37131
+ if (args.output) parts.push("--output", pathArg(path18.join(args.output, path18.dirname(rel))));
36880
37132
  return parts.join(" ");
36881
37133
  }
36882
37134
  var EXPORT_SOURCE_MARKER = ".argent-flow-source";
36883
37135
  var MARKER_READ_RETRIES = 4;
36884
37136
  var MARKER_READ_DELAY_MS = 5;
36885
37137
  async function readExportMarker(dir) {
36886
- const marker = path17.join(dir, EXPORT_SOURCE_MARKER);
37138
+ const marker = path18.join(dir, EXPORT_SOURCE_MARKER);
36887
37139
  for (let attempt = 0; ; attempt++) {
36888
37140
  let owner;
36889
37141
  try {
@@ -36893,7 +37145,7 @@ async function readExportMarker(dir) {
36893
37145
  }
36894
37146
  if (owner) return owner;
36895
37147
  if (attempt === MARKER_READ_RETRIES) return null;
36896
- await new Promise((resolve12) => setTimeout(resolve12, MARKER_READ_DELAY_MS));
37148
+ await new Promise((resolve13) => setTimeout(resolve13, MARKER_READ_DELAY_MS));
36897
37149
  }
36898
37150
  }
36899
37151
  async function classifyExportDir(dir, flowPath) {
@@ -36918,7 +37170,7 @@ function occupiedBy(owner) {
36918
37170
  async function takeExportDir(dir, flowPath) {
36919
37171
  try {
36920
37172
  await fsp.mkdir(dir, { recursive: true });
36921
- await fsp.writeFile(path17.join(dir, EXPORT_SOURCE_MARKER), `${flowPath}
37173
+ await fsp.writeFile(path18.join(dir, EXPORT_SOURCE_MARKER), `${flowPath}
36922
37174
  `, { flag: "wx" });
36923
37175
  return null;
36924
37176
  } catch (err) {
@@ -36937,7 +37189,7 @@ async function claimExportDirName(outputDir, flowPath, stem) {
36937
37189
  }
36938
37190
  const avoided = [];
36939
37191
  for (const name of candidates) {
36940
- const dir = path17.join(outputDir, name);
37192
+ const dir = path18.join(outputDir, name);
36941
37193
  const claim2 = await classifyExportDir(dir, flowPath);
36942
37194
  const reason = claim2.state === "foreign" ? occupiedBy(claim2.owner) : await takeExportDir(dir, flowPath);
36943
37195
  if (reason !== null) {
@@ -36946,7 +37198,7 @@ async function claimExportDirName(outputDir, flowPath, stem) {
36946
37198
  }
36947
37199
  for (const entry of avoided) {
36948
37200
  console.error(
36949
- `warning: ${entry.dir} ${entry.reason}; writing this flow's artifacts to ${dir} so neither set is overwritten`
37201
+ `warning: ${entry.dir} ${entry.reason}; writing this e2e test's artifacts to ${dir} so neither set is overwritten`
36950
37202
  );
36951
37203
  }
36952
37204
  return name;
@@ -36957,10 +37209,10 @@ async function claimExportDirName(outputDir, flowPath, stem) {
36957
37209
  return null;
36958
37210
  }
36959
37211
  async function exportFailureArtifacts(report, outputDir, flowPath, ctx) {
36960
- const stem = path17.basename(flowPath, ".yaml");
37212
+ const stem = path18.basename(flowPath, ".yaml");
36961
37213
  if (!SAFE_ARTIFACT_NAME.test(stem)) {
36962
37214
  console.error(
36963
- `warning: skipping artifact export for unsafe flow filename ${JSON.stringify(stem)}`
37215
+ `warning: skipping artifact export for unsafe e2e test filename ${JSON.stringify(stem)}`
36964
37216
  );
36965
37217
  return;
36966
37218
  }
@@ -36990,11 +37242,11 @@ async function exportFailureArtifacts(report, outputDir, flowPath, ctx) {
36990
37242
  if (dir === null) {
36991
37243
  const dirName = await claimExportDirName(outputDir, flowPath, stem);
36992
37244
  if (dirName === null) return;
36993
- dir = path17.join(outputDir, dirName);
37245
+ dir = path18.join(outputDir, dirName);
36994
37246
  }
36995
- const dest = path17.join(dir, fileName(role));
36996
- const rel = path17.relative(outputDir, dest);
36997
- if (rel.startsWith("..") || path17.isAbsolute(rel)) continue;
37247
+ const dest = path18.join(dir, fileName(role));
37248
+ const rel = path18.relative(outputDir, dest);
37249
+ if (rel.startsWith("..") || path18.isAbsolute(rel)) continue;
36998
37250
  try {
36999
37251
  await fsp.copyFile(value, dest);
37000
37252
  s.artifacts[role] = dest;
@@ -37009,7 +37261,7 @@ async function exportFailureArtifacts(report, outputDir, flowPath, ctx) {
37009
37261
  function keyFromBaselinePath(artifacts) {
37010
37262
  const baseline = artifacts.baseline;
37011
37263
  if (typeof baseline !== "string") return null;
37012
- return path17.basename(baseline).replace(/\.png$/, "");
37264
+ return path18.basename(baseline).replace(/\.png$/, "");
37013
37265
  }
37014
37266
  function resolveArtifactDisplayPaths(report) {
37015
37267
  for (const s of report.steps) {
@@ -37021,12 +37273,12 @@ function resolveArtifactDisplayPaths(report) {
37021
37273
  }
37022
37274
  function exitAfterFlush(code, streams = [process.stdout, process.stderr]) {
37023
37275
  return Promise.all(
37024
- streams.map((s) => new Promise((resolve12) => s.write("", () => resolve12())))
37276
+ streams.map((s) => new Promise((resolve13) => s.write("", () => resolve13())))
37025
37277
  ).then(() => process.exit(code));
37026
37278
  }
37027
37279
  function renderReport(report) {
37028
37280
  const lines = [];
37029
- lines.push(`Flow "${report.flow}"${report.device ? ` on ${report.device}` : ""}`);
37281
+ lines.push(`E2E test "${report.flow}"${report.device ? ` on ${report.device}` : ""}`);
37030
37282
  if (report.executionPrerequisite) {
37031
37283
  lines.push(` assumes: ${report.executionPrerequisite}`);
37032
37284
  }
@@ -37054,8 +37306,8 @@ ${renderSummary(report)}`);
37054
37306
  }
37055
37307
  async function isRunnableFlowFile(filePath) {
37056
37308
  try {
37057
- const stat6 = await fsp.stat(filePath);
37058
- if (!stat6.isFile()) return false;
37309
+ const stat7 = await fsp.stat(filePath);
37310
+ if (!stat7.isFile()) return false;
37059
37311
  await fsp.access(filePath, fsConstants2.R_OK);
37060
37312
  return true;
37061
37313
  } catch {
@@ -37066,59 +37318,70 @@ async function collectRunnableFlowPaths(dir, relDir = "") {
37066
37318
  const found = [];
37067
37319
  const entries = await fsp.readdir(dir, { withFileTypes: true });
37068
37320
  for (const entry of entries) {
37069
- const rel = relDir ? path17.join(relDir, entry.name) : entry.name;
37321
+ const rel = relDir ? path18.join(relDir, entry.name) : entry.name;
37070
37322
  if (entry.isDirectory()) {
37071
37323
  if (entry.name === "__baselines__") continue;
37072
37324
  found.push(
37073
- ...await collectRunnableFlowPaths(path17.join(dir, entry.name), rel).catch(() => [])
37325
+ ...await collectRunnableFlowPaths(path18.join(dir, entry.name), rel).catch(() => [])
37074
37326
  );
37075
37327
  continue;
37076
37328
  }
37077
37329
  if (!entry.name.endsWith(".yaml")) continue;
37078
- if (!SAFE_FLOW_NAME.test(path17.basename(entry.name, ".yaml"))) continue;
37079
- if (await isRunnableFlowFile(path17.join(dir, entry.name))) found.push(rel);
37330
+ if (!SAFE_FLOW_NAME.test(path18.basename(entry.name, ".yaml"))) continue;
37331
+ if (await isRunnableFlowFile(path18.join(dir, entry.name))) found.push(rel);
37080
37332
  }
37081
37333
  return found;
37082
37334
  }
37083
- function resolveFlowRef(ref) {
37335
+ async function resolveFlowRef(ref, projectRoot) {
37084
37336
  if (!SAFE_FLOW_NAME.test(ref)) return { suppliedPath: ref, fromName: false };
37085
- return { suppliedPath: path17.join(FLOWS_DIR, `${ref}.yaml`), fromName: true };
37337
+ const picked = await resolveE2eFile(projectRoot, ref);
37338
+ return {
37339
+ suppliedPath: path18.relative(projectRoot, picked.path),
37340
+ fromName: true,
37341
+ ...picked.shadowed === void 0 ? {} : { shadowed: path18.relative(projectRoot, picked.shadowed) }
37342
+ };
37086
37343
  }
37087
37344
  async function savedFlowHint(projectRoot, missingPath) {
37088
- const dir = path17.resolve(projectRoot, FLOWS_DIR);
37089
- const within = path17.relative(dir, missingPath);
37090
- if (!within.startsWith("..") && !path17.isAbsolute(within)) return "";
37091
- const wanted = `${path17.basename(missingPath, ".yaml")}.yaml`;
37092
- const entries = await fsp.readdir(dir).catch(() => null);
37093
- if (entries === null) return "";
37094
- const actual = entries.includes(wanted) ? wanted : entries.find((name2) => name2.toLowerCase() === wanted.toLowerCase());
37095
- if (actual === void 0) return "";
37096
- const name = path17.basename(actual, ".yaml");
37097
- if (!SAFE_FLOW_NAME.test(name)) return "";
37098
- if (!await isRunnableFlowFile(path17.join(dir, actual))) return "";
37099
- return `
37100
- A flow named "${name}" is saved under ${FLOWS_DIR} \u2014 did you mean: argent flow run ${name}`;
37345
+ const dirs = E2E_DIRS.map((rel) => ({ rel, abs: path18.resolve(projectRoot, rel) }));
37346
+ for (const { abs } of dirs) {
37347
+ const within = path18.relative(abs, missingPath);
37348
+ if (!within.startsWith("..") && !path18.isAbsolute(within)) return "";
37349
+ }
37350
+ const wanted = `${path18.basename(missingPath, ".yaml")}.yaml`;
37351
+ for (const { rel, abs } of dirs) {
37352
+ const entries = await fsp.readdir(abs).catch(() => null);
37353
+ if (entries === null) continue;
37354
+ const actual = entries.includes(wanted) ? wanted : entries.find((name2) => name2.toLowerCase() === wanted.toLowerCase());
37355
+ if (actual === void 0) continue;
37356
+ const name = path18.basename(actual, ".yaml");
37357
+ if (!SAFE_FLOW_NAME.test(name)) return "";
37358
+ if (!await isRunnableFlowFile(path18.join(abs, actual))) return "";
37359
+ return `
37360
+ An e2e test named "${name}" is saved under ${rel} \u2014 did you mean: argent e2e run ${name}`;
37361
+ }
37362
+ return "";
37101
37363
  }
37102
37364
  async function collectFlowFiles(dir, recursive2) {
37103
37365
  const found = [];
37104
37366
  const walk = async (current, rel) => {
37105
37367
  for (const entry of await fsp.readdir(current, { withFileTypes: true })) {
37106
- const entryRel = rel ? path17.join(rel, entry.name) : entry.name;
37368
+ const entryRel = rel ? path18.join(rel, entry.name) : entry.name;
37107
37369
  if (entry.isDirectory()) {
37108
37370
  if (recursive2 && !entry.name.startsWith(".") && entry.name !== "node_modules") {
37109
- await walk(path17.join(current, entry.name), entryRel).catch(() => {
37371
+ await walk(path18.join(current, entry.name), entryRel).catch(() => {
37110
37372
  });
37111
37373
  }
37112
37374
  continue;
37113
37375
  }
37114
37376
  if (!entry.name.endsWith(".yaml")) continue;
37115
- if (!SAFE_FLOW_NAME.test(path17.basename(entry.name, ".yaml"))) continue;
37116
- if (await isRunnableFlowFile(path17.join(current, entry.name))) found.push(entryRel);
37377
+ if (!SAFE_FLOW_NAME.test(path18.basename(entry.name, ".yaml"))) continue;
37378
+ if (await isRunnableFlowFile(path18.join(current, entry.name))) found.push(entryRel);
37117
37379
  }
37118
37380
  };
37119
37381
  await walk(dir, "");
37120
37382
  return found.sort();
37121
37383
  }
37384
+ var RUN_TOOL_ID = "e2e-execute";
37122
37385
  function buildRunPayload(flowPath, projectRoot, args) {
37123
37386
  const payload = {
37124
37387
  flow_path: flowPath,
@@ -37200,7 +37463,7 @@ function rejectionVerdict(code) {
37200
37463
  case FAILURE_CODES.FLOW_FILE_INVALID:
37201
37464
  case FAILURE_CODES.FLOW_ENTRY_UNRECOGNIZED:
37202
37465
  case FAILURE_CODES.FLOW_E2E_HAS_PREREQUISITE:
37203
- return "not run (invalid flow)";
37466
+ return "not run (invalid e2e test)";
37204
37467
  case FAILURE_CODES.FLOW_DEVICE_RESOLUTION:
37205
37468
  return "not run (no device resolved)";
37206
37469
  case FAILURE_CODES.FILE_INPUT_UPLOAD_FAILED:
@@ -37209,6 +37472,20 @@ function rejectionVerdict(code) {
37209
37472
  return "not run (rejected)";
37210
37473
  }
37211
37474
  }
37475
+ function nestedStepWarnings(steps, into = /* @__PURE__ */ new Set()) {
37476
+ for (const s of steps) {
37477
+ if (!s || typeof s.result !== "object" || s.result === null) continue;
37478
+ const { warning, steps: inner } = s.result;
37479
+ if (typeof warning === "string" && warning !== s.warning) into.add(warning);
37480
+ if (Array.isArray(inner)) nestedStepWarnings(inner, into);
37481
+ }
37482
+ return [...into];
37483
+ }
37484
+ function printWarnings(warnings, json2) {
37485
+ for (const warning of warnings) {
37486
+ console.error(json2 ? JSON.stringify({ event: "warning", warning }) : `warning: ${warning}`);
37487
+ }
37488
+ }
37212
37489
  function isFlowReport(data) {
37213
37490
  const steps = data?.steps;
37214
37491
  return Array.isArray(steps) && steps.every((step) => !!step && typeof step === "object");
@@ -37233,15 +37510,15 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
37233
37510
  try {
37234
37511
  flows = await collectFlowFiles(dir, args.recursive);
37235
37512
  } catch {
37236
- return reject(`Could not read flow directory: ${dir}`);
37513
+ return reject(`Could not read e2e test directory: ${dir}`);
37237
37514
  }
37238
37515
  if (flows.length === 0) {
37239
37516
  return reject(
37240
- `No flows found in ${dir}` + (args.recursive ? "" : "\nPass -r/--recursive to include subdirectories.")
37517
+ `No e2e tests found in ${dir}` + (args.recursive ? "" : "\nPass -r/--recursive to include subdirectories.")
37241
37518
  );
37242
37519
  }
37243
37520
  const { callTool, baseUrl } = runToolsClient(args, options);
37244
- const outputBase = args.output ? path17.resolve(args.output) : void 0;
37521
+ const outputBase = args.output ? path18.resolve(args.output) : void 0;
37245
37522
  const results = [];
37246
37523
  const failures = [];
37247
37524
  const batchStartedAt = Date.now();
@@ -37254,11 +37531,11 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
37254
37531
  if (!args.json) console.log(` ${STATUS_GLYPH.skip} not run (batch stopped)`);
37255
37532
  continue;
37256
37533
  }
37257
- const flowPath = path17.join(dir, rel);
37534
+ const flowPath = path18.join(dir, rel);
37258
37535
  const rerun = rerunCommand(flowPath, rel, projectRoot, args);
37259
37536
  let report;
37260
37537
  try {
37261
- const resp = await callTool("flow-execute", buildRunPayload(flowPath, projectRoot, args));
37538
+ const resp = await callTool(RUN_TOOL_ID, buildRunPayload(flowPath, projectRoot, args));
37262
37539
  if (isFlowReport(resp.data)) report = resp.data;
37263
37540
  } catch (thrown) {
37264
37541
  const unreachableErr = await toolServerUnreachable(thrown);
@@ -37285,9 +37562,10 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
37285
37562
  stopped = true;
37286
37563
  continue;
37287
37564
  }
37565
+ printWarnings(nestedStepWarnings(report.steps), args.json);
37288
37566
  await exportAndResolveArtifacts(
37289
37567
  report,
37290
- outputBase ? path17.join(outputBase, path17.dirname(rel)) : void 0,
37568
+ outputBase ? path18.join(outputBase, path18.dirname(rel)) : void 0,
37291
37569
  flowPath,
37292
37570
  baseUrl
37293
37571
  );
@@ -37325,25 +37603,54 @@ ${renderBatchSummary(counts, durationMs)}`);
37325
37603
  }
37326
37604
  return exitAfterFlush(unreachable ? 2 : counts.failed === 0 ? 0 : 1);
37327
37605
  }
37328
- async function flow(argv, options) {
37606
+ async function e2e(argv, options) {
37329
37607
  const [sub, ...rest] = argv;
37330
37608
  if (!sub || sub === "--help" || sub === "-h") {
37331
37609
  printHelp();
37332
37610
  return;
37333
37611
  }
37334
37612
  if (sub === "list") {
37335
- const dir = path17.join(process.cwd(), FLOWS_DIR);
37336
- try {
37337
- const paths = (await collectRunnableFlowPaths(dir)).sort().map((rel) => path17.join(FLOWS_DIR, rel));
37338
- if (paths.length === 0) console.log("No flows found in .argent/flows");
37339
- else console.log(paths.join("\n"));
37340
- } catch {
37341
- console.log("No .argent/flows directory in the current working directory.");
37613
+ const lines = [];
37614
+ const notes = [];
37615
+ let legacyCount = 0;
37616
+ const byName = /* @__PURE__ */ new Map();
37617
+ let anyDir = false;
37618
+ for (const dir of E2E_DIRS) {
37619
+ let rels;
37620
+ try {
37621
+ rels = (await collectRunnableFlowPaths(path18.join(process.cwd(), dir))).sort();
37622
+ } catch {
37623
+ continue;
37624
+ }
37625
+ anyDir = true;
37626
+ for (const rel of rels) {
37627
+ const shown = path18.join(dir, rel);
37628
+ const name = path18.dirname(rel) === "." ? path18.basename(rel, ".yaml") : void 0;
37629
+ const usedByName = name === void 0 ? void 0 : byName.get(name);
37630
+ if (name !== void 0 && usedByName === void 0) byName.set(name, shown);
37631
+ lines.push(shown);
37632
+ if (dir === E2E_DIR) continue;
37633
+ legacyCount++;
37634
+ if (usedByName)
37635
+ notes.push(`warning: ${shown} is shadowed by ${usedByName} when run by name`);
37636
+ }
37637
+ }
37638
+ if (legacyCount > 0) {
37639
+ notes.push(
37640
+ `note: ${legacyCount} test${legacyCount === 1 ? "" : "s"} listed from .argent/flows (legacy); move ${legacyCount === 1 ? "it" : "them"} to .argent/e2e`
37641
+ );
37642
+ }
37643
+ if (!anyDir) {
37644
+ console.log(`No ${E2E_DIRS.join(" or ")} directory in the current working directory.`);
37645
+ } else if (lines.length === 0) console.log(`No e2e tests found in ${E2E_DIRS.join(" or ")}`);
37646
+ else {
37647
+ console.log(lines.join("\n"));
37648
+ for (const note of notes) console.error(note);
37342
37649
  }
37343
37650
  return;
37344
37651
  }
37345
37652
  if (sub !== "run") {
37346
- console.error(`Unknown flow subcommand "${sub}". Run \`argent flow --help\`.`);
37653
+ console.error(`Unknown e2e subcommand "${sub}". Run \`argent e2e --help\`.`);
37347
37654
  return exitAfterFlush(2);
37348
37655
  }
37349
37656
  const flagGiven = (flag) => rest.some((tok) => tok === flag || tok.startsWith(`${flag}=`));
@@ -37374,7 +37681,7 @@ async function flow(argv, options) {
37374
37681
  throw err;
37375
37682
  }
37376
37683
  if (!args.flowRef) {
37377
- const message = "argent flow run <flow|flow.yaml|dir> requires a flow name, a YAML file path, or a directory path.";
37684
+ const message = "argent e2e run <test|test.yaml|dir> requires an e2e test name, a YAML file path, or a directory path.";
37378
37685
  return usageError(message, message);
37379
37686
  }
37380
37687
  const fail = (message, code, err = message) => {
@@ -37383,109 +37690,112 @@ async function flow(argv, options) {
37383
37690
  return exitAfterFlush(code);
37384
37691
  };
37385
37692
  const projectRoot = process.cwd();
37386
- const { suppliedPath, fromName } = resolveFlowRef(args.flowRef);
37693
+ const { suppliedPath, fromName, shadowed } = await resolveFlowRef(args.flowRef, projectRoot);
37694
+ if (shadowed !== void 0) {
37695
+ printWarnings([e2eShadowWarning(suppliedPath, shadowed)], args.json);
37696
+ }
37387
37697
  if (suppliedPath.split(/[\\/]+/).includes("..")) {
37388
- let recovery = "Pass the fully resolved path to the flow's YAML.";
37389
- const suppliedBase2 = path17.basename(suppliedPath);
37698
+ let recovery = "Pass the fully resolved path to the e2e test's YAML.";
37699
+ const suppliedBase2 = path18.basename(suppliedPath);
37390
37700
  if (suppliedBase2 !== ".." && suppliedBase2 !== ".") {
37391
37701
  try {
37392
- const resolved = path17.join(await fsp.realpath(path17.dirname(suppliedPath)), suppliedBase2);
37702
+ const resolved = path18.join(await fsp.realpath(path18.dirname(suppliedPath)), suppliedBase2);
37393
37703
  await fsp.stat(resolved);
37394
- recovery = `Did you mean: argent flow run ${shellQuoteArg(resolved)}`;
37704
+ recovery = `Did you mean: argent e2e run ${shellQuoteArg(resolved)}`;
37395
37705
  } catch {
37396
37706
  }
37397
37707
  }
37398
37708
  return fail(
37399
- `Flow path must not contain ".." segments \u2014 they are collapsed without following symlinks, so the path can name a different file than the one your shell opens: ${suppliedPath}
37709
+ `E2E test path must not contain ".." segments \u2014 they are collapsed without following symlinks, so the path can name a different file than the one your shell opens: ${suppliedPath}
37400
37710
  ` + recovery,
37401
37711
  2
37402
37712
  );
37403
37713
  }
37404
- const resolvedPath = path17.resolve(projectRoot, suppliedPath);
37714
+ const resolvedPath = path18.resolve(projectRoot, suppliedPath);
37405
37715
  let isDirectory = false;
37406
37716
  try {
37407
37717
  isDirectory = (await fsp.stat(resolvedPath)).isDirectory();
37408
37718
  } catch {
37409
37719
  if (args.recursive && !fromName) {
37410
- return fail(`Flow directory not found: ${resolvedPath}`, 2);
37720
+ return fail(`E2E test directory not found: ${resolvedPath}`, 2);
37411
37721
  }
37412
37722
  }
37413
37723
  if (isDirectory) {
37414
37724
  if (args.jsonStream) {
37415
- return fail("--json-stream supports a single flow; directory runs are not supported.", 2);
37725
+ return fail("--json-stream supports a single e2e test; directory runs are not supported.", 2);
37416
37726
  }
37417
37727
  return runFlowDirectory(resolvedPath, args, projectRoot, options);
37418
37728
  }
37419
37729
  if (args.recursive) {
37420
37730
  return fail(
37421
- fromName ? `flow run --recursive requires a directory path; "${args.flowRef}" is a saved-flow name, which always addresses the single file ${suppliedPath}.` : `flow run --recursive requires a directory path: ${suppliedPath}`,
37731
+ fromName ? `e2e run --recursive requires a directory path; "${args.flowRef}" is a saved test's name, which always addresses the single file ${suppliedPath}.` : `e2e run --recursive requires a directory path: ${suppliedPath}`,
37422
37732
  2
37423
37733
  );
37424
37734
  }
37425
37735
  const separatorTrimmedPath = suppliedPath.replace(/[\\/]+$/, "");
37426
37736
  if (separatorTrimmedPath !== suppliedPath && separatorTrimmedPath !== "") {
37427
- const hint = SAFE_FLOW_NAME.test(separatorTrimmedPath) ? `.${path17.sep}${separatorTrimmedPath}` : separatorTrimmedPath;
37737
+ const hint = SAFE_FLOW_NAME.test(separatorTrimmedPath) ? `.${path18.sep}${separatorTrimmedPath}` : separatorTrimmedPath;
37428
37738
  return fail(
37429
- `Flow path must not end in a path separator \u2014 the separator claims a directory, which the kernel would refuse to open as a file, so the CLI would run a file this string does not name: ${suppliedPath}
37430
- Did you mean: argent flow run ${shellQuoteArg(hint)}`,
37739
+ `E2E test path must not end in a path separator \u2014 the separator claims a directory, which the kernel would refuse to open as a file, so the CLI would run a file this string does not name: ${suppliedPath}
37740
+ Did you mean: argent e2e run ${shellQuoteArg(hint)}`,
37431
37741
  2
37432
37742
  );
37433
37743
  }
37434
- if (path17.extname(suppliedPath) !== ".yaml") {
37435
- const looksLikeName = !suppliedPath.includes("/") && !suppliedPath.includes("\\") && path17.extname(suppliedPath) === "";
37436
- if (path17.basename(suppliedPath).toLowerCase() === ".yaml") {
37744
+ if (path18.extname(suppliedPath) !== ".yaml") {
37745
+ const looksLikeName = !suppliedPath.includes("/") && !suppliedPath.includes("\\") && path18.extname(suppliedPath) === "";
37746
+ if (path18.basename(suppliedPath).toLowerCase() === ".yaml") {
37437
37747
  return fail(
37438
- `Flow filename must have a non-empty name containing only letters, numbers, "_", or "-": ${suppliedPath}`,
37748
+ `E2E test filename must have a non-empty name containing only letters, numbers, "_", or "-": ${suppliedPath}`,
37439
37749
  2
37440
37750
  );
37441
37751
  }
37442
37752
  if (looksLikeName) {
37443
37753
  return fail(
37444
- `Flow name must contain only letters, numbers, "_", or "-": ${suppliedPath}
37445
- Names run \`${FLOWS_DIR}/<name>.yaml\`; pass a path ending in .yaml to run a flow file kept elsewhere.`,
37754
+ `E2E test name must contain only letters, numbers, "_", or "-": ${suppliedPath}
37755
+ Names run \`${E2E_DIRS.map((dir) => `${dir}/<name>.yaml`).join("` or `")}\`; pass a path ending in .yaml to run an e2e test file kept elsewhere.`,
37446
37756
  2
37447
37757
  );
37448
37758
  }
37449
- if (path17.extname(suppliedPath).toLowerCase() === ".yaml") {
37759
+ if (path18.extname(suppliedPath).toLowerCase() === ".yaml") {
37450
37760
  return fail(
37451
- `Flow extension must be lowercase .yaml, not ${path17.extname(suppliedPath)}: ${suppliedPath}`,
37761
+ `E2E test extension must be lowercase .yaml, not ${path18.extname(suppliedPath)}: ${suppliedPath}`,
37452
37762
  2
37453
37763
  );
37454
37764
  }
37455
- return fail(`Flow path must end in .yaml: ${suppliedPath}`, 2);
37765
+ return fail(`E2E test path must end in .yaml: ${suppliedPath}`, 2);
37456
37766
  }
37457
- const flowName = path17.basename(suppliedPath, ".yaml");
37767
+ const flowName = path18.basename(suppliedPath, ".yaml");
37458
37768
  if (!SAFE_FLOW_NAME.test(flowName)) {
37459
37769
  return fail(
37460
- `Flow filename must have a non-empty name containing only letters, numbers, "_", or "-": ${suppliedPath}`,
37770
+ `E2E test filename must have a non-empty name containing only letters, numbers, "_", or "-": ${suppliedPath}`,
37461
37771
  2
37462
37772
  );
37463
37773
  }
37464
37774
  const flowPath = resolvedPath;
37465
37775
  try {
37466
- const stat6 = await fsp.stat(flowPath);
37467
- if (!stat6.isFile()) {
37468
- return fail(`Flow path is not a file: ${flowPath}`, 2);
37776
+ const stat7 = await fsp.stat(flowPath);
37777
+ if (!stat7.isFile()) {
37778
+ return fail(`E2E test path is not a file: ${flowPath}`, 2);
37469
37779
  }
37470
37780
  await fsp.access(flowPath, fsConstants2.R_OK);
37471
37781
  } catch (err) {
37472
37782
  const code = err.code;
37473
- const detail = code === "ENOENT" ? "Flow file not found" : "Could not read flow file";
37783
+ const detail = code === "ENOENT" ? "E2E test file not found" : "Could not read e2e test file";
37474
37784
  let recovery = "";
37475
37785
  if (code === "ENOENT") {
37476
37786
  recovery = fromName ? `
37477
- No flow named "${args.flowRef}" is saved there \u2014 run \`argent flow list\` to see the saved flows.` : await savedFlowHint(projectRoot, flowPath);
37787
+ No e2e test named "${args.flowRef}" is saved in ${E2E_DIRS.join(" or ")} \u2014 run \`argent e2e list\` to see the saved tests.` : await savedFlowHint(projectRoot, flowPath);
37478
37788
  }
37479
37789
  return fail(`${detail}: ${flowPath}${recovery}`, 2);
37480
37790
  }
37481
- const suppliedBase = path17.basename(flowPath);
37482
- const siblings = await fsp.readdir(path17.dirname(flowPath)).catch(() => null);
37791
+ const suppliedBase = path18.basename(flowPath);
37792
+ const siblings = await fsp.readdir(path18.dirname(flowPath)).catch(() => null);
37483
37793
  if (siblings !== null && !siblings.includes(suppliedBase)) {
37484
37794
  const actual = siblings.find((name) => name.toLowerCase() === suppliedBase.toLowerCase());
37485
- const actualRunnable = actual !== void 0 && path17.extname(actual) === ".yaml" && SAFE_FLOW_NAME.test(path17.basename(actual, ".yaml"));
37486
- const recovery = actualRunnable ? fromName ? `Did you mean: argent flow run ${path17.basename(actual, ".yaml")}` : `Did you mean: argent flow run ${shellQuoteArg(path17.join(path17.dirname(suppliedPath), actual))}` : actual !== void 0 ? `Rename ${actual} to ${suppliedBase} to run it \u2014 flow files must be lowercase .yaml.` : "Pass the flow file's name exactly as it appears on disk.";
37795
+ const actualRunnable = actual !== void 0 && path18.extname(actual) === ".yaml" && SAFE_FLOW_NAME.test(path18.basename(actual, ".yaml"));
37796
+ const recovery = actualRunnable ? fromName ? `Did you mean: argent e2e run ${path18.basename(actual, ".yaml")}` : `Did you mean: argent e2e run ${shellQuoteArg(path18.join(path18.dirname(suppliedPath), actual))}` : actual !== void 0 ? `Rename ${actual} to ${suppliedBase} to run it \u2014 e2e test files must be lowercase .yaml.` : "Pass the e2e test file's name exactly as it appears on disk.";
37487
37797
  return fail(
37488
- `Flow path must name the file as it appears on disk \u2014 this filesystem matched ${JSON.stringify(suppliedBase)} case-insensitively${actual !== void 0 ? ` to ${JSON.stringify(actual)}` : ""}, so the flow name (which keys the report, __baselines__/, and --output) would be one no file carries: ${suppliedPath}
37798
+ `E2E test path must name the file as it appears on disk \u2014 this filesystem matched ${JSON.stringify(suppliedBase)} case-insensitively${actual !== void 0 ? ` to ${JSON.stringify(actual)}` : ""}, so the test name (which keys the report, __baselines__/, and --output) would be one no file carries: ${suppliedPath}
37489
37799
  ${recovery}`,
37490
37800
  2
37491
37801
  );
@@ -37500,7 +37810,7 @@ ${recovery}`,
37500
37810
  writeJsonStreamRecord({ event: "progress", data: s });
37501
37811
  return;
37502
37812
  }
37503
- if (liveSteps === 0) console.log(`Flow "${flowName}"`);
37813
+ if (liveSteps === 0) console.log(`E2E test "${flowName}"`);
37504
37814
  liveSteps++;
37505
37815
  if (s.kind === "echo") {
37506
37816
  const line = renderEchoLine(s);
@@ -37515,7 +37825,7 @@ ${recovery}`,
37515
37825
  let report;
37516
37826
  try {
37517
37827
  const resp = await callTool(
37518
- "flow-execute",
37828
+ RUN_TOOL_ID,
37519
37829
  payload,
37520
37830
  args.json ? void 0 : { onProgress: onStepReport }
37521
37831
  );
@@ -37523,7 +37833,7 @@ ${recovery}`,
37523
37833
  } catch (err) {
37524
37834
  const unreachableErr = await toolServerUnreachable(err);
37525
37835
  if (!args.json && !args.jsonStream) {
37526
- if (liveSteps === 0) console.log(`Flow "${flowName}"`);
37836
+ if (liveSteps === 0) console.log(`E2E test "${flowName}"`);
37527
37837
  console.log(
37528
37838
  ` ${STATUS_GLYPH.error} ` + (unreachableErr ? UNREACHABLE_VERDICT : err instanceof ToolInvocationError && err.errorKind === "validation" ? rejectionVerdict(err.errorCode) : "did not finish (run error)")
37529
37839
  );
@@ -37533,15 +37843,16 @@ ${recovery}`,
37533
37843
  }
37534
37844
  if (!isFlowReport(report)) {
37535
37845
  if (!args.json && !args.jsonStream) {
37536
- if (liveSteps === 0) console.log(`Flow "${flowName}"`);
37846
+ if (liveSteps === 0) console.log(`E2E test "${flowName}"`);
37537
37847
  console.log(` ${STATUS_GLYPH.error} did not finish (no run report)`);
37538
37848
  }
37539
37849
  return fail(`"${flowName}" did not produce a run report.`, 2);
37540
37850
  }
37851
+ printWarnings(nestedStepWarnings(report.steps), args.json);
37541
37852
  try {
37542
37853
  await exportAndResolveArtifacts(
37543
37854
  report,
37544
- args.output ? path17.resolve(args.output) : void 0,
37855
+ args.output ? path18.resolve(args.output) : void 0,
37545
37856
  flowPath,
37546
37857
  baseUrl
37547
37858
  );
@@ -37580,7 +37891,7 @@ function summarize(description, max = 80) {
37580
37891
  async function tools(argv, options) {
37581
37892
  const { fetchTool, fetchTools } = createToolsClient({ paths: options.paths });
37582
37893
  async function listTools(json3) {
37583
- const list = await fetchTools();
37894
+ const list = (await fetchTools()).filter((tool) => tool.aliasOf === void 0);
37584
37895
  if (json3) {
37585
37896
  console.log(JSON.stringify(list, null, 2));
37586
37897
  return;
@@ -37655,12 +37966,12 @@ Listing tools contacts the argent tool-server, starting one if none is running.
37655
37966
  }
37656
37967
 
37657
37968
  // ../argent-cli/src/server.ts
37658
- import * as fs12 from "node:fs";
37659
- import * as path18 from "node:path";
37969
+ import * as fs13 from "node:fs";
37970
+ import * as path19 from "node:path";
37660
37971
  import { homedir as homedir5, networkInterfaces } from "node:os";
37661
37972
  import { spawn as spawn3 } from "node:child_process";
37662
- var STATE_DIR2 = path18.join(homedir5(), ".argent");
37663
- var LOG_FILE2 = path18.join(STATE_DIR2, "tool-server.log");
37973
+ var STATE_DIR2 = path19.join(homedir5(), ".argent");
37974
+ var LOG_FILE2 = path19.join(STATE_DIR2, "tool-server.log");
37664
37975
  async function describeForeignServers(ownBundlePath) {
37665
37976
  const others = (await readAllToolsServerStates()).filter(
37666
37977
  ({ state: state2 }) => state2.bundlePath !== ownBundlePath && isToolsServerProcessAlive(state2.pid)
@@ -37724,12 +38035,12 @@ Stop one with: kill <pid>`);
37724
38035
  }
37725
38036
  }
37726
38037
  function logsCmd(follow) {
37727
- if (!fs12.existsSync(LOG_FILE2)) {
38038
+ if (!fs13.existsSync(LOG_FILE2)) {
37728
38039
  console.log(`No log file at ${LOG_FILE2}`);
37729
38040
  return;
37730
38041
  }
37731
38042
  if (!follow) {
37732
- process.stdout.write(fs12.readFileSync(LOG_FILE2, "utf8"));
38043
+ process.stdout.write(fs13.readFileSync(LOG_FILE2, "utf8"));
37733
38044
  return;
37734
38045
  }
37735
38046
  const child = spawn3("tail", ["-f", LOG_FILE2], { stdio: "inherit" });
@@ -38011,22 +38322,31 @@ function signalNumber(signal) {
38011
38322
  const map2 = { SIGINT: 2, SIGTERM: 15, SIGHUP: 1, SIGKILL: 9 };
38012
38323
  return map2[signal] ?? null;
38013
38324
  }
38014
- async function server(argv, options) {
38015
- const sub = argv[0];
38016
- const json2 = argv.includes("--json");
38017
- const follow = argv.includes("-f") || argv.includes("--follow");
38018
- if (!sub || sub === "--help" || sub === "-h") {
38019
- console.log(`Usage:
38325
+ function printServerHelp() {
38326
+ console.log(`Usage:
38020
38327
  argent server start [flags] Spawn a long-lived tool-server (see --help)
38021
38328
  argent server status [--json] Show tool-server pid, port, and health
38022
38329
  argent server stop Terminate the running tool-server
38023
38330
  argent server logs [-f] Print (or follow) the tool-server log
38024
38331
  `);
38332
+ }
38333
+ async function server(argv, options) {
38334
+ const sub = argv[0];
38335
+ const json2 = argv.includes("--json");
38336
+ const follow = argv.includes("-f") || argv.includes("--follow");
38337
+ if (!sub || sub === "--help" || sub === "-h") {
38338
+ printServerHelp();
38339
+ return;
38340
+ }
38341
+ const rest = argv.slice(1);
38342
+ const actsOnServer = sub === "status" || sub === "stop" || sub === "logs";
38343
+ if (actsOnServer && (rest.includes("--help") || rest.includes("-h"))) {
38344
+ printServerHelp();
38025
38345
  return;
38026
38346
  }
38027
38347
  switch (sub) {
38028
38348
  case "start":
38029
- await startCmd(argv.slice(1), options?.paths);
38349
+ await startCmd(rest, options?.paths);
38030
38350
  return;
38031
38351
  case "status":
38032
38352
  await statusCmd(json2, options?.paths);
@@ -38044,9 +38364,9 @@ async function server(argv, options) {
38044
38364
  }
38045
38365
 
38046
38366
  // ../argent-cli/src/lens.ts
38047
- import * as fs13 from "node:fs";
38367
+ import * as fs14 from "node:fs";
38048
38368
  import * as os2 from "node:os";
38049
- import * as path19 from "node:path";
38369
+ import * as path20 from "node:path";
38050
38370
 
38051
38371
  // ../argent-cli/src/lens-terminal.ts
38052
38372
  import { execFileSync as execFileSync3 } from "node:child_process";
@@ -38264,15 +38584,15 @@ function isSessionAlive(session) {
38264
38584
  // ../argent-cli/src/lens-pty.ts
38265
38585
  import { chmodSync as chmodSync2, readdirSync as readdirSync2 } from "node:fs";
38266
38586
  import { createRequire } from "node:module";
38267
- import { dirname as dirname11, join as join17 } from "node:path";
38587
+ import { dirname as dirname12, join as join19 } from "node:path";
38268
38588
  var nodeRequire = createRequire(import.meta.url);
38269
38589
  function ensureSpawnHelperExecutable(req = nodeRequire) {
38270
38590
  if (process.platform !== "darwin") return;
38271
38591
  try {
38272
- const prebuilds = join17(dirname11(req.resolve("node-pty/package.json")), "prebuilds");
38592
+ const prebuilds = join19(dirname12(req.resolve("node-pty/package.json")), "prebuilds");
38273
38593
  for (const entry of readdirSync2(prebuilds)) {
38274
38594
  try {
38275
- chmodSync2(join17(prebuilds, entry, "spawn-helper"), 493);
38595
+ chmodSync2(join19(prebuilds, entry, "spawn-helper"), 493);
38276
38596
  } catch {
38277
38597
  }
38278
38598
  }
@@ -38304,7 +38624,7 @@ function ptyInjectBeats(text2) {
38304
38624
  ];
38305
38625
  }
38306
38626
  function sleep(ms) {
38307
- return new Promise((resolve12) => setTimeout(resolve12, ms));
38627
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
38308
38628
  }
38309
38629
  var DEFAULT_COLS = 80;
38310
38630
  var DEFAULT_ROWS = 24;
@@ -38525,7 +38845,7 @@ var SPAWN_GRACE_MS = 8e3;
38525
38845
  var DEATH_CONFIRMATIONS = 3;
38526
38846
  var SSE_RECONNECT_MS = 1e3;
38527
38847
  function sleep2(ms) {
38528
- return new Promise((resolve12) => setTimeout(resolve12, ms));
38848
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
38529
38849
  }
38530
38850
  var TRUST_PROMPT_RE = /trust this folder|do you trust|yes,? i trust|trust the files in this/i;
38531
38851
  async function dismissTrustPrompt(session) {
@@ -38797,12 +39117,12 @@ async function lens(argv, options) {
38797
39117
  await endSession(baseUrl);
38798
39118
  process.exit(1);
38799
39119
  }
38800
- const seedFile = path19.join(os2.tmpdir(), `argent-lens-seed-${process.pid}-${Date.now()}.txt`);
38801
- fs13.writeFileSync(seedFile, buildSeedPrompt(), "utf8");
39120
+ const seedFile = path20.join(os2.tmpdir(), `argent-lens-seed-${process.pid}-${Date.now()}.txt`);
39121
+ fs14.writeFileSync(seedFile, buildSeedPrompt(), "utf8");
38802
39122
  const launchCmd = agent.launch(shellQuote(process.cwd()), shellQuote(seedFile));
38803
39123
  const removeSeedFile = () => {
38804
39124
  try {
38805
- fs13.rmSync(seedFile, { force: true });
39125
+ fs14.rmSync(seedFile, { force: true });
38806
39126
  } catch {
38807
39127
  }
38808
39128
  };
@@ -39161,7 +39481,7 @@ Options:
39161
39481
 
39162
39482
  // ../argent-cli/src/config.ts
39163
39483
  var import_picocolors2 = __toESM(require_picocolors(), 1);
39164
- import * as path20 from "node:path";
39484
+ import * as path21 from "node:path";
39165
39485
  function config2(argv) {
39166
39486
  if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
39167
39487
  printUsage();
@@ -39332,16 +39652,16 @@ function wantsHelp(argv) {
39332
39652
  }
39333
39653
  function scopeLabel(scope) {
39334
39654
  if (scope === "global") return "global";
39335
- return `project: ${path20.dirname(configDir("project"))}`;
39655
+ return `project: ${path21.dirname(configDir("project"))}`;
39336
39656
  }
39337
39657
  function degenerateProjectScopeWarning(scope) {
39338
39658
  if (scope !== "project") return null;
39339
39659
  const projDir = configDir("project");
39340
- if (path20.resolve(projDir) === path20.resolve(configDir("global"))) {
39341
- return `WARNING: no project found between ${process.cwd()} and your home directory \u2014 "project" scope resolved to the home directory, so this writes the GLOBAL config file (${path20.join(projDir, "config.json")}).`;
39660
+ if (path21.resolve(projDir) === path21.resolve(configDir("global"))) {
39661
+ return `WARNING: no project found between ${process.cwd()} and your home directory \u2014 "project" scope resolved to the home directory, so this writes the GLOBAL config file (${path21.join(projDir, "config.json")}).`;
39342
39662
  }
39343
39663
  if (findProjectRoot(process.cwd()) === null) {
39344
- return `WARNING: no project markers (.argent, .git, package.json) found above ${process.cwd()} \u2014 treating it as the project root and creating ${path20.join(projDir, "config.json")}.`;
39664
+ return `WARNING: no project markers (.argent, .git, package.json) found above ${process.cwd()} \u2014 treating it as the project root and creating ${path21.join(projDir, "config.json")}.`;
39345
39665
  }
39346
39666
  return null;
39347
39667
  }
@@ -40258,7 +40578,7 @@ import { styleText as styleText2, stripVTControlCharacters } from "node:util";
40258
40578
  import process$1 from "node:process";
40259
40579
  var import_sisteransi2 = __toESM(require_src(), 1);
40260
40580
  import { existsSync as existsSync7, lstatSync as lstatSync3, readdirSync as readdirSync3 } from "node:fs";
40261
- import { dirname as dirname13, join as join20 } from "node:path";
40581
+ import { dirname as dirname14, join as join22 } from "node:path";
40262
40582
  function isUnicodeSupported() {
40263
40583
  if (process$1.platform !== "win32") {
40264
40584
  return process$1.env.TERM !== "linux";
@@ -41260,8 +41580,8 @@ async function cmdDisable(scope) {
41260
41580
 
41261
41581
  // ../argent-cli/src/providers.ts
41262
41582
  var import_picocolors7 = __toESM(require_picocolors(), 1);
41263
- import * as fs17 from "node:fs";
41264
- import * as path23 from "node:path";
41583
+ import * as fs18 from "node:fs";
41584
+ import * as path24 from "node:path";
41265
41585
 
41266
41586
  // ../device-providers/src/contract.ts
41267
41587
  var PROVIDER_SCHEMA_VERSION = 1;
@@ -41406,9 +41726,9 @@ var providerEnvelopeSchema = providerRecordSchema.extend({
41406
41726
  });
41407
41727
 
41408
41728
  // ../device-providers/src/read.ts
41409
- import * as fs14 from "node:fs";
41729
+ import * as fs15 from "node:fs";
41410
41730
  import * as os3 from "node:os";
41411
- import * as path21 from "node:path";
41731
+ import * as path22 from "node:path";
41412
41732
  var DISABLE_ENV = "ARGENT_DISABLE_DEVICE_PROVIDERS";
41413
41733
  var OVERRIDE_ENV = "ARGENT_DEVICE_PROVIDERS";
41414
41734
  function resolveHomeDir2() {
@@ -41417,7 +41737,7 @@ function resolveHomeDir2() {
41417
41737
  return trimmed ? raw : os3.homedir();
41418
41738
  }
41419
41739
  function providersDirectory() {
41420
- return path21.join(resolveHomeDir2(), ".argent", "providers");
41740
+ return path22.join(resolveHomeDir2(), ".argent", "providers");
41421
41741
  }
41422
41742
  function discoveryDisabled() {
41423
41743
  const raw = process.env[DISABLE_ENV];
@@ -41433,7 +41753,7 @@ function warnOnce(key, message) {
41433
41753
  function readProviderFile(file2) {
41434
41754
  let raw;
41435
41755
  try {
41436
- raw = fs14.readFileSync(file2, "utf8");
41756
+ raw = fs15.readFileSync(file2, "utf8");
41437
41757
  } catch {
41438
41758
  return void 0;
41439
41759
  }
@@ -41483,15 +41803,15 @@ function discoverProviders() {
41483
41803
  function descriptorFiles() {
41484
41804
  const directory = providersDirectory();
41485
41805
  try {
41486
- return fs14.readdirSync(directory).filter((name) => name.endsWith(".json")).sort().map((name) => path21.join(directory, name));
41806
+ return fs15.readdirSync(directory).filter((name) => name.endsWith(".json")).sort().map((name) => path22.join(directory, name));
41487
41807
  } catch {
41488
41808
  return [];
41489
41809
  }
41490
41810
  }
41491
41811
 
41492
41812
  // ../device-providers/src/write.ts
41493
- import * as fs15 from "node:fs";
41494
- import * as path22 from "node:path";
41813
+ import * as fs16 from "node:fs";
41814
+ import * as path23 from "node:path";
41495
41815
  var ProviderValidationError = class extends Error {
41496
41816
  /** One line per problem, `path: message`, in the order zod reported them. */
41497
41817
  issues;
@@ -41543,20 +41863,20 @@ function publishProvider(record2, options = {}) {
41543
41863
  );
41544
41864
  }
41545
41865
  const directory = providersDirectory();
41546
- const file2 = path22.join(directory, `${validated.id}.json`);
41866
+ const file2 = path23.join(directory, `${validated.id}.json`);
41547
41867
  const body = JSON.stringify(canonicalize(candidate), null, 2) + "\n";
41548
41868
  try {
41549
- if (fs15.readFileSync(file2, "utf8") === body) return { changed: false, path: file2 };
41869
+ if (fs16.readFileSync(file2, "utf8") === body) return { changed: false, path: file2 };
41550
41870
  } catch {
41551
41871
  }
41552
- fs15.mkdirSync(directory, { recursive: true });
41872
+ fs16.mkdirSync(directory, { recursive: true });
41553
41873
  const temporary = `${file2}.${process.pid}.tmp`;
41554
41874
  try {
41555
- fs15.writeFileSync(temporary, body);
41556
- fs15.renameSync(temporary, file2);
41875
+ fs16.writeFileSync(temporary, body);
41876
+ fs16.renameSync(temporary, file2);
41557
41877
  } catch (error63) {
41558
41878
  try {
41559
- fs15.rmSync(temporary, { force: true });
41879
+ fs16.rmSync(temporary, { force: true });
41560
41880
  } catch {
41561
41881
  }
41562
41882
  throw error63;
@@ -41567,9 +41887,9 @@ function withdrawProvider(id) {
41567
41887
  if (!PROVIDER_ID_SHAPE.test(id)) {
41568
41888
  throw new Error(`'${id}' is not a valid provider id (${String(PROVIDER_ID_SHAPE)}).`);
41569
41889
  }
41570
- const file2 = path22.join(providersDirectory(), `${id}.json`);
41890
+ const file2 = path23.join(providersDirectory(), `${id}.json`);
41571
41891
  try {
41572
- fs15.unlinkSync(file2);
41892
+ fs16.unlinkSync(file2);
41573
41893
  return true;
41574
41894
  } catch (e) {
41575
41895
  if (e.code === "ENOENT") return false;
@@ -41599,7 +41919,7 @@ function pruneOrphanedProviders(options = {}) {
41599
41919
  continue;
41600
41920
  }
41601
41921
  try {
41602
- fs15.unlinkSync(file2);
41922
+ fs16.unlinkSync(file2);
41603
41923
  removed.push(entry);
41604
41924
  } catch {
41605
41925
  }
@@ -41609,7 +41929,7 @@ function pruneOrphanedProviders(options = {}) {
41609
41929
 
41610
41930
  // ../argent-cli/src/providers-check.ts
41611
41931
  var import_picocolors6 = __toESM(require_picocolors(), 1);
41612
- import * as fs16 from "node:fs";
41932
+ import * as fs17 from "node:fs";
41613
41933
  var KNOWN_CAPABILITIES = new Set(EXTERNAL_CAPABILITIES);
41614
41934
  var PROBE_TIMEOUT_MS = 5e3;
41615
41935
  function error62(message) {
@@ -41675,7 +41995,7 @@ async function checkDevices(devices, findings) {
41675
41995
  );
41676
41996
  } else {
41677
41997
  try {
41678
- fs16.accessSync(device.deviceSet, fs16.constants.R_OK);
41998
+ fs17.accessSync(device.deviceSet, fs17.constants.R_OK);
41679
41999
  } catch {
41680
42000
  findings.push(
41681
42001
  error62(`${label}: deviceSet '${device.deviceSet}' is not readable by this user`)
@@ -41732,7 +42052,7 @@ async function checkDevices(devices, findings) {
41732
42052
  );
41733
42053
  } else {
41734
42054
  try {
41735
- fs16.accessSync(device.nativeDevtools.socketPath, fs16.constants.R_OK | fs16.constants.W_OK);
42055
+ fs17.accessSync(device.nativeDevtools.socketPath, fs17.constants.R_OK | fs17.constants.W_OK);
41736
42056
  } catch {
41737
42057
  findings.push(
41738
42058
  error62(
@@ -41803,7 +42123,7 @@ async function checkDescriptorFile(file2, expectedVersion) {
41803
42123
  const report = { deviceCount: 0, findings, source: file2 };
41804
42124
  let raw;
41805
42125
  try {
41806
- raw = fs16.readFileSync(file2, "utf8");
42126
+ raw = fs17.readFileSync(file2, "utf8");
41807
42127
  } catch (e) {
41808
42128
  findings.push(error62(`unreadable: ${e instanceof Error ? e.message : String(e)}`));
41809
42129
  return report;
@@ -41939,7 +42259,7 @@ async function readDocument(args) {
41939
42259
  }
41940
42260
  if (args.file) {
41941
42261
  try {
41942
- return { raw: fs17.readFileSync(args.file, "utf8"), source: args.file };
42262
+ return { raw: fs18.readFileSync(args.file, "utf8"), source: args.file };
41943
42263
  } catch (e) {
41944
42264
  throw new UsageError2(
41945
42265
  `cannot read ${args.file}: ${e instanceof Error ? e.message : String(e)}`
@@ -42072,7 +42392,7 @@ function runWithdraw(args) {
42072
42392
  throw new UsageError2(`'${id}' is not a valid provider id (${String(PROVIDER_ID_SHAPE)})`);
42073
42393
  }
42074
42394
  const removed = withdrawProvider(id);
42075
- const file2 = path23.join(providersDirectory(), `${id}.json`);
42395
+ const file2 = path24.join(providersDirectory(), `${id}.json`);
42076
42396
  if (args.json) {
42077
42397
  console.log(JSON.stringify({ ok: true, path: file2, removed }, null, 2));
42078
42398
  return;
@@ -42280,9 +42600,10 @@ export {
42280
42600
  FLAG_REGISTRY,
42281
42601
  config2 as config,
42282
42602
  disable,
42603
+ e2e,
42283
42604
  enable,
42284
42605
  flags,
42285
- flow,
42606
+ e2e as flow,
42286
42607
  getFlagDefinition,
42287
42608
  isFlagEnabled,
42288
42609
  lens,