@swmansion/argent 0.31.2-next.2 → 0.31.2-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1323,7 +1323,31 @@ var init_e2e_dirs = __esm({
1323
1323
  function canonicalToolId(id) {
1324
1324
  return Object.hasOwn(TOOL_ID_ALIASES, id) ? TOOL_ID_ALIASES[id] : id;
1325
1325
  }
1326
- var TOOL_ID_ALIASES;
1326
+ function toolParamAliases(tool) {
1327
+ const id = canonicalToolId(tool);
1328
+ return Object.hasOwn(TOOL_PARAM_ALIASES, id) ? TOOL_PARAM_ALIASES[id] : {};
1329
+ }
1330
+ function canonicalToolArgs(tool, args) {
1331
+ if (typeof args !== "object" || args === null || Array.isArray(args)) return args;
1332
+ const record2 = args;
1333
+ let out;
1334
+ for (const [former, current] of Object.entries(toolParamAliases(tool))) {
1335
+ if (record2[former] === void 0) continue;
1336
+ if (record2[current] !== void 0) throw new ToolParamAliasError(former, current);
1337
+ out ??= { ...record2 };
1338
+ out[current] = out[former];
1339
+ delete out[former];
1340
+ }
1341
+ return out ?? args;
1342
+ }
1343
+ function withFormerParamSpecs(tool, specs) {
1344
+ const former = Object.entries(toolParamAliases(tool));
1345
+ const copies = specs.flatMap(
1346
+ (spec) => spec.path === `\${${spec.target}}` ? former.filter(([, current]) => current === spec.target).map(([name]) => ({ ...spec, target: name, path: `\${${name}}` })) : []
1347
+ );
1348
+ return copies.length > 0 ? [...specs, ...copies] : specs;
1349
+ }
1350
+ var TOOL_ID_ALIASES, TOOL_PARAM_ALIASES, ToolParamAliasError;
1327
1351
  var init_tool_ids = __esm({
1328
1352
  "../registry/src/tool-ids.ts"() {
1329
1353
  "use strict";
@@ -1336,6 +1360,19 @@ var init_tool_ids = __esm({
1336
1360
  "flow-read-prerequisite": "e2e-read-prerequisite",
1337
1361
  "flow-execute": "e2e-execute"
1338
1362
  });
1363
+ TOOL_PARAM_ALIASES = Object.freeze({
1364
+ "e2e-execute": Object.freeze({ flow_path: "e2e_test_path", flow_file: "e2e_test_file" }),
1365
+ "e2e-read-prerequisite": Object.freeze({
1366
+ flow_path: "e2e_test_path",
1367
+ flow_file: "e2e_test_file"
1368
+ })
1369
+ });
1370
+ ToolParamAliasError = class extends Error {
1371
+ constructor(former, current) {
1372
+ super(`Pass ${current} or its former name ${former}, not both.`);
1373
+ this.name = "ToolParamAliasError";
1374
+ }
1375
+ };
1339
1376
  }
1340
1377
  });
1341
1378
 
@@ -1382,7 +1419,13 @@ async function resolveFlowRelativeFile(anchorDir, target, addressable) {
1382
1419
  }
1383
1420
  function nestedFlowTarget(args) {
1384
1421
  if (typeof args !== "object" || args === null || Array.isArray(args)) return void 0;
1385
- const { name, project_root: projectRoot, flow_path: flowPath } = args;
1422
+ let canonical;
1423
+ try {
1424
+ canonical = canonicalToolArgs("e2e-execute", args);
1425
+ } catch {
1426
+ return void 0;
1427
+ }
1428
+ const { name, project_root: projectRoot, e2e_test_path: flowPath } = canonical;
1386
1429
  if (flowPath === void 0) {
1387
1430
  if (typeof name !== "string" || !FLOW_NAME_PATTERN.test(name)) return void 0;
1388
1431
  if (!isResolvedAbsolute(projectRoot)) return void 0;
@@ -1391,7 +1434,7 @@ function nestedFlowTarget(args) {
1391
1434
  }
1392
1435
  if (name !== void 0 || !isResolvedAbsolute(flowPath)) return void 0;
1393
1436
  if (!FLOW_FILE_NAME_PATTERN.test(path6.basename(flowPath))) return void 0;
1394
- return { kind: "flow_path", path: flowPath };
1437
+ return { kind: "e2e_test_path", path: flowPath };
1395
1438
  }
1396
1439
  function isResolvedAbsolute(value) {
1397
1440
  return typeof value === "string" && path6.isAbsolute(value) && !value.split(/[\\/]+/).includes("..");
@@ -22444,6 +22487,7 @@ var init_registry = __esm({
22444
22487
  init_artifacts();
22445
22488
  init_errors();
22446
22489
  init_failure_codes();
22490
+ init_tool_ids();
22447
22491
  init_urn();
22448
22492
  init_zod_to_json_schema();
22449
22493
  import_node_crypto2 = require("node:crypto");
@@ -22524,6 +22568,18 @@ var init_registry = __esm({
22524
22568
  );
22525
22569
  this.events.emit("toolInvoked", toolId, toolInvocationId, startedMsg, calledAs);
22526
22570
  try {
22571
+ try {
22572
+ params = canonicalToolArgs(toolId, params);
22573
+ } catch (err) {
22574
+ if (!(err instanceof ToolParamAliasError)) throw err;
22575
+ throw new FailureError(`Invalid params for tool "${toolId}": ${err.message}`, {
22576
+ error_code: FAILURE_CODES.TOOL_INPUT_INVALID,
22577
+ failure_stage: "tool_params_parse",
22578
+ failure_area: "registry",
22579
+ error_kind: "validation"
22580
+ });
22581
+ }
22582
+ effectiveParams = params;
22527
22583
  if (definition.zodSchema) {
22528
22584
  const parsed = definition.zodSchema.safeParse(params ?? {});
22529
22585
  if (!parsed.success) {
@@ -101024,7 +101080,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
101024
101080
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
101025
101081
  function readCliVersion() {
101026
101082
  if (true) {
101027
- return "0.31.2-next.2";
101083
+ return "0.31.2-next.3";
101028
101084
  }
101029
101085
  return "0.0.0";
101030
101086
  }
@@ -131011,7 +131067,9 @@ function createHttpApp(registry2, options) {
131011
131067
  )
131012
131068
  };
131013
131069
  if (def.outputHint) entry.outputHint = renderFlagGated(def.outputHint, isFlagEnabled);
131014
- if (def.fileInputs && def.fileInputs.length > 0) entry.fileInputs = def.fileInputs;
131070
+ if (def.fileInputs && def.fileInputs.length > 0) {
131071
+ entry.fileInputs = withFormerParamSpecs(def.id, def.fileInputs);
131072
+ }
131015
131073
  if (def.alwaysLoad) entry.alwaysLoad = true;
131016
131074
  if (def.searchHint) entry.searchHint = renderFlagGated(def.searchHint, isFlagEnabled);
131017
131075
  if (def.longRunning) entry.longRunning = true;
@@ -131087,11 +131145,29 @@ function createHttpApp(registry2, options) {
131087
131145
  return;
131088
131146
  }
131089
131147
  }
131148
+ let body;
131149
+ try {
131150
+ body = canonicalToolArgs(def.id, req.body);
131151
+ } catch (err) {
131152
+ if (!(err instanceof ToolParamAliasError)) throw err;
131153
+ emitHttpFailure(
131154
+ {
131155
+ error_code: FAILURE_CODES.HTTP_ZOD_VALIDATION_FAILED,
131156
+ failure_stage: "http_param_alias",
131157
+ failure_area: "http",
131158
+ error_kind: "validation"
131159
+ },
131160
+ req.body
131161
+ );
131162
+ const issues = [{ code: "custom", path: [], message: err.message }];
131163
+ res.status(400).json({ error: JSON.stringify(issues), message: err.message, issues });
131164
+ return;
131165
+ }
131090
131166
  let bodyArgs;
131091
131167
  let resolvedFileInputs;
131092
131168
  let derivedTargets;
131093
131169
  try {
131094
- const resolved = await resolveFileInputs(def, req.body, (id) => {
131170
+ const resolved = await resolveFileInputs(def, body, (id) => {
131095
131171
  const entry = uploads.get(id);
131096
131172
  if (entry) uploads.delete(id);
131097
131173
  return entry;
@@ -168118,7 +168194,13 @@ function fromYamlStep(raw, blockDepth = 0) {
168118
168194
  if ("script" in raw) return parseScriptStep(raw, raw.script);
168119
168195
  if ("tool" in raw) {
168120
168196
  const r = raw;
168121
- const step = { kind: "tool", name: r.tool, args: r.args ?? {} };
168197
+ let args = r.args ?? {};
168198
+ try {
168199
+ args = canonicalToolArgs(r.tool, args);
168200
+ } catch (err) {
168201
+ badEntry(raw, err instanceof Error ? err.message : String(err));
168202
+ }
168203
+ const step = { kind: "tool", name: r.tool, args };
168122
168204
  if (r.delayMs !== void 0) step.delayMs = r.delayMs;
168123
168205
  return step;
168124
168206
  }
@@ -168470,7 +168552,7 @@ var flowStartRecordingTool = {
168470
168552
  },
168471
168553
  description: `Start recording a new e2e test, resetting .argent/e2e/<name>.yaml to an empty e2e test and replacing any existing one.
168472
168554
  Use when you want to capture a reusable sequence of device interactions for later replay.
168473
- Returns { message, flowFile, savedTo } and optionally { restarted, discardedSteps } if a live recording of the same e2e test was discarded.
168555
+ Returns { message, e2eTestFile, savedTo } and optionally { restarted, discardedSteps } if a live recording of the same e2e test was discarded.
168474
168556
  Without a link, it creates that file and fails if the .argent/e2e/ directory cannot be created or the file cannot be written. Over a link (argent link or ARGENT_TOOLS_URL, also to 127.0.0.1), your client writes the file, and \`savedTo\` is its path on your computer, or null when that write failed.
168475
168557
 
168476
168558
  Several e2e tests can be recorded at once, each keyed by the \`name\` + \`project_root\`
@@ -168541,12 +168623,14 @@ reports for those steps.`,
168541
168623
  message: `Restarted recording "${params.name}" \u2014 ${lost} was discarded and ` + reset,
168542
168624
  restarted: true,
168543
168625
  ...discardedSteps === void 0 ? {} : { discardedSteps },
168626
+ e2eTestFile: flowFile,
168544
168627
  flowFile,
168545
168628
  savedTo
168546
168629
  };
168547
168630
  }
168548
168631
  return {
168549
168632
  message: `Started recording "${params.name}" e2e test`,
168633
+ e2eTestFile: flowFile,
168550
168634
  flowFile,
168551
168635
  savedTo
168552
168636
  };
@@ -169698,7 +169782,7 @@ async function runDirective(env, step) {
169698
169782
  return {
169699
169783
  ok: false,
169700
169784
  indeterminate: true,
169701
- reason: `\`await: { idle }\` cannot run on ${env.device.platform}: flows have no UI-tree source on this platform, so screen stillness can never be judged. Replace this step with an explicit \`wait:\`.`
169785
+ reason: `\`await: { idle }\` cannot run on ${env.device.platform}: e2e tests have no UI-tree source on this platform, so screen stillness can never be judged. Replace this step with an explicit \`wait:\`.`
169702
169786
  };
169703
169787
  }
169704
169788
  switch (step.kind) {
@@ -170647,7 +170731,7 @@ var UPLOAD_STAGE_BY_KIND = {
170647
170731
  };
170648
170732
  function nestedFlowRef(args) {
170649
170733
  if (typeof args.name === "string") return ` (name: ${args.name})`;
170650
- if (typeof args.flow_path === "string") return ` (flow_path: ${args.flow_path})`;
170734
+ if (typeof args.e2e_test_path === "string") return ` (e2e_test_path: ${args.e2e_test_path})`;
170651
170735
  return "";
170652
170736
  }
170653
170737
  function toolStepFilePaths(registry2, tool, args) {
@@ -170760,9 +170844,9 @@ async function prepareNestedFlow(registry2, project, toolId, args) {
170760
170844
  };
170761
170845
  const resolved = await resolveFileInputs(
170762
170846
  { fileInputs: registry2.getTool(toolId)?.fileInputs },
170763
- { ...args, flow_file: wire }
170847
+ { ...args, e2e_test_file: wire }
170764
170848
  );
170765
- const input2 = resolved.fileInputs?.flow_file;
170849
+ const input2 = resolved.fileInputs?.e2e_test_file;
170766
170850
  if (input2) {
170767
170851
  input2.canonical = hop.canonical;
170768
170852
  input2.spelling = hop.spelling;
@@ -170797,7 +170881,8 @@ function count(value) {
170797
170881
  return typeof value === "number" ? value : 0;
170798
170882
  }
170799
170883
  function flowExecuteOutcome(result) {
170800
- const flow = typeof result.flow === "string" ? result.flow : "the composed e2e test";
170884
+ const name = result.e2eTest ?? result.flow;
170885
+ const flow = typeof name === "string" ? name : "the composed e2e test";
170801
170886
  if (!("steps" in result) && typeof result.notice === "string") {
170802
170887
  const prerequisite = typeof result.executionPrerequisite === "string" && result.executionPrerequisite ? `: ${result.executionPrerequisite}` : "";
170803
170888
  return {
@@ -171350,7 +171435,7 @@ var DIRECTIVE_COMMAND_HINTS = {
171350
171435
  run: {
171351
171436
  tool: "e2e-execute",
171352
171437
  rewritten: true,
171353
- rewriteCondition: "when the target resolves as a sibling e2e test in this recording's folder, on the computer that has the project; a `name` that does not is kept as a raw `tool: e2e-execute` step, and a `flow_path` that is not a sibling is refused outright and records nothing"
171438
+ rewriteCondition: "when the target resolves as a sibling e2e test in this recording's folder, on the computer that has the project; a `name` that does not is kept as a raw `tool: e2e-execute` step, and an `e2e_test_path` that is not a sibling is refused outright and records nothing"
171354
171439
  },
171355
171440
  type: { tool: "keyboard", rewritten: false },
171356
171441
  await: { tool: AWAIT_UI_ELEMENT_TOOL_ID, rewritten: false },
@@ -171399,10 +171484,10 @@ function directiveCommandHint(command) {
171399
171484
  }
171400
171485
  var RUN_TARGET_COMMAND = "e2e-execute";
171401
171486
  async function rewriteSiblingFlowPath(session, args, project, linked) {
171402
- const flowPath = args.flow_path;
171487
+ const flowPath = args.e2e_test_path;
171403
171488
  if (typeof flowPath !== "string" || args.name !== void 0) return;
171404
171489
  const invalid = (detail) => new FailureError(
171405
- `Cannot record an e2e-execute of flow_path "${flowPath}": ${detail}. flow_path carries no file-input resolution through e2e-add-step's opaque args \u2014 pass name + project_root for an e2e test saved beside the recording, or add a \`run: <relative path>.yaml\` step to the e2e test YAML by hand for a cross-directory target.`,
171490
+ `Cannot record an e2e-execute of e2e_test_path "${flowPath}": ${detail}. e2e_test_path carries no file-input resolution through e2e-add-step's opaque args \u2014 pass name + project_root for an e2e test saved beside the recording, or add a \`run: <relative path>.yaml\` step to the e2e test YAML by hand for a cross-directory target.`,
171406
171491
  {
171407
171492
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
171408
171493
  failure_stage: "flow_add_step_flow_path",
@@ -171446,7 +171531,7 @@ async function rewriteSiblingFlowPath(session, args, project, linked) {
171446
171531
  const suppliedBase = path45.basename(flowPath);
171447
171532
  if (linked && project.mode === "host") {
171448
171533
  throw new FailureError(
171449
- `Cannot record an e2e-execute of flow_path "${flowPath}": the argent client sent no files with this call, so the recorder cannot check that the file is a sibling of the recording. Update the argent CLI or MCP adapter on the client.`,
171534
+ `Cannot record an e2e-execute of e2e_test_path "${flowPath}": the argent client sent no files with this call, so the recorder cannot check that the file is a sibling of the recording. Update the argent CLI or MCP adapter on the client.`,
171450
171535
  {
171451
171536
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
171452
171537
  failure_stage: "flow_add_step_flow_path",
@@ -171461,11 +171546,11 @@ async function rewriteSiblingFlowPath(session, args, project, linked) {
171461
171546
  } catch (err) {
171462
171547
  if (path45.resolve(flowDir) === path45.resolve(flowsDir)) throw err;
171463
171548
  throw invalid(
171464
- `over a link, this argent client sends a flow_path only for an e2e test beside the recording; update the argent CLI or MCP adapter on the client (${err instanceof Error ? err.message : String(err)})`
171549
+ `over a link, this argent client sends an e2e_test_path only for an e2e test beside the recording; update the argent CLI or MCP adapter on the client (${err instanceof Error ? err.message : String(err)})`
171465
171550
  );
171466
171551
  }
171467
171552
  if (spelling.state !== "listed") {
171468
- const recovery = spelling.state === "absent" ? `pass the basename exactly as it appears on disk` : spelling.addressable ? `pass flow_path with the on-disk basename "${spelling.actual}"` : `rename "${spelling.actual}" to "${suppliedBase}" to record it \u2014 e2e test files must be lowercase .yaml`;
171553
+ const recovery = spelling.state === "absent" ? `pass the basename exactly as it appears on disk` : spelling.addressable ? `pass e2e_test_path with the on-disk basename "${spelling.actual}"` : `rename "${spelling.actual}" to "${suppliedBase}" to record it \u2014 e2e test files must be lowercase .yaml`;
171469
171554
  throw invalid(
171470
171555
  `the file must be named as it appears on disk \u2014 no directory entry is named "${suppliedBase}"` + (spelling.state === "case_folded" ? ` (this filesystem matched it case-insensitively to "${spelling.actual}")` : "") + `, so the recorded run: step would name an e2e test no case-sensitive checkout can find \u2014 ` + recovery
171471
171556
  );
@@ -171476,7 +171561,7 @@ async function rewriteSiblingFlowPath(session, args, project, linked) {
171476
171561
  throw invalid(`project_root "${projectRoot}" resolves "${stem}" to "${picked.path}" instead`);
171477
171562
  }
171478
171563
  }
171479
- delete args.flow_path;
171564
+ delete args.e2e_test_path;
171480
171565
  args.name = stem;
171481
171566
  }
171482
171567
  async function captureRunTarget(session, args, project) {
@@ -171538,7 +171623,7 @@ async function captureRunTarget(session, args, project) {
171538
171623
  function replayRefusal(issue2, args) {
171539
171624
  let hint;
171540
171625
  if (issue2.kind === "nested") {
171541
- hint = nestedFlowTarget(args)?.kind === "name" ? " Over a link, a nested e2e-execute runs only when the argent client sends the e2e test it names with the call. Update the argent CLI or MCP adapter on the client." : " Over a link, a nested e2e-execute runs only when it names its e2e test with a test name in name, has an absolute project_root with no .. segment, and has no flow_path.";
171626
+ hint = nestedFlowTarget(args)?.kind === "name" ? " Over a link, a nested e2e-execute runs only when the argent client sends the e2e test it names with the call. Update the argent CLI or MCP adapter on the client." : " Over a link, a nested e2e-execute runs only when it names its e2e test with a test name in name, has an absolute project_root with no .. segment, and has no e2e_test_path.";
171542
171627
  } else if (issue2.fixes.length === 0) {
171543
171628
  hint = " A replay without a link runs this step. To keep it, add it to the YAML by hand after e2e-finish-recording.";
171544
171629
  } else {
@@ -171598,6 +171683,10 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
171598
171683
  throw err;
171599
171684
  }
171600
171685
  const authoredArgs = { ...args };
171686
+ try {
171687
+ args = canonicalToolArgs(command, args);
171688
+ } catch {
171689
+ }
171601
171690
  const linked = isLinkedRecorderCall(session, ctx);
171602
171691
  const stepFiles = ctx?.fileInputs?.project_root?.members;
171603
171692
  const project = stepFiles ? new ClientProjectAccess(stepFiles) : new HostProjectAccess();
@@ -173303,7 +173392,7 @@ var flowFinishRecordingTool = {
173303
173392
  completedMsg: ({ params }) => `Saved recorded e2e test ${params.name}`,
173304
173393
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to finish recording of e2e test ${params.name}: ${failureSignal2.error_code}`
173305
173394
  },
173306
- description: `Finish recording the e2e test named by \`name\` + \`project_root\`, leaving recordings under any other key untouched. Returns { message, path, executionPrerequisite, steps, summary, flowFile, savedTo } - a summary of all recorded steps plus the final YAML. Use when you have added all desired steps and want to finalize the e2e test file. Fails if that e2e test has no recording in progress.
173395
+ description: `Finish recording the e2e test named by \`name\` + \`project_root\`, leaving recordings under any other key untouched. Returns { message, path, executionPrerequisite, steps, summary, e2eTestFile, savedTo } - a summary of all recorded steps plus the final YAML. Use when you have added all desired steps and want to finalize the e2e test file. Fails if that e2e test has no recording in progress.
173307
173396
  A warning e2e-add-step raised on a recorded \`await-ui-element\` is repeated in \`summary\` as a \`warning:\` line of its own, right below the step it judges, and \`message\` counts them by kind. A warning is repeated only while the step it judges is still identifiable by its number: hand-editing the .yaml during the recording moves the steps, so those warnings are DROPPED rather than pinned on whichever step inherited the number, and \`message\` says how many were dropped. A step that carries a cross-tree warning was re-probed against the runner's tree: read it before converting that wait to \`await:\`/\`assert:\`, which is what the verdict is about and what this moment is for. A step that recorded a wait which did not pass was never probed at all, and its own warning names the CAUSE, because only one of them judges the condition: an unmet wait was read and found false, and it stops the run at replay; a wait whose tree source could not be read, or one that was cancelled, observed nothing and leaves the condition UNKNOWN rather than known-bad. Read those before replaying.
173308
173397
  You can still edit the .yaml file directly afterwards to remove or reorder steps.`,
173309
173398
  zodSchema: zodSchema70,
@@ -173341,6 +173430,7 @@ You can still edit the .yaml file directly afterwards to remove or reorder steps
173341
173430
  executionPrerequisite: flow.executionPrerequisite,
173342
173431
  steps: flow.steps.length,
173343
173432
  summary,
173433
+ e2eTestFile: flowFile,
173344
173434
  flowFile,
173345
173435
  savedTo
173346
173436
  };
@@ -175786,15 +175876,15 @@ async function restoreStatusBar(device) {
175786
175876
  // ../tool-server/src/tools/flows/flow-run.ts
175787
175877
  var zodSchema71 = external_exports.object({
175788
175878
  name: external_exports.string().optional().describe(
175789
- 'Name of a saved e2e test to run from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when flow_path is set.'
175879
+ 'Name of a saved e2e test to run from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when e2e_test_path is set.'
175790
175880
  ),
175791
175881
  project_root: external_exports.string().describe(
175792
- "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with flow_path, the e2e test, its run: siblings, its script: paths and baselines all resolve beside the YAML instead, so pass the agent's cwd. A script still RUNS in this root whichever source was used."
175882
+ "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with e2e_test_path, the e2e test, its run: siblings, its script: paths and baselines all resolve beside the YAML instead, so pass the agent's cwd. A script still RUNS in this root whichever source was used."
175793
175883
  ),
175794
- flow_file: external_exports.string().optional().describe(
175884
+ e2e_test_file: external_exports.string().optional().describe(
175795
175885
  "Path to the e2e test .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset."
175796
175886
  ),
175797
- flow_path: external_exports.string().optional().describe(
175887
+ e2e_test_path: external_exports.string().optional().describe(
175798
175888
  "Omit when name is set. Absolute path to an e2e test .yaml on the client. Over a link (argent link or ARGENT_TOOLS_URL), the argent client uploads the file, its run: fragments and the snapshot baselines of each run, and the tool-server runs those copies. Keep run: fragments under project_root or beside the e2e test file. With updateBaselines, the client writes the new baselines when the run ends. The client also uploads each absolute .png or .yaml path that a tool: step takes as a file argument, when the file is under project_root or beside the e2e test file. A tool: e2e-execute step that names an e2e test with name and an absolute project_root without a .. segment runs: the client also uploads that e2e test and its own files. Over a link, the uploaded e2e tests must not have: script: steps; tool: steps that run an e2e test another way or record an e2e test; tool: steps that take a directory, an app or an output directory; tool: steps whose tool builds a file path from several arguments; tool: steps that name a relative path or a file other than .png or .yaml. Without a link, the tool-server reads the files in place and all step kinds run."
175799
175889
  ),
175800
175890
  device: external_exports.string().optional().describe(
@@ -175810,32 +175900,32 @@ var zodSchema71 = external_exports.object({
175810
175900
  "Set to true to confirm the execution prerequisite has been met. Required (LLM path) when a fragment defines an executionPrerequisite."
175811
175901
  )
175812
175902
  }).superRefine((params, ctx) => {
175813
- if (params.name === void 0 === (params.flow_path === void 0)) {
175903
+ if (params.name === void 0 === (params.e2e_test_path === void 0)) {
175814
175904
  ctx.addIssue({
175815
175905
  code: external_exports.ZodIssueCode.custom,
175816
- message: params.name !== void 0 ? "Pass exactly one e2e test source: name or flow_path." : "Pass exactly one e2e test source: name or flow_path. e2e-execute needs the e2e test's name in `name` \u2014 it resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.",
175817
- // The ROOT, not `flow_path`: the rule spans both source fields, and a
175818
- // path would prefix the message with "`flow_path`:".
175906
+ message: params.name !== void 0 ? "Pass exactly one e2e test source: name or e2e_test_path." : "Pass exactly one e2e test source: name or e2e_test_path. e2e-execute needs the e2e test's name in `name` \u2014 it resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.",
175907
+ // The ROOT, not `e2e_test_path`: the rule spans both source fields, and a
175908
+ // path would prefix the message with "`e2e_test_path`:".
175819
175909
  path: []
175820
175910
  });
175821
175911
  }
175822
175912
  });
175823
175913
  var fileInputs4 = [
175824
175914
  {
175825
- target: "flow_path",
175826
- path: "${flow_path}",
175915
+ target: "e2e_test_path",
175916
+ path: "${e2e_test_path}",
175827
175917
  kind: "file",
175828
175918
  optional: true,
175829
175919
  unwrapWhenSet: "name",
175830
175920
  collect: "flow"
175831
175921
  },
175832
175922
  {
175833
- target: "flow_file",
175923
+ target: "e2e_test_file",
175834
175924
  // A client that predates `paths` reads the legacy dir only.
175835
175925
  path: "${project_root}/.argent/flows/${name}.yaml",
175836
175926
  paths: E2E_FILE_TEMPLATES,
175837
175927
  kind: "file",
175838
- skipWhenSet: "flow_path",
175928
+ skipWhenSet: "e2e_test_path",
175839
175929
  collect: "flow"
175840
175930
  }
175841
175931
  ];
@@ -176126,8 +176216,8 @@ function deviceEnv(state3) {
176126
176216
  return { ...state3, device: state3.device };
176127
176217
  }
176128
176218
  function displayFlowName(params) {
176129
- const stem = params.flow_path === void 0 ? void 0 : path50.basename(params.flow_path, ".yaml");
176130
- return params.name || stem || params.flow_path || "(unspecified)";
176219
+ const stem = params.e2e_test_path === void 0 ? void 0 : path50.basename(params.e2e_test_path, ".yaml");
176220
+ return params.name || stem || params.e2e_test_path || "(unspecified)";
176131
176221
  }
176132
176222
  function* walkSteps(steps, within = "") {
176133
176223
  for (const [i, step] of steps.entries()) {
@@ -176273,7 +176363,9 @@ function assertUploadSelfContained(registry2, flow, closure, origin = {
176273
176363
  throw new FailureError(
176274
176364
  `${origin.subject} is not self-contained, and ${origin.arrival}. The steps below read or write project files, which stay on the client:
176275
176365
  ` + offending.map((o) => ` - ${o.line}`).join("\n") + `
176276
- Run the e2e test on the computer that runs the tool-server, with no link and no ARGENT_TOOLS_URL, so that the tool-server reads the files in place.${uploadUpdateHint(servable)}${toolFilePathHints(toolFileFixes)}`,
176366
+ Run the e2e test on the computer that runs the tool-server, with no link and no ARGENT_TOOLS_URL, so that the tool-server reads the files in place.${uploadUpdateHint(servable)}` + // An older client lists e2e_test_path from this schema but collects the
176367
+ // files only for flow_path.
176368
+ (servable.length > 0 ? " A client older than the e2e_test_path param sends those files for a test passed as flow_path." : "") + toolFilePathHints(toolFileFixes),
176277
176369
  {
176278
176370
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
176279
176371
  failure_stage: UPLOAD_STAGE_BY_KIND[offending[0].kind],
@@ -176294,7 +176386,7 @@ function createRunFlowTool(registry2) {
176294
176386
  description: `Run a saved YAML e2e test end to end. Use when
176295
176387
  asked to replay a recorded path, re-run a QA regression, or check that a known journey still passes; for a
176296
176388
  one-off interaction use the gesture tools instead, and to author an e2e test use e2e-start-recording. Pass
176297
- exactly one e2e test source: name (under project_root) or flow_path.
176389
+ exactly one e2e test source: name (under project_root) or e2e_test_path.
176298
176390
  Returns a per-step report: the first failure stops the run and the rest report as skipped.`,
176299
176391
  longRunning: true,
176300
176392
  zodSchema: zodSchema71,
@@ -176305,11 +176397,11 @@ Returns a per-step report: the first failure stops the run and the rest report a
176305
176397
  const signal = ctx?.signal;
176306
176398
  const { filePath, flowName, viaUpload, shadowed } = await resolveFlowSource(
176307
176399
  params,
176308
- ctx?.fileInputs?.flow_file,
176309
- ctx?.fileInputs?.flow_path
176400
+ ctx?.fileInputs?.e2e_test_file,
176401
+ ctx?.fileInputs?.e2e_test_path
176310
176402
  );
176311
176403
  const warning = shadowed ? { warning: e2eShadowWarning(filePath, shadowed) } : {};
176312
- const rootInput = viaUpload ? ctx?.fileInputs?.flow_path ?? ctx?.fileInputs?.flow_file : void 0;
176404
+ const rootInput = viaUpload ? ctx?.fileInputs?.e2e_test_path ?? ctx?.fileInputs?.e2e_test_file : void 0;
176313
176405
  const clientProject = rootInput?.members ? new ClientProjectAccess(rootInput.members) : void 0;
176314
176406
  const project = clientProject ?? new HostProjectAccess();
176315
176407
  const canonicalPath = await canonicalFlowPath(filePath);
@@ -176369,6 +176461,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
176369
176461
  }
176370
176462
  if (flow.executionPrerequisite && !params.prerequisiteAcknowledged) {
176371
176463
  return {
176464
+ e2eTest: flowName,
176372
176465
  flow: flowName,
176373
176466
  notice: "This e2e test has an execution prerequisite that must be fulfilled before it can run. Verify the prerequisite is met and call e2e-execute again with prerequisiteAcknowledged set to true.",
176374
176467
  executionPrerequisite: flow.executionPrerequisite,
@@ -176622,6 +176715,7 @@ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2, t
176622
176715
  else errored++;
176623
176716
  }
176624
176717
  return {
176718
+ e2eTest: flowName,
176625
176719
  flow: flowName,
176626
176720
  device: deviceId,
176627
176721
  executionPrerequisite,
@@ -176640,6 +176734,7 @@ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2, t
176640
176734
  };
176641
176735
  }
176642
176736
  function pushReport(state3, report) {
176737
+ if (report.e2eTest !== void 0) report.flow = report.e2eTest;
176643
176738
  state3.reports.push(report);
176644
176739
  state3.onStepReport?.(report);
176645
176740
  }
@@ -176676,7 +176771,7 @@ async function execSteps(state3, steps, scope) {
176676
176771
  index,
176677
176772
  kind: step.kind,
176678
176773
  status: "skip",
176679
- flow: stepFlow(step, scope),
176774
+ e2eTest: stepFlow(step, scope),
176680
176775
  target: stepTarget(step),
176681
176776
  ...depthOf(scope),
176682
176777
  ...stopReason ? { reason: stopReason } : {},
@@ -176694,7 +176789,7 @@ async function execSteps(state3, steps, scope) {
176694
176789
  index,
176695
176790
  kind: step.kind,
176696
176791
  status: "error",
176697
- flow: scopeFlow(scope),
176792
+ e2eTest: scopeFlow(scope),
176698
176793
  target: stepTarget(step),
176699
176794
  ...depthOf(scope),
176700
176795
  reason: `step needs a device but the e2e test was resolved as device-free \u2014 pass an explicit device`
@@ -176710,7 +176805,7 @@ async function execSteps(state3, steps, scope) {
176710
176805
  kind: step.kind,
176711
176806
  status: "skip",
176712
176807
  reason: "run aborted",
176713
- flow: stepFlow(step, scope),
176808
+ e2eTest: stepFlow(step, scope),
176714
176809
  target: stepTarget(step),
176715
176810
  ...depthOf(scope),
176716
176811
  ...step.kind === "echo" ? { message: step.message } : {}
@@ -176762,7 +176857,7 @@ function reportBlockSkipped(state3, steps, scope, reason2) {
176762
176857
  kind: step.kind,
176763
176858
  status: "skip",
176764
176859
  reason: reason2,
176765
- flow: stepFlow(step, scope),
176860
+ e2eTest: stepFlow(step, scope),
176766
176861
  target: stepTarget(step),
176767
176862
  ...depthOf(scope),
176768
176863
  ...step.kind === "echo" ? { message: step.message } : {}
@@ -176788,7 +176883,7 @@ async function execWhenStep(state3, step, scope) {
176788
176883
  const marker = {
176789
176884
  index,
176790
176885
  kind: "when",
176791
- flow: scopeFlow(scope),
176886
+ e2eTest: scopeFlow(scope),
176792
176887
  target,
176793
176888
  ...depthOf(scope)
176794
176889
  };
@@ -176848,7 +176943,7 @@ async function execRunStep(state3, step, scope) {
176848
176943
  index,
176849
176944
  kind: "run",
176850
176945
  status: "error",
176851
- flow: display,
176946
+ e2eTest: display,
176852
176947
  target,
176853
176948
  reason: reason2,
176854
176949
  ...depthOf(scope),
@@ -176896,7 +176991,7 @@ async function execRunStep(state3, step, scope) {
176896
176991
  index,
176897
176992
  kind: "run",
176898
176993
  status: "pass",
176899
- flow: display,
176994
+ e2eTest: display,
176900
176995
  target,
176901
176996
  ...depthOf(scope),
176902
176997
  durationMs: Date.now() - startedAt
@@ -176950,7 +177045,7 @@ async function execLeafStep(state3, step, index, scope) {
176950
177045
  const base = {
176951
177046
  index,
176952
177047
  kind: step.kind,
176953
- flow: scopeFlow(scope),
177048
+ e2eTest: scopeFlow(scope),
176954
177049
  target: stepTarget(step),
176955
177050
  ...depthOf(scope)
176956
177051
  };
@@ -177158,7 +177253,7 @@ function errMsg4(err) {
177158
177253
  return err instanceof Error ? err.message : String(err);
177159
177254
  }
177160
177255
  function assertFlowPathShape(flowPath) {
177161
- const windows = windowsPathRefusal("flow_path", flowPath);
177256
+ const windows = windowsPathRefusal("e2e_test_path", flowPath);
177162
177257
  if (windows) {
177163
177258
  throw new FailureError(windows, {
177164
177259
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
@@ -177169,7 +177264,7 @@ function assertFlowPathShape(flowPath) {
177169
177264
  }
177170
177265
  if (!path50.isAbsolute(flowPath)) {
177171
177266
  throw new FailureError(
177172
- `Invalid flow_path "${flowPath}": e2e test paths must be absolute \u2014 a relative path is resolved against the tool server's working directory, not the caller's. Pass the absolute path to the e2e test's YAML.`,
177267
+ `Invalid e2e_test_path "${flowPath}": e2e test paths must be absolute \u2014 a relative path is resolved against the tool server's working directory, not the caller's. Pass the absolute path to the e2e test's YAML.`,
177173
177268
  {
177174
177269
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177175
177270
  failure_stage: "flow_path_absolute",
@@ -177180,7 +177275,7 @@ function assertFlowPathShape(flowPath) {
177180
177275
  }
177181
177276
  if (flowPath.split(/[\\/]+/).includes("..")) {
177182
177277
  throw new FailureError(
177183
- `Invalid flow_path "${flowPath}": e2e test paths must not contain ".." segments \u2014 a ".." after a symlinked directory can name a different file than the spelling suggests, and the argent client always sends fully resolved paths. Pass the fully resolved absolute path to the e2e test's YAML.`,
177278
+ `Invalid e2e_test_path "${flowPath}": e2e test paths must not contain ".." segments \u2014 a ".." after a symlinked directory can name a different file than the spelling suggests, and the argent client always sends fully resolved paths. Pass the fully resolved absolute path to the e2e test's YAML.`,
177184
177279
  {
177185
177280
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177186
177281
  failure_stage: "flow_path_dotdot",
@@ -177195,7 +177290,7 @@ function flowNameOf(clientPath) {
177195
177290
  const bareExtension = path50.basename(clientPath).toLowerCase() === ".yaml";
177196
177291
  if (!bareExtension && clientExt !== ".yaml") {
177197
177292
  const detail = clientExt.toLowerCase() === ".yaml" ? `e2e test files must use the lowercase .yaml extension, not "${clientExt}".` : `e2e test files must use the .yaml extension.`;
177198
- throw new FailureError(`Invalid flow_path "${clientPath}": ${detail}`, {
177293
+ throw new FailureError(`Invalid e2e_test_path "${clientPath}": ${detail}`, {
177199
177294
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177200
177295
  failure_stage: "flow_path_extension",
177201
177296
  failure_area: "tool_server",
@@ -177208,9 +177303,9 @@ function flowNameOf(clientPath) {
177208
177303
  }
177209
177304
  function flowPathCasingError(clientPath, spelling) {
177210
177305
  const suppliedBase = path50.basename(clientPath);
177211
- const recovery = spelling.state === "absent" ? `Pass the basename exactly as it appears on disk.` : spelling.addressable ? `Pass flow_path with the on-disk basename "${spelling.actual}".` : `Rename "${spelling.actual}" to "${suppliedBase}" to run it \u2014 e2e test files must be lowercase .yaml.`;
177306
+ const recovery = spelling.state === "absent" ? `Pass the basename exactly as it appears on disk.` : spelling.addressable ? `Pass e2e_test_path with the on-disk basename "${spelling.actual}".` : `Rename "${spelling.actual}" to "${suppliedBase}" to run it \u2014 e2e test files must be lowercase .yaml.`;
177212
177307
  return new FailureError(
177213
- `Invalid flow_path "${clientPath}": the file must be named as it appears on disk \u2014 this filesystem matched "${suppliedBase}" case-insensitively` + (spelling.state === "case_folded" ? ` to "${spelling.actual}"` : "") + `, so the e2e test name (which keys the report and __baselines__/) would be one no directory entry carries. ${recovery}`,
177308
+ `Invalid e2e_test_path "${clientPath}": the file must be named as it appears on disk \u2014 this filesystem matched "${suppliedBase}" case-insensitively` + (spelling.state === "case_folded" ? ` to "${spelling.actual}"` : "") + `, so the e2e test name (which keys the report and __baselines__/) would be one no directory entry carries. ${recovery}`,
177214
177309
  {
177215
177310
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177216
177311
  failure_stage: "flow_path_casing",
@@ -177220,8 +177315,8 @@ function flowPathCasingError(clientPath, spelling) {
177220
177315
  );
177221
177316
  }
177222
177317
  async function resolveFlowSource(params, fileInput, flowPathInput) {
177223
- if (params.name === void 0 === (params.flow_path === void 0)) {
177224
- throw new FailureError("Pass exactly one e2e test source: name or flow_path.", {
177318
+ if (params.name === void 0 === (params.e2e_test_path === void 0)) {
177319
+ throw new FailureError("Pass exactly one e2e test source: name or e2e_test_path.", {
177225
177320
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177226
177321
  failure_stage: "flow_source",
177227
177322
  failure_area: "tool_server",
@@ -177229,16 +177324,16 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
177229
177324
  });
177230
177325
  }
177231
177326
  assertValidProjectRoot(params.project_root);
177232
- if (params.flow_path !== void 0) {
177327
+ if (params.e2e_test_path !== void 0) {
177233
177328
  if (flowPathInput?.viaUpload) {
177234
177329
  const clientPath2 = flowPathInput.clientPath;
177235
177330
  assertFlowPathShape(clientPath2);
177236
- return { filePath: params.flow_path, flowName: flowNameOf(clientPath2), viaUpload: true };
177331
+ return { filePath: params.e2e_test_path, flowName: flowNameOf(clientPath2), viaUpload: true };
177237
177332
  }
177238
- const isVerifiedHostPath = flowPathInput?.presentOnHost === true && flowPathInput.statVerified === true && path50.resolve(params.flow_path) === path50.resolve(flowPathInput.clientPath);
177333
+ const isVerifiedHostPath = flowPathInput?.presentOnHost === true && flowPathInput.statVerified === true && path50.resolve(params.e2e_test_path) === path50.resolve(flowPathInput.clientPath);
177239
177334
  if (!isVerifiedHostPath) {
177240
177335
  throw new FailureError(
177241
- `Invalid flow_path "${params.flow_path}": explicit e2e test paths must be supplied through the flow_path file-input boundary. Pass the client-local path and let the argent client resolve it.`,
177336
+ `Invalid e2e_test_path "${params.e2e_test_path}": explicit e2e test paths must be supplied through the e2e_test_path file-input boundary. Pass the client-local path and let the argent client resolve it.`,
177242
177337
  {
177243
177338
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177244
177339
  failure_stage: "flow_path_boundary",
@@ -177247,24 +177342,26 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
177247
177342
  }
177248
177343
  );
177249
177344
  }
177250
- assertFlowPathShape(params.flow_path);
177345
+ assertFlowPathShape(params.e2e_test_path);
177251
177346
  const clientPath = flowPathInput.clientPath;
177252
177347
  const flowName2 = flowNameOf(clientPath);
177253
177348
  const spelling = await classifyOnDiskSpelling(
177254
- path50.dirname(params.flow_path),
177349
+ path50.dirname(params.e2e_test_path),
177255
177350
  path50.basename(clientPath)
177256
177351
  );
177257
177352
  if (spelling.state !== "listed") throw flowPathCasingError(clientPath, spelling);
177258
- return { filePath: params.flow_path, flowName: flowName2, viaUpload: false };
177353
+ return { filePath: params.e2e_test_path, flowName: flowName2, viaUpload: false };
177259
177354
  }
177260
177355
  const flowName = params.name;
177261
177356
  assertSafeFlowName(flowName);
177262
177357
  const candidates = e2eFileCandidates(params.project_root, flowName);
177263
- if (params.flow_file && fileInput?.viaUpload)
177264
- return { filePath: params.flow_file, flowName, viaUpload: true };
177265
- if (params.flow_file && (!path50.isAbsolute(params.flow_file) || params.flow_file.split(/[\\/]+/).includes("..") || !candidates.some((candidate) => path50.resolve(candidate) === path50.resolve(params.flow_file)))) {
177358
+ if (params.e2e_test_file && fileInput?.viaUpload)
177359
+ return { filePath: params.e2e_test_file, flowName, viaUpload: true };
177360
+ if (params.e2e_test_file && (!path50.isAbsolute(params.e2e_test_file) || params.e2e_test_file.split(/[\\/]+/).includes("..") || !candidates.some(
177361
+ (candidate) => path50.resolve(candidate) === path50.resolve(params.e2e_test_file)
177362
+ ))) {
177266
177363
  throw new FailureError(
177267
- `Invalid flow_file "${params.flow_file}": it must resolve to the e2e test's path under the project root ("${candidates.join('" or "')}"). flow_file is internal \u2014 leave it unset and pass project_root + name.`,
177364
+ `Invalid e2e_test_file "${params.e2e_test_file}": it must resolve to the e2e test's path under the project root ("${candidates.join('" or "')}"). e2e_test_file is internal \u2014 leave it unset and pass project_root + name.`,
177268
177365
  {
177269
177366
  error_code: FAILURE_CODES.FLOW_FILE_INVALID,
177270
177367
  failure_stage: "flow_file_containment",
@@ -177274,8 +177371,8 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
177274
177371
  );
177275
177372
  }
177276
177373
  const picked = await pickE2eFile(candidates);
177277
- const filePath = params.flow_file || picked.path;
177278
- const spellingDirs = params.flow_file || picked.exists ? [path50.dirname(filePath)] : candidates.map((candidate) => path50.dirname(candidate));
177374
+ const filePath = params.e2e_test_file || picked.path;
177375
+ const spellingDirs = params.e2e_test_file || picked.exists ? [path50.dirname(filePath)] : candidates.map((candidate) => path50.dirname(candidate));
177279
177376
  for (const dir of spellingDirs) {
177280
177377
  const spelling = await classifyOnDiskSpelling(dir, `${flowName}.yaml`);
177281
177378
  if (spelling.state === "case_folded") throw flowNameCasingError(flowName, spelling);
@@ -177290,22 +177387,22 @@ var fs66 = __toESM(require("node:fs/promises"));
177290
177387
  init_src2();
177291
177388
  var zodSchema72 = external_exports.object({
177292
177389
  name: external_exports.string().optional().describe(
177293
- 'Name of a saved e2e test to inspect from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when flow_path is set.'
177390
+ 'Name of a saved e2e test to inspect from `.argent/e2e`, or `.argent/flows` when it is not there (e.g. "settings-explore"). Omit when e2e_test_path is set.'
177294
177391
  ),
177295
177392
  project_root: external_exports.string().describe(
177296
- "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with flow_path, the prerequisite is read from that YAML instead, so pass the agent's cwd."
177393
+ "Absolute path to the calling agent's project root: the cwd it is working in. With name, the saved e2e test is read from `.argent/e2e/<name>.yaml`, else `.argent/flows/<name>.yaml`, under this root; with e2e_test_path, the prerequisite is read from that YAML instead, so pass the agent's cwd."
177297
177394
  ),
177298
- flow_file: external_exports.string().optional().describe(
177395
+ e2e_test_file: external_exports.string().optional().describe(
177299
177396
  "Path to the e2e test .yaml as readable by the tool-server. Internal: the argent client derives it from project_root and name automatically; leave unset."
177300
177397
  ),
177301
- flow_path: external_exports.string().optional().describe(
177398
+ e2e_test_path: external_exports.string().optional().describe(
177302
177399
  "Omit when name is set. Absolute path to an e2e test .yaml on the client. Over a link (argent link or ARGENT_TOOLS_URL), the argent client uploads the file and the tool-server reads the uploaded copy; without a link, the tool-server reads the file in place. Pass the path through the argent client; a raw path that the file-input boundary did not verify is rejected. Pass the same e2e test source here as to e2e-execute, so the prerequisite you read belongs to the e2e test that will run."
177303
177400
  )
177304
177401
  }).superRefine((params, ctx) => {
177305
- if (params.name === void 0 === (params.flow_path === void 0)) {
177402
+ if (params.name === void 0 === (params.e2e_test_path === void 0)) {
177306
177403
  ctx.addIssue({
177307
177404
  code: external_exports.ZodIssueCode.custom,
177308
- message: params.name !== void 0 ? "Pass exactly one e2e test source: name or flow_path." : "Pass exactly one e2e test source: name or flow_path. e2e-read-prerequisite needs the e2e test's name in `name` \u2014 it resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.",
177405
+ message: params.name !== void 0 ? "Pass exactly one e2e test source: name or e2e_test_path." : "Pass exactly one e2e test source: name or e2e_test_path. e2e-read-prerequisite needs the e2e test's name in `name` \u2014 it resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.",
177309
177406
  // The ROOT, matching flow-execute: the rule spans both source fields,
177310
177407
  // so it must not be anchored on one of them.
177311
177408
  path: []
@@ -177314,18 +177411,18 @@ var zodSchema72 = external_exports.object({
177314
177411
  });
177315
177412
  var fileInputs5 = [
177316
177413
  {
177317
- target: "flow_path",
177318
- path: "${flow_path}",
177414
+ target: "e2e_test_path",
177415
+ path: "${e2e_test_path}",
177319
177416
  kind: "file",
177320
177417
  optional: true,
177321
177418
  unwrapWhenSet: "name"
177322
177419
  },
177323
177420
  {
177324
- target: "flow_file",
177421
+ target: "e2e_test_file",
177325
177422
  path: "${project_root}/.argent/flows/${name}.yaml",
177326
177423
  paths: E2E_FILE_TEMPLATES,
177327
177424
  kind: "file",
177328
- skipWhenSet: "flow_path"
177425
+ skipWhenSet: "e2e_test_path"
177329
177426
  }
177330
177427
  ];
177331
177428
  var flowReadPrerequisiteTool = {
@@ -177336,8 +177433,8 @@ var flowReadPrerequisiteTool = {
177336
177433
  completedMsg: () => "Read e2e test prerequisite",
177337
177434
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read e2e test prerequisite: ${failureSignal2.error_code}`
177338
177435
  },
177339
- description: `Read the execution prerequisite of an e2e test without running it: a saved e2e test from the .argent/e2e/ directory (or the older .argent/flows/), or an explicit boundary-managed flow_path.
177340
- Returns { flow, executionPrerequisite, warning? }: the logical name, plus the precondition its author recorded
177436
+ description: `Read the execution prerequisite of an e2e test without running it: a saved e2e test from the .argent/e2e/ directory (or the older .argent/flows/), or an explicit boundary-managed e2e_test_path.
177437
+ Returns { e2eTest, executionPrerequisite, warning? }: the logical name, plus the precondition its author recorded
177341
177438
  verbatim. Empty when none was declared, which is always so for a self-contained scenario: one opening
177342
177439
  on a launch may declare no prerequisite, because it builds its own start state.
177343
177440
  Use when deciding whether the device already sits where a fragment expects it (correct app foregrounded,
@@ -177345,7 +177442,7 @@ correct account, correct screen) before committing to a run, or when relaying th
177345
177442
  Touches no device: nothing is launched, tapped, dispatched or torn down, and no simulator or emulator
177346
177443
  needs booting, so calling this costs nothing but a file read.
177347
177444
  Fails if the e2e test file does not exist.
177348
- Address the e2e test exactly as you will address it in e2e-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.`,
177445
+ Address the e2e test exactly as you will address it in e2e-execute: name or e2e_test_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/e2e/<name>.yaml, else .argent/flows/<name>.yaml.`,
177349
177446
  readOnly: true,
177350
177447
  zodSchema: zodSchema72,
177351
177448
  fileInputs: fileInputs5,
@@ -177353,11 +177450,12 @@ Address the e2e test exactly as you will address it in e2e-execute: name or flow
177353
177450
  async execute(_services, params, ctx) {
177354
177451
  const { filePath, flowName, shadowed } = await resolveFlowSource(
177355
177452
  params,
177356
- ctx?.fileInputs?.flow_file,
177357
- ctx?.fileInputs?.flow_path
177453
+ ctx?.fileInputs?.e2e_test_file,
177454
+ ctx?.fileInputs?.e2e_test_path
177358
177455
  );
177359
177456
  const flow = parseFlow(await fs66.readFile(filePath, "utf8"));
177360
177457
  return {
177458
+ e2eTest: flowName,
177361
177459
  flow: flowName,
177362
177460
  executionPrerequisite: flow.executionPrerequisite,
177363
177461
  ...shadowed ? { warning: e2eShadowWarning(filePath, shadowed) } : {}