@swmansion/argent 0.32.1-next.16 → 0.32.1-next.18

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.
@@ -24653,7 +24653,7 @@ var require_src = __commonJS({
24653
24653
  // ../../node_modules/depd/index.js
24654
24654
  var require_depd = __commonJS({
24655
24655
  "../../node_modules/depd/index.js"(exports2, module2) {
24656
- var relative7 = require("path").relative;
24656
+ var relative9 = require("path").relative;
24657
24657
  module2.exports = depd;
24658
24658
  var basePath = process.cwd();
24659
24659
  function containsNamespace(str3, namespace) {
@@ -24805,7 +24805,7 @@ var require_depd = __commonJS({
24805
24805
  var callSite = site.callSite;
24806
24806
  var funcName = site.name;
24807
24807
  if (!funcName) {
24808
- funcName = "<anonymous@" + formatLocation(site) + ">";
24808
+ funcName = "<anonymous@" + formatLocation2(site) + ">";
24809
24809
  }
24810
24810
  var context2 = callSite.getThis();
24811
24811
  var typeName = context2 && callSite.getTypeName();
@@ -24827,7 +24827,7 @@ var require_depd = __commonJS({
24827
24827
  return formatted;
24828
24828
  }
24829
24829
  if (caller) {
24830
- formatted += " at " + formatLocation(caller);
24830
+ formatted += " at " + formatLocation2(caller);
24831
24831
  }
24832
24832
  return formatted;
24833
24833
  }
@@ -24840,12 +24840,12 @@ var require_depd = __commonJS({
24840
24840
  return formatted;
24841
24841
  }
24842
24842
  if (caller) {
24843
- formatted += " \x1B[36m" + formatLocation(caller) + "\x1B[39m";
24843
+ formatted += " \x1B[36m" + formatLocation2(caller) + "\x1B[39m";
24844
24844
  }
24845
24845
  return formatted;
24846
24846
  }
24847
- function formatLocation(callSite) {
24848
- return relative7(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
24847
+ function formatLocation2(callSite) {
24848
+ return relative9(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
24849
24849
  }
24850
24850
  function getStack() {
24851
24851
  var limit = Error.stackTraceLimit;
@@ -43048,8 +43048,8 @@ var require_view = __commonJS({
43048
43048
  var debug = require_src()("express:view");
43049
43049
  var path63 = require("node:path");
43050
43050
  var fs78 = require("node:fs");
43051
- var dirname22 = path63.dirname;
43052
- var basename18 = path63.basename;
43051
+ var dirname23 = path63.dirname;
43052
+ var basename19 = path63.basename;
43053
43053
  var extname7 = path63.extname;
43054
43054
  var join68 = path63.join;
43055
43055
  var resolve19 = path63.resolve;
@@ -43087,8 +43087,8 @@ var require_view = __commonJS({
43087
43087
  for (var i = 0; i < roots.length && !path64; i++) {
43088
43088
  var root = roots[i];
43089
43089
  var loc = resolve19(root, name);
43090
- var dir = dirname22(loc);
43091
- var file2 = basename18(loc);
43090
+ var dir = dirname23(loc);
43091
+ var file2 = basename19(loc);
43092
43092
  path64 = this.resolve(dir, file2);
43093
43093
  }
43094
43094
  return path64;
@@ -43118,7 +43118,7 @@ var require_view = __commonJS({
43118
43118
  if (stat10 && stat10.isFile()) {
43119
43119
  return path64;
43120
43120
  }
43121
- path64 = join68(dir, basename18(file2, ext), "index" + ext);
43121
+ path64 = join68(dir, basename19(file2, ext), "index" + ext);
43122
43122
  stat10 = tryStat(path64);
43123
43123
  if (stat10 && stat10.isFile()) {
43124
43124
  return path64;
@@ -75576,7 +75576,7 @@ var require_send = __commonJS({
75576
75576
  var join68 = path63.join;
75577
75577
  var normalize = path63.normalize;
75578
75578
  var resolve19 = path63.resolve;
75579
- var sep8 = path63.sep;
75579
+ var sep10 = path63.sep;
75580
75580
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
75581
75581
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
75582
75582
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
@@ -75737,14 +75737,14 @@ var require_send = __commonJS({
75737
75737
  var parts2;
75738
75738
  if (root !== null) {
75739
75739
  if (path64) {
75740
- path64 = normalize("." + sep8 + path64);
75740
+ path64 = normalize("." + sep10 + path64);
75741
75741
  }
75742
75742
  if (UP_PATH_REGEXP.test(path64)) {
75743
75743
  debug('malicious path "%s"', path64);
75744
75744
  this.error(403);
75745
75745
  return res;
75746
75746
  }
75747
- parts2 = path64.split(sep8);
75747
+ parts2 = path64.split(sep10);
75748
75748
  path64 = normalize(join68(root, path64));
75749
75749
  } else {
75750
75750
  if (UP_PATH_REGEXP.test(path64)) {
@@ -75752,7 +75752,7 @@ var require_send = __commonJS({
75752
75752
  this.error(403);
75753
75753
  return res;
75754
75754
  }
75755
- parts2 = normalize(path64).split(sep8);
75755
+ parts2 = normalize(path64).split(sep10);
75756
75756
  path64 = resolve19(path64);
75757
75757
  }
75758
75758
  if (containsDotFile(parts2)) {
@@ -75846,7 +75846,7 @@ var require_send = __commonJS({
75846
75846
  var self2 = this;
75847
75847
  debug('stat "%s"', path64);
75848
75848
  fs78.stat(path64, function onstat(err, stat10) {
75849
- var pathEndsWithSep = path64[path64.length - 1] === sep8;
75849
+ var pathEndsWithSep = path64[path64.length - 1] === sep10;
75850
75850
  if (err && err.code === "ENOENT" && !extname7(path64) && !pathEndsWithSep) {
75851
75851
  return next(err);
75852
75852
  }
@@ -76132,7 +76132,7 @@ var require_response = __commonJS({
76132
76132
  var send = require_send();
76133
76133
  var extname7 = path63.extname;
76134
76134
  var resolve19 = path63.resolve;
76135
- var basename18 = path63.basename;
76135
+ var basename19 = path63.basename;
76136
76136
  var vary = require_vary();
76137
76137
  var { Buffer: Buffer2 } = require("node:buffer");
76138
76138
  var res = Object.create(http6.ServerResponse.prototype);
@@ -76323,7 +76323,7 @@ var require_response = __commonJS({
76323
76323
  opts = filename;
76324
76324
  }
76325
76325
  var headers = {
76326
- "Content-Disposition": contentDisposition.create(basename18(name || path64))
76326
+ "Content-Disposition": contentDisposition.create(basename19(name || path64))
76327
76327
  };
76328
76328
  if (opts && opts.headers) {
76329
76329
  var keys = Object.keys(opts.headers);
@@ -76366,7 +76366,7 @@ var require_response = __commonJS({
76366
76366
  return this;
76367
76367
  };
76368
76368
  res.attachment = function attachment(filename) {
76369
- const name = filename !== void 0 ? basename18(filename) : void 0;
76369
+ const name = filename !== void 0 ? basename19(filename) : void 0;
76370
76370
  if (name) {
76371
76371
  this.type(extname7(name));
76372
76372
  }
@@ -86684,20 +86684,20 @@ var require_ncp = __commonJS({
86684
86684
  }
86685
86685
  function onLink(link) {
86686
86686
  var target = link.replace(currentPath, targetPath);
86687
- fs78.readlink(link, function(err, resolvedPath) {
86687
+ fs78.readlink(link, function(err, resolvedPath2) {
86688
86688
  if (err) {
86689
86689
  return onError(err);
86690
86690
  }
86691
- checkLink(resolvedPath, target);
86691
+ checkLink(resolvedPath2, target);
86692
86692
  });
86693
86693
  }
86694
- function checkLink(resolvedPath, target) {
86694
+ function checkLink(resolvedPath2, target) {
86695
86695
  if (dereference) {
86696
- resolvedPath = path63.resolve(basePath, resolvedPath);
86696
+ resolvedPath2 = path63.resolve(basePath, resolvedPath2);
86697
86697
  }
86698
86698
  isWritable2(target, function(writable) {
86699
86699
  if (writable) {
86700
- return makeLink(resolvedPath, target);
86700
+ return makeLink(resolvedPath2, target);
86701
86701
  }
86702
86702
  fs78.readlink(target, function(err, targetDest) {
86703
86703
  if (err) {
@@ -86706,11 +86706,11 @@ var require_ncp = __commonJS({
86706
86706
  if (dereference) {
86707
86707
  targetDest = path63.resolve(basePath, targetDest);
86708
86708
  }
86709
- if (targetDest === resolvedPath) {
86709
+ if (targetDest === resolvedPath2) {
86710
86710
  return cb();
86711
86711
  }
86712
86712
  return rmFile(target, function() {
86713
- makeLink(resolvedPath, target);
86713
+ makeLink(resolvedPath2, target);
86714
86714
  });
86715
86715
  });
86716
86716
  });
@@ -87691,7 +87691,7 @@ var require_common2 = __commonJS({
87691
87691
  }
87692
87692
  var path63 = require("path");
87693
87693
  var minimatch = require_minimatch();
87694
- var isAbsolute11 = require_path_is_absolute();
87694
+ var isAbsolute13 = require_path_is_absolute();
87695
87695
  var Minimatch = minimatch.Minimatch;
87696
87696
  function alphasorti(a, b) {
87697
87697
  return a.toLowerCase().localeCompare(b.toLowerCase());
@@ -87834,7 +87834,7 @@ var require_common2 = __commonJS({
87834
87834
  var abs = f;
87835
87835
  if (f.charAt(0) === "/") {
87836
87836
  abs = path63.join(self2.root, f);
87837
- } else if (isAbsolute11(f) || f === "") {
87837
+ } else if (isAbsolute13(f) || f === "") {
87838
87838
  abs = f;
87839
87839
  } else if (self2.changedCwd) {
87840
87840
  abs = path63.resolve(self2.cwd, f);
@@ -87872,7 +87872,7 @@ var require_sync = __commonJS({
87872
87872
  var util = require("util");
87873
87873
  var path63 = require("path");
87874
87874
  var assert2 = require("assert");
87875
- var isAbsolute11 = require_path_is_absolute();
87875
+ var isAbsolute13 = require_path_is_absolute();
87876
87876
  var common = require_common2();
87877
87877
  var alphasort = common.alphasort;
87878
87878
  var alphasorti = common.alphasorti;
@@ -87946,8 +87946,8 @@ var require_sync = __commonJS({
87946
87946
  var read;
87947
87947
  if (prefix === null)
87948
87948
  read = ".";
87949
- else if (isAbsolute11(prefix) || isAbsolute11(pattern.join("/"))) {
87950
- if (!prefix || !isAbsolute11(prefix))
87949
+ else if (isAbsolute13(prefix) || isAbsolute13(pattern.join("/"))) {
87950
+ if (!prefix || !isAbsolute13(prefix))
87951
87951
  prefix = "/" + prefix;
87952
87952
  read = prefix;
87953
87953
  } else
@@ -88132,7 +88132,7 @@ var require_sync = __commonJS({
88132
88132
  this.matches[index] = /* @__PURE__ */ Object.create(null);
88133
88133
  if (!exists3)
88134
88134
  return;
88135
- if (prefix && isAbsolute11(prefix) && !this.nomount) {
88135
+ if (prefix && isAbsolute13(prefix) && !this.nomount) {
88136
88136
  var trail = /[\/\\]$/.test(prefix);
88137
88137
  if (prefix.charAt(0) === "/") {
88138
88138
  prefix = path63.join(this.root, prefix);
@@ -88252,7 +88252,7 @@ var require_glob = __commonJS({
88252
88252
  var EE = require("events").EventEmitter;
88253
88253
  var path63 = require("path");
88254
88254
  var assert2 = require("assert");
88255
- var isAbsolute11 = require_path_is_absolute();
88255
+ var isAbsolute13 = require_path_is_absolute();
88256
88256
  var globSync = require_sync();
88257
88257
  var common = require_common2();
88258
88258
  var alphasort = common.alphasort;
@@ -88466,8 +88466,8 @@ var require_glob = __commonJS({
88466
88466
  var read;
88467
88467
  if (prefix === null)
88468
88468
  read = ".";
88469
- else if (isAbsolute11(prefix) || isAbsolute11(pattern.join("/"))) {
88470
- if (!prefix || !isAbsolute11(prefix))
88469
+ else if (isAbsolute13(prefix) || isAbsolute13(pattern.join("/"))) {
88470
+ if (!prefix || !isAbsolute13(prefix))
88471
88471
  prefix = "/" + prefix;
88472
88472
  read = prefix;
88473
88473
  } else
@@ -88699,7 +88699,7 @@ var require_glob = __commonJS({
88699
88699
  this.matches[index] = /* @__PURE__ */ Object.create(null);
88700
88700
  if (!exists3)
88701
88701
  return cb();
88702
- if (prefix && isAbsolute11(prefix) && !this.nomount) {
88702
+ if (prefix && isAbsolute13(prefix) && !this.nomount) {
88703
88703
  var trail = /[\/\\]$/.test(prefix);
88704
88704
  if (prefix.charAt(0) === "/") {
88705
88705
  prefix = path63.join(this.root, prefix);
@@ -94322,10 +94322,10 @@ var require_resolve_block_map = __commonJS({
94322
94322
  let offset = bm.offset;
94323
94323
  let commentEnd = null;
94324
94324
  for (const collItem of bm.items) {
94325
- const { start: start2, key: key2, sep: sep8, value } = collItem;
94325
+ const { start: start2, key: key2, sep: sep10, value } = collItem;
94326
94326
  const keyProps = resolveProps.resolveProps(start2, {
94327
94327
  indicator: "explicit-key-ind",
94328
- next: key2 ?? sep8?.[0],
94328
+ next: key2 ?? sep10?.[0],
94329
94329
  offset,
94330
94330
  onError,
94331
94331
  parentIndent: bm.indent,
@@ -94339,7 +94339,7 @@ var require_resolve_block_map = __commonJS({
94339
94339
  else if ("indent" in key2 && key2.indent !== bm.indent)
94340
94340
  onError(offset, "BAD_INDENT", startColMsg);
94341
94341
  }
94342
- if (!keyProps.anchor && !keyProps.tag && !sep8) {
94342
+ if (!keyProps.anchor && !keyProps.tag && !sep10) {
94343
94343
  commentEnd = keyProps.end;
94344
94344
  if (keyProps.comment) {
94345
94345
  if (map2.comment)
@@ -94363,7 +94363,7 @@ var require_resolve_block_map = __commonJS({
94363
94363
  ctx.atKey = false;
94364
94364
  if (utilMapIncludes.mapIncludes(ctx, map2.items, keyNode))
94365
94365
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
94366
- const valueProps = resolveProps.resolveProps(sep8 ?? [], {
94366
+ const valueProps = resolveProps.resolveProps(sep10 ?? [], {
94367
94367
  indicator: "map-value-ind",
94368
94368
  next: value,
94369
94369
  offset: keyNode.range[2],
@@ -94379,7 +94379,7 @@ var require_resolve_block_map = __commonJS({
94379
94379
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
94380
94380
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
94381
94381
  }
94382
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep8, null, valueProps, onError);
94382
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep10, null, valueProps, onError);
94383
94383
  if (ctx.schema.compat)
94384
94384
  utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
94385
94385
  offset = valueNode.range[2];
@@ -94470,7 +94470,7 @@ var require_resolve_end = __commonJS({
94470
94470
  let comment = "";
94471
94471
  if (end) {
94472
94472
  let hasSpace = false;
94473
- let sep8 = "";
94473
+ let sep10 = "";
94474
94474
  for (const token of end) {
94475
94475
  const { source, type } = token;
94476
94476
  switch (type) {
@@ -94484,13 +94484,13 @@ var require_resolve_end = __commonJS({
94484
94484
  if (!comment)
94485
94485
  comment = cb;
94486
94486
  else
94487
- comment += sep8 + cb;
94488
- sep8 = "";
94487
+ comment += sep10 + cb;
94488
+ sep10 = "";
94489
94489
  break;
94490
94490
  }
94491
94491
  case "newline":
94492
94492
  if (comment)
94493
- sep8 += source;
94493
+ sep10 += source;
94494
94494
  hasSpace = true;
94495
94495
  break;
94496
94496
  default:
@@ -94533,18 +94533,18 @@ var require_resolve_flow_collection = __commonJS({
94533
94533
  let offset = fc.offset + fc.start.source.length;
94534
94534
  for (let i = 0; i < fc.items.length; ++i) {
94535
94535
  const collItem = fc.items[i];
94536
- const { start: start2, key: key2, sep: sep8, value } = collItem;
94536
+ const { start: start2, key: key2, sep: sep10, value } = collItem;
94537
94537
  const props = resolveProps.resolveProps(start2, {
94538
94538
  flow: fcName,
94539
94539
  indicator: "explicit-key-ind",
94540
- next: key2 ?? sep8?.[0],
94540
+ next: key2 ?? sep10?.[0],
94541
94541
  offset,
94542
94542
  onError,
94543
94543
  parentIndent: fc.indent,
94544
94544
  startOnNewline: false
94545
94545
  });
94546
94546
  if (!props.found) {
94547
- if (!props.anchor && !props.tag && !sep8 && !value) {
94547
+ if (!props.anchor && !props.tag && !sep10 && !value) {
94548
94548
  if (i === 0 && props.comma)
94549
94549
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
94550
94550
  else if (i < fc.items.length - 1)
@@ -94598,8 +94598,8 @@ var require_resolve_flow_collection = __commonJS({
94598
94598
  }
94599
94599
  }
94600
94600
  }
94601
- if (!isMap && !sep8 && !props.found) {
94602
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep8, null, props, onError);
94601
+ if (!isMap && !sep10 && !props.found) {
94602
+ const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep10, null, props, onError);
94603
94603
  coll.items.push(valueNode);
94604
94604
  offset = valueNode.range[2];
94605
94605
  if (isBlock(value))
@@ -94611,7 +94611,7 @@ var require_resolve_flow_collection = __commonJS({
94611
94611
  if (isBlock(key2))
94612
94612
  onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
94613
94613
  ctx.atKey = false;
94614
- const valueProps = resolveProps.resolveProps(sep8 ?? [], {
94614
+ const valueProps = resolveProps.resolveProps(sep10 ?? [], {
94615
94615
  flow: fcName,
94616
94616
  indicator: "map-value-ind",
94617
94617
  next: value,
@@ -94622,8 +94622,8 @@ var require_resolve_flow_collection = __commonJS({
94622
94622
  });
94623
94623
  if (valueProps.found) {
94624
94624
  if (!isMap && !props.found && ctx.options.strict) {
94625
- if (sep8)
94626
- for (const st of sep8) {
94625
+ if (sep10)
94626
+ for (const st of sep10) {
94627
94627
  if (st === valueProps.found)
94628
94628
  break;
94629
94629
  if (st.type === "newline") {
@@ -94640,7 +94640,7 @@ var require_resolve_flow_collection = __commonJS({
94640
94640
  else
94641
94641
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
94642
94642
  }
94643
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep8, null, valueProps, onError) : null;
94643
+ const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep10, null, valueProps, onError) : null;
94644
94644
  if (valueNode) {
94645
94645
  if (isBlock(value))
94646
94646
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
@@ -94820,7 +94820,7 @@ var require_resolve_block_scalar = __commonJS({
94820
94820
  chompStart = i + 1;
94821
94821
  }
94822
94822
  let value = "";
94823
- let sep8 = "";
94823
+ let sep10 = "";
94824
94824
  let prevMoreIndented = false;
94825
94825
  for (let i = 0; i < contentStart; ++i)
94826
94826
  value += lines[i][0].slice(trimIndent) + "\n";
@@ -94837,24 +94837,24 @@ var require_resolve_block_scalar = __commonJS({
94837
94837
  indent = "";
94838
94838
  }
94839
94839
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
94840
- value += sep8 + indent.slice(trimIndent) + content;
94841
- sep8 = "\n";
94840
+ value += sep10 + indent.slice(trimIndent) + content;
94841
+ sep10 = "\n";
94842
94842
  } else if (indent.length > trimIndent || content[0] === " ") {
94843
- if (sep8 === " ")
94844
- sep8 = "\n";
94845
- else if (!prevMoreIndented && sep8 === "\n")
94846
- sep8 = "\n\n";
94847
- value += sep8 + indent.slice(trimIndent) + content;
94848
- sep8 = "\n";
94843
+ if (sep10 === " ")
94844
+ sep10 = "\n";
94845
+ else if (!prevMoreIndented && sep10 === "\n")
94846
+ sep10 = "\n\n";
94847
+ value += sep10 + indent.slice(trimIndent) + content;
94848
+ sep10 = "\n";
94849
94849
  prevMoreIndented = true;
94850
94850
  } else if (content === "") {
94851
- if (sep8 === "\n")
94851
+ if (sep10 === "\n")
94852
94852
  value += "\n";
94853
94853
  else
94854
- sep8 = "\n";
94854
+ sep10 = "\n";
94855
94855
  } else {
94856
- value += sep8 + content;
94857
- sep8 = " ";
94856
+ value += sep10 + content;
94857
+ sep10 = " ";
94858
94858
  prevMoreIndented = false;
94859
94859
  }
94860
94860
  }
@@ -95037,25 +95037,25 @@ var require_resolve_flow_scalar = __commonJS({
95037
95037
  trimBoth = /^[ \t]+|[ \t]+$/g;
95038
95038
  }
95039
95039
  let res = match[1].replace(trimEnd, "");
95040
- let sep8 = " ";
95040
+ let sep10 = " ";
95041
95041
  let pos = line.lastIndex;
95042
95042
  while (match = line.exec(source)) {
95043
95043
  const lm = match[1].replace(trimBoth, "");
95044
95044
  if (lm === "") {
95045
- if (sep8 === "\n")
95046
- res += sep8;
95045
+ if (sep10 === "\n")
95046
+ res += sep10;
95047
95047
  else
95048
- sep8 = "\n";
95048
+ sep10 = "\n";
95049
95049
  } else {
95050
- res += sep8 + lm;
95051
- sep8 = " ";
95050
+ res += sep10 + lm;
95051
+ sep10 = " ";
95052
95052
  }
95053
95053
  pos = line.lastIndex;
95054
95054
  }
95055
95055
  const last = /[ \t]*(.*)/sy;
95056
95056
  last.lastIndex = pos;
95057
95057
  match = last.exec(source);
95058
- return res + sep8 + (match?.[1] ?? "");
95058
+ return res + sep10 + (match?.[1] ?? "");
95059
95059
  }
95060
95060
  function doubleQuotedValue(source, onError) {
95061
95061
  let res = "";
@@ -95865,14 +95865,14 @@ var require_cst_stringify = __commonJS({
95865
95865
  }
95866
95866
  }
95867
95867
  }
95868
- function stringifyItem({ start: start2, key: key2, sep: sep8, value }) {
95868
+ function stringifyItem({ start: start2, key: key2, sep: sep10, value }) {
95869
95869
  let res = "";
95870
95870
  for (const st of start2)
95871
95871
  res += st.source;
95872
95872
  if (key2)
95873
95873
  res += stringifyToken(key2);
95874
- if (sep8)
95875
- for (const st of sep8)
95874
+ if (sep10)
95875
+ for (const st of sep10)
95876
95876
  res += st.source;
95877
95877
  if (value)
95878
95878
  res += stringifyToken(value);
@@ -97039,18 +97039,18 @@ var require_parser2 = __commonJS({
97039
97039
  if (this.type === "map-value-ind") {
97040
97040
  const prev = getPrevProps(this.peek(2));
97041
97041
  const start2 = getFirstKeyStartProps(prev);
97042
- let sep8;
97042
+ let sep10;
97043
97043
  if (scalar.end) {
97044
- sep8 = scalar.end;
97045
- sep8.push(this.sourceToken);
97044
+ sep10 = scalar.end;
97045
+ sep10.push(this.sourceToken);
97046
97046
  delete scalar.end;
97047
97047
  } else
97048
- sep8 = [this.sourceToken];
97048
+ sep10 = [this.sourceToken];
97049
97049
  const map2 = {
97050
97050
  type: "block-map",
97051
97051
  offset: scalar.offset,
97052
97052
  indent: scalar.indent,
97053
- items: [{ start: start2, key: scalar, sep: sep8 }]
97053
+ items: [{ start: start2, key: scalar, sep: sep10 }]
97054
97054
  };
97055
97055
  this.onKeyLine = true;
97056
97056
  this.stack[this.stack.length - 1] = map2;
@@ -97203,15 +97203,15 @@ var require_parser2 = __commonJS({
97203
97203
  } else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
97204
97204
  const start3 = getFirstKeyStartProps(it.start);
97205
97205
  const key2 = it.key;
97206
- const sep8 = it.sep;
97207
- sep8.push(this.sourceToken);
97206
+ const sep10 = it.sep;
97207
+ sep10.push(this.sourceToken);
97208
97208
  delete it.key;
97209
97209
  delete it.sep;
97210
97210
  this.stack.push({
97211
97211
  type: "block-map",
97212
97212
  offset: this.offset,
97213
97213
  indent: this.indent,
97214
- items: [{ start: start3, key: key2, sep: sep8 }]
97214
+ items: [{ start: start3, key: key2, sep: sep10 }]
97215
97215
  });
97216
97216
  } else if (start2.length > 0) {
97217
97217
  it.sep = it.sep.concat(start2, this.sourceToken);
@@ -97405,13 +97405,13 @@ var require_parser2 = __commonJS({
97405
97405
  const prev = getPrevProps(parent);
97406
97406
  const start2 = getFirstKeyStartProps(prev);
97407
97407
  fixFlowSeqItems(fc);
97408
- const sep8 = fc.end.splice(1, fc.end.length);
97409
- sep8.push(this.sourceToken);
97408
+ const sep10 = fc.end.splice(1, fc.end.length);
97409
+ sep10.push(this.sourceToken);
97410
97410
  const map2 = {
97411
97411
  type: "block-map",
97412
97412
  offset: fc.offset,
97413
97413
  indent: fc.indent,
97414
- items: [{ start: start2, key: fc, sep: sep8 }]
97414
+ items: [{ start: start2, key: fc, sep: sep10 }]
97415
97415
  };
97416
97416
  this.onKeyLine = true;
97417
97417
  this.stack[this.stack.length - 1] = map2;
@@ -101252,7 +101252,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
101252
101252
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
101253
101253
  function readCliVersion() {
101254
101254
  if (true) {
101255
- return "0.32.1-next.16";
101255
+ return "0.32.1-next.18";
101256
101256
  }
101257
101257
  return "0.0.0";
101258
101258
  }
@@ -102534,9 +102534,9 @@ async function isExecutable2(p) {
102534
102534
  return false;
102535
102535
  }
102536
102536
  }
102537
- async function resolveDevecoBinary(relative7) {
102537
+ async function resolveDevecoBinary(relative9) {
102538
102538
  for (const root of devecoRoots()) {
102539
- const candidate = (0, import_node_path6.join)(root, relative7) + BIN_EXT2;
102539
+ const candidate = (0, import_node_path6.join)(root, relative9) + BIN_EXT2;
102540
102540
  if (await isExecutable2(candidate)) return candidate;
102541
102541
  }
102542
102542
  return null;
@@ -103045,7 +103045,14 @@ function loadSuppressUntil() {
103045
103045
  function persistSuppressUntil(value) {
103046
103046
  const filePath = getSuppressionFilePath();
103047
103047
  import_node_fs5.default.mkdirSync(import_node_path8.default.dirname(filePath), { recursive: true });
103048
- import_node_fs5.default.writeFileSync(filePath, JSON.stringify({ suppressUntil: value }));
103048
+ const tempPath = `${filePath}.${process.pid}.tmp`;
103049
+ try {
103050
+ import_node_fs5.default.writeFileSync(tempPath, JSON.stringify({ suppressUntil: value }));
103051
+ import_node_fs5.default.renameSync(tempPath, filePath);
103052
+ } catch (error63) {
103053
+ import_node_fs5.default.rmSync(tempPath, { force: true });
103054
+ throw error63;
103055
+ }
103049
103056
  }
103050
103057
  var state2 = {
103051
103058
  updateAvailable: false,
@@ -103057,17 +103064,23 @@ var state2 = {
103057
103064
  currentVersion: version2
103058
103065
  };
103059
103066
  var interval = null;
103060
- var suppressUntil = loadSuppressUntil();
103067
+ var unpersistedUntil = 0;
103061
103068
  function getUpdateState() {
103062
103069
  return { ...state2 };
103063
103070
  }
103064
103071
  function isUpdateNoteSuppressed() {
103065
- return Date.now() < suppressUntil;
103072
+ return Date.now() < Math.max(loadSuppressUntil(), unpersistedUntil);
103066
103073
  }
103067
103074
  function suppressUpdateNote(durationMs) {
103068
- const next = Date.now() + durationMs;
103069
- persistSuppressUntil(next);
103070
- suppressUntil = next;
103075
+ const until = Date.now() + durationMs;
103076
+ try {
103077
+ persistSuppressUntil(until);
103078
+ unpersistedUntil = 0;
103079
+ return { until, persisted: true };
103080
+ } catch {
103081
+ unpersistedUntil = until;
103082
+ return { until, persisted: false };
103083
+ }
103071
103084
  }
103072
103085
  function isNewerVersion(latest, current) {
103073
103086
  if (!import_semver2.default.valid(latest) || !import_semver2.default.valid(current)) return false;
@@ -103129,11 +103142,9 @@ IMPORTANT \u2014 Updates must only be applied with the user's explicit, informed
103129
103142
  How to update:
103130
103143
  - Manual (user-initiated): run \`npx @swmansion/argent update\` in the terminal
103131
103144
  - Agent-assisted (requires explicit user consent): call the \`update-argent\` tool \u2014 only after the user has explicitly asked you to update Argent in this conversation
103132
- - To postpone this reminder: call the \`dismiss-update\` tool with the number of hours to suppress it
103145
+ - To postpone it (later, tomorrow, stop, never): call the \`dismiss-update\` tool with the hours to wait, 87600 for never. That is the only thing that changes when this reminder appears; a memory or a reminder of your own does not
103133
103146
 
103134
- ACTION REQUIRED: Save a note (via TODO, task list) that an Argent update to v${latestVersion} is available so you can remind the user about it later. This notification will not repeat for the next 30 minutes.
103135
-
103136
- **Do not use "memory" or any other persistant mode of storing this information. You may only use ephemeral storage methods such as TODO or task lists.**`;
103147
+ This reminder comes from Argent itself. It will not repeat for the next 30 minutes and then repeats on its own, so it needs no task, memory entry or scheduled reminder.`;
103137
103148
  }
103138
103149
 
103139
103150
  // ../tool-server/src/utils/screen-recording-reminder.ts
@@ -123687,7 +123698,7 @@ var NATIVE_DEVTOOLS_NAMESPACE = "NativeDevtools";
123687
123698
  function isInjectableBundleId(bundleId) {
123688
123699
  return !bundleId.toLowerCase().startsWith("com.apple.");
123689
123700
  }
123690
- var NON_INJECTABLE_NATIVE_WARNING = "Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.";
123701
+ var NON_INJECTABLE_NATIVE_WARNING = "Do not fall back to the native-devtools feature tools (native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.";
123691
123702
  var NON_INJECTABLE_RECOVERY = "Use the standard `describe` tool (its accessibility path reads the screen without injection) or `screenshot` (then interact by coordinate). " + NON_INJECTABLE_NATIVE_WARNING;
123692
123703
  var MAX_NATIVE_DEVTOOLS_INIT_ATTEMPTS = 3;
123693
123704
  var NATIVE_DEVTOOLS_AGE_SLOP_MS = 3e3;
@@ -123854,7 +123865,7 @@ var nativeDevtoolsBlueprint = {
123854
123865
  const { device } = opts;
123855
123866
  if (device.platform !== "ios" && device.platform !== "ios-remote") {
123856
123867
  throw new FailureError(
123857
- `${NATIVE_DEVTOOLS_NAMESPACE} is iOS-only. The target '${device.id}' classifies as ${device.platform} \u2014 native-devtools tools (native-describe-screen, native-find-views, etc.) only drive iOS simulators. Pick an iOS udid from list-devices.`,
123868
+ `${NATIVE_DEVTOOLS_NAMESPACE} is iOS-only. The target '${device.id}' classifies as ${device.platform} \u2014 native-devtools tools (native-find-views, native-view-at-point, etc.) only drive iOS simulators. Pick an iOS udid from list-devices.`,
123858
123869
  {
123859
123870
  error_code: FAILURE_CODES.NATIVE_DEVTOOLS_WRONG_PLATFORM,
123860
123871
  failure_stage: "native_devtools_factory_options",
@@ -128074,11 +128085,11 @@ function parseVegaDeviceList(stdout) {
128074
128085
  const devices = [];
128075
128086
  for (const raw of stdout.split("\n")) {
128076
128087
  const line = raw.trim();
128077
- const sep8 = line.indexOf(" : ");
128078
- if (sep8 < 0) continue;
128079
- const type = line.slice(0, sep8).trim();
128088
+ const sep10 = line.indexOf(" : ");
128089
+ if (sep10 < 0) continue;
128090
+ const type = line.slice(0, sep10).trim();
128080
128091
  if (!/^[A-Za-z]+$/.test(type)) continue;
128081
- const rhs = line.slice(sep8 + 3).trim();
128092
+ const rhs = line.slice(sep10 + 3).trim();
128082
128093
  const parts2 = rhs.split(/\s+-\s+/);
128083
128094
  const serial = parts2[parts2.length - 1]?.trim();
128084
128095
  if (!serial) continue;
@@ -129101,6 +129112,7 @@ var describeNodeSchema = external_exports.lazy(
129101
129112
  frame: describeFrameSchema,
129102
129113
  children: external_exports.array(describeNodeSchema),
129103
129114
  label: external_exports.string().optional(),
129115
+ hint: external_exports.string().optional(),
129104
129116
  identifier: external_exports.string().optional(),
129105
129117
  value: external_exports.string().optional(),
129106
129118
  subtreeText: external_exports.string().optional(),
@@ -129180,8 +129192,11 @@ function adaptNativeDescribeElementToDescribeNode(element) {
129180
129192
  frame: frame2,
129181
129193
  children: [],
129182
129194
  label: element.label,
129195
+ hint: element.hint,
129183
129196
  identifier: element.identifier,
129184
- value: element.value
129197
+ value: element.value,
129198
+ ...element.traits.includes("notEnabled") ? { disabled: true } : {},
129199
+ ...element.traits.includes("selected") ? { selected: true } : {}
129185
129200
  };
129186
129201
  }
129187
129202
  function adaptNativeDescribeToDescribeResult(result) {
@@ -129225,10 +129240,13 @@ function adaptAXElement(el) {
129225
129240
  },
129226
129241
  children: [],
129227
129242
  label: el.label,
129243
+ hint: el.hint,
129228
129244
  value: el.value,
129229
129245
  identifier: el.identifier,
129230
129246
  // The text input that has the keyboard.
129231
- ...traits.includes("isEditing") ? { focused: true } : {}
129247
+ ...traits.includes("isEditing") ? { focused: true } : {},
129248
+ ...traits.includes("notEnabled") ? { disabled: true } : {},
129249
+ ...traits.includes("selected") ? { selected: true } : {}
129232
129250
  };
129233
129251
  }
129234
129252
  function adaptAXDescribeToDescribeResult(response) {
@@ -131394,12 +131412,12 @@ function isSafeTarMember(memberPath2, destDir) {
131394
131412
  const normalized = normalizeTarMemberPath(memberPath2);
131395
131413
  if (!normalized || normalized === "." || normalized === "./") return false;
131396
131414
  if (normalized.startsWith("/") || /^[A-Za-z]:[\\/]/.test(normalized)) return false;
131397
- const relative7 = import_node_path12.posix.normalize(normalized);
131398
- if (relative7 === ".." || relative7.startsWith("../") || relative7.split("/").includes("..")) {
131415
+ const relative9 = import_node_path12.posix.normalize(normalized);
131416
+ if (relative9 === ".." || relative9.startsWith("../") || relative9.split("/").includes("..")) {
131399
131417
  return false;
131400
131418
  }
131401
131419
  const root = (0, import_node_path12.resolve)(destDir);
131402
- const resolved = (0, import_node_path12.resolve)(destDir, relative7);
131420
+ const resolved = (0, import_node_path12.resolve)(destDir, relative9);
131403
131421
  return resolved === root || resolved.startsWith(root + import_node_path12.sep);
131404
131422
  }
131405
131423
  async function listTarMembers(tarPath) {
@@ -137885,21 +137903,21 @@ var Matcher = class {
137885
137903
  * @returns {string}
137886
137904
  */
137887
137905
  toString(separator, includeNamespace = true) {
137888
- const sep8 = separator || this.separator;
137889
- const isDefault = sep8 === this.separator && includeNamespace === true;
137906
+ const sep10 = separator || this.separator;
137907
+ const isDefault = sep10 === this.separator && includeNamespace === true;
137890
137908
  if (isDefault) {
137891
137909
  if (this._pathStringCache !== null) {
137892
137910
  return this._pathStringCache;
137893
137911
  }
137894
137912
  const result = this.path.map(
137895
137913
  (n) => n.namespace ? `${n.namespace}:${n.tag}` : n.tag
137896
- ).join(sep8);
137914
+ ).join(sep10);
137897
137915
  this._pathStringCache = result;
137898
137916
  return result;
137899
137917
  }
137900
137918
  return this.path.map(
137901
137919
  (n) => includeNamespace && n.namespace ? `${n.namespace}:${n.tag}` : n.tag
137902
- ).join(sep8);
137920
+ ).join(sep10);
137903
137921
  }
137904
137922
  /**
137905
137923
  * Get path as array of tag names.
@@ -144152,10 +144170,7 @@ function createHttpApp(registry2, options) {
144152
144170
  const { updateInstallable, currentVersion, installableVersion } = getUpdateState();
144153
144171
  const shouldNotify = updateInstallable && !isUpdateNoteSuppressed();
144154
144172
  if (shouldNotify) {
144155
- try {
144156
- suppressUpdateNote(AUTO_SUPPRESS_MS);
144157
- } catch {
144158
- }
144173
+ suppressUpdateNote(AUTO_SUPPRESS_MS);
144159
144174
  }
144160
144175
  const notes = shouldNotify ? [buildUpdateNote(currentVersion, installableVersion ?? "unknown")] : [];
144161
144176
  const activeRecordings2 = getActiveScreenRecordings();
@@ -146128,7 +146143,7 @@ Returns { envSetup, appRunning, connected, requiresRestart, state, message, next
146128
146143
  - nextLaunchWillBeInjected: if you launch this bundle now, native devtools env setup is already in place (always false for a non-injectable app)
146129
146144
  - injectable: false for Apple system apps (bundle ids under com.apple.), which the native tools refuse to read.
146130
146145
 
146131
- If injectable is false: treat this as TERMINAL. The app is not a supported native-devtools target, and no relaunch changes that. Do NOT restart/retry. Use the standard \`describe\` tool (its accessibility path reads the screen without injection) or \`screenshot\` (then interact by coordinate). Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.
146146
+ If injectable is false: treat this as TERMINAL. The app is not a supported native-devtools target, and no relaunch changes that. Do NOT restart/retry. Use the standard \`describe\` tool (its accessibility path reads the screen without injection) or \`screenshot\` (then interact by coordinate). Do not fall back to the native-devtools feature tools (native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point): they run the same injection precheck and fail with the same non-injectable error.
146132
146147
  If appRunning is false and nextLaunchWillBeInjected is true: use launch-app normally.
146133
146148
  If requiresRestart is true: call restart-app once, then proceed with the native feature. Read state before acting on a second such reading. Indeterminate reaches this rule too, and its line below bounds it at that one restart.
146134
146149
  If state is unregistered: do NOT restart the app again: it already launched under the terms a restart would recreate. Restart the tool-server (\`argent server stop && argent server start --detach\`), then retry. If it reads unregistered again after that restart, stop: the process loads argent's dylib but never dials, and no further restart on either side changes it. Treat native devtools as unavailable, then use \`describe\` or \`screenshot\` and drive by coordinate.
@@ -146138,6 +146153,13 @@ Returns { status: "init_failed", message, attempts } instead when the simulator'
146138
146153
  Fails if the simulator server is not running for the given UDID.`,
146139
146154
  zodSchema: zodSchema3,
146140
146155
  readOnly: true,
146156
+ // When the app is not connected, the native-* tools that use native devtools
146157
+ // run the same precheck and return the same `message` (buildAppStateMessage),
146158
+ // so agents need no separate status call. Their `status` names the remedy,
146159
+ // where this tool gives `state`. They fail instead for an Apple system app and
146160
+ // for an app that a device provider did not lend. The SDK and the e2e-full
146161
+ // suite still call it.
146162
+ hideFromMcp: true,
146141
146163
  interaction: {
146142
146164
  startedMsg: ({ params }) => `Checking native inspection for ${params.bundleId}`,
146143
146165
  completedMsg: ({ params }) => `Checked native inspection for ${params.bundleId}`,
@@ -146328,7 +146350,7 @@ On iOS: returns { status, count, events } where each event contains URL, method,
146328
146350
  <flag:macos-apps>On a Mac app it records NSURLSession requests, react-native-macos fetch included, with the same event fields. The first call turns capture on and earlier requests are not logged: call it once, then repeat the action. Capture stays on across restart-app with an empty log per process, and requests sent while the app starts can be missing. The statuses below are iOS only.
146329
146351
  </flag:macos-apps>If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: follow the message (re-boot the simulator) rather than retrying.
146330
146352
  On a device whose devtools agent argent attached to rather than armed itself, a not-connected app fails with \`NATIVE_DEVTOOLS_NOT_CONNECTED\` instead of a status, and no restart on argent's side fixes it. An Apple system app is rejected outright (terminal: never retry it).
146331
- On Android: needs a debuggable build, and native-devtools-status does not run there. The first call starts capture and usually returns armed: false. Call it again every few seconds until armed is true, then repeat the action whose requests you need: earlier requests are not captured.
146353
+ On Android: needs a debuggable build. The first call starts capture and usually returns armed: false. Call it again every few seconds until armed is true, then repeat the action whose requests you need: earlier requests are not captured.
146332
146354
  Capture also misses a request already in flight at the attach and requests from clients other than OkHttp (e.g. HttpURLConnection, Cronet); an app whose OkHttp is fully minified reports capture unavailable.
146333
146355
  Returns { status, header, armed, capture, captureDetail, count, total, requests }. When capture is active, captureDetail and the header can say that only some requests are captured: then an empty or short list does not mean the app sent nothing. Pass a request's ID (android-3f9a-12) to view-network-request-details for its headers, redirects and bodies.
146334
146356
  Capture can slow the app. It stays on, and launch-app and restart-app attach it to each new process, until a call with stop: true turns it off for this app (stop-all-simulator-servers for the device also does); restart-app then starts the app without the agent. stop: true returns { status, stopped, message }, where stopped is false when capture was not on for the app. On iOS stop: true fails: capture there ends only when stop-all-simulator-servers stops this device's services and the app restarts.
@@ -146493,15 +146515,15 @@ var zodSchema5 = external_exports.object({
146493
146515
  includeAncestors: external_exports.boolean().optional().describe("Include ancestor chain for each matched view (default true)"),
146494
146516
  includeChildren: external_exports.boolean().optional().describe("Include child views for each matched view (default true)"),
146495
146517
  fields: external_exports.array(external_exports.string()).optional().describe(
146496
- "View fields to include. Defaults: className, frame, hidden, alpha, identifier, label, nativeID, userInteractionEnabled, depth. Additional: pointer, tag, windowFrame, screenFrame, bounds, center, opaque, clipsToBounds, transform, contentMode, backgroundColor, tintColor, layerName"
146518
+ "View fields to include. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor, value, firstResponder"
146497
146519
  )
146498
146520
  });
146499
146521
  var nativeFindViewsTool = {
146500
146522
  id: "native-find-views",
146501
146523
  description: `Search for specific UIViews in the running app by class name, accessibility identifier, accessibility label, tag or React Native nativeID; at least one of these params is required.
146502
146524
  Use when you need to locate a specific view by its properties without dumping the entire native-full-hierarchy.
146503
- Returns { status: "ok", matches }: the matching views with their frames, properties, optional ancestors and optional children.
146504
- <flag:macos-apps>On a Mac app it searches the NSViews of every visible window: className is the NSView class, and identifier matches the accessibility identifier or the view identifier. The statuses below are iOS only.
146525
+ Returns { status: "ok", matches }: the matching views with their frames, properties, optional ancestors and optional children. Frames are in points. frame and center are relative to the superview, and windowFrame turns with the UI. To tap a view, divide the centre of its screenFrame by the screen size in points, which native-full-hierarchy returns as screen (maxDepth: 1 is enough), and pass the result to gesture-tap. Matches are not filtered for visibility. Before tapping, call native-user-interactable-view-at-point at that centre with skipClasses ["UITextEffectsWindow"]. If it does not return the match or a descendant, check a screenshot.
146526
+ <flag:macos-apps>On a Mac app it searches the NSViews of every visible window: className is the NSView class, and identifier matches the accessibility identifier or the view identifier. The tap recipe above and the statuses below are iOS only.
146505
146527
  </flag:macos-apps>If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: follow the message (re-boot the simulator) rather than retrying.
146506
146528
  An Apple system app is rejected outright (terminal: never retry it).`,
146507
146529
  zodSchema: zodSchema5,
@@ -146538,7 +146560,7 @@ init_zod();
146538
146560
  var zodSchema6 = external_exports.object({
146539
146561
  ...nativeAppTarget,
146540
146562
  fields: external_exports.array(external_exports.string()).optional().describe(
146541
- "View fields to include. Use EXACT names: className, frame, hidden, alpha, identifier, label, nativeID, userInteractionEnabled, depth, pointer, tag, windowFrame, screenFrame, bounds, center, opaque, clipsToBounds, transform, contentMode, backgroundColor, tintColor, layerName. Defaults to all of the first group when omitted."
146563
+ "View fields to include. Use EXACT names. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor, value, firstResponder"
146542
146564
  ),
146543
146565
  skipClasses: external_exports.array(external_exports.string()).optional().describe(
146544
146566
  'Exact UIView class names whose entire subtree should be pruned (e.g. ["UIImageView"] to drop image leaf nodes)'
@@ -146621,6 +146643,10 @@ normalized contract.
146621
146643
  An Apple system app is rejected outright (terminal: never retry it).`,
146622
146644
  zodSchema: zodSchema7,
146623
146645
  readOnly: true,
146646
+ // Agents get the disabled and selected states and the VoiceOver hint from
146647
+ // `describe`, which falls back to this RPC (ViewHierarchy.describeScreen) when
146648
+ // the ax-service returns nothing. The SDK still calls this tool directly.
146649
+ hideFromMcp: true,
146624
146650
  interaction: {
146625
146651
  startedMsg: ({ params }) => `Reading native screen for ${params.bundleId}`,
146626
146652
  completedMsg: ({ params }) => `Read native screen for ${params.bundleId}`,
@@ -146648,13 +146674,13 @@ init_src2();
146648
146674
  var zodSchema8 = external_exports.object({
146649
146675
  ...nativeAppTarget,
146650
146676
  x: external_exports.number().describe(
146651
- "Raw X coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames)<flag:macos-apps>; on a Mac app, points from the top-left of the area describe reports</flag:macos-apps>. NOT normalized [0,1] tap space."
146677
+ "Raw X coordinate in points, on the portrait axes of the screen<flag:macos-apps>; on a Mac app, points from the top-left of the area describe reports</flag:macos-apps>. NOT normalized [0,1] tap space."
146652
146678
  ),
146653
146679
  y: external_exports.number().describe("Raw Y coordinate in points, on the same axes as x. NOT normalized [0,1] tap space."),
146654
146680
  includeAncestors: external_exports.boolean().optional().describe("Include ancestor chain for the matched view (default true)"),
146655
146681
  includeChildren: external_exports.boolean().optional().describe("Include child views for the matched view (default false)"),
146656
146682
  fields: external_exports.array(external_exports.string()).optional().describe(
146657
- "View fields to include. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor"
146683
+ "View fields to include. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor, value, firstResponder"
146658
146684
  ),
146659
146685
  skipClasses: external_exports.array(external_exports.string()).optional().describe("Exact UIView class names whose entire subtree should be pruned"),
146660
146686
  skipClassPrefixes: external_exports.array(external_exports.string()).optional().describe("Class name prefixes to prune entire subtrees"),
@@ -146676,7 +146702,8 @@ identifier, label and layer name, plus its ancestors and subviews as requested.
146676
146702
  view is null when nothing is drawn at that point.
146677
146703
 
146678
146704
  To get x and y from a normalized describe frame, multiply its values by the
146679
- screen size in points, also when the UI is landscape.<flag:macos-apps> On a Mac app,
146705
+ screen size in points, also when the UI is landscape.
146706
+ native-full-hierarchy returns that size as screen (pass maxDepth: 1 and fields: ["className"] to keep it small).<flag:macos-apps> On a Mac app,
146680
146707
  multiply them by the size of the area describe reports instead.</flag:macos-apps>
146681
146708
 
146682
146709
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: follow the message (re-boot the simulator) rather than retrying.
@@ -146710,13 +146737,13 @@ init_src2();
146710
146737
  var zodSchema9 = external_exports.object({
146711
146738
  ...nativeAppTarget,
146712
146739
  x: external_exports.number().describe(
146713
- "Raw X coordinate in points, on the portrait axes of the screen (the axes of native-describe-screen frames)<flag:macos-apps>; on a Mac app, points from the top-left of the area describe reports</flag:macos-apps>. NOT normalized [0,1] tap space."
146740
+ "Raw X coordinate in points, on the portrait axes of the screen<flag:macos-apps>; on a Mac app, points from the top-left of the area describe reports</flag:macos-apps>. NOT normalized [0,1] tap space."
146714
146741
  ),
146715
146742
  y: external_exports.number().describe("Raw Y coordinate in points, on the same axes as x. NOT normalized [0,1] tap space."),
146716
146743
  includeAncestors: external_exports.boolean().optional().describe("Include ancestor chain for the matched view (default true)"),
146717
146744
  includeChildren: external_exports.boolean().optional().describe("Include child views for the matched view (default false)"),
146718
146745
  fields: external_exports.array(external_exports.string()).optional().describe(
146719
- "View fields to include. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor"
146746
+ "View fields to include. Defaults: pointer, className, tag, frame, windowFrame, screenFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor, value, firstResponder"
146720
146747
  ),
146721
146748
  skipClasses: external_exports.array(external_exports.string()).optional().describe("Exact UIView class names whose entire subtree should be pruned"),
146722
146749
  skipClassPrefixes: external_exports.array(external_exports.string()).optional().describe("Class name prefixes to prune entire subtrees"),
@@ -146738,7 +146765,8 @@ identifier, label and layer name, plus its ancestors and subviews as requested.
146738
146765
  view is null when no touchable view sits under that point.
146739
146766
 
146740
146767
  To get x and y from a normalized describe frame, multiply its values by the
146741
- screen size in points, also when the UI is landscape.<flag:macos-apps> On a Mac app,
146768
+ screen size in points, also when the UI is landscape.
146769
+ native-full-hierarchy returns that size as screen (pass maxDepth: 1 and fields: ["className"] to keep it small).<flag:macos-apps> On a Mac app,
146742
146770
  multiply them by the size of the area describe reports instead.</flag:macos-apps>
146743
146771
 
146744
146772
  If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help. Restart the tool-server (\`argent server stop && argent server start --detach\`) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting. Do not restart it, wait a few seconds and retry. If status is init_failed: follow the message (re-boot the simulator) rather than retrying.
@@ -146770,8 +146798,17 @@ An Apple system app is rejected outright (terminal: never retry it).`,
146770
146798
  init_src2();
146771
146799
 
146772
146800
  // ../tool-server/src/utils/debugger/discovery.ts
146801
+ var import_node_fs13 = require("node:fs");
146773
146802
  init_src2();
146774
146803
  var DECOY_VM = "don't use";
146804
+ function decodeProjectRoot(raw) {
146805
+ if (!raw.includes("%") || (0, import_node_fs13.existsSync)(raw)) return raw;
146806
+ try {
146807
+ return decodeURIComponent(raw);
146808
+ } catch {
146809
+ return raw;
146810
+ }
146811
+ }
146775
146812
  async function discoverMetro(port) {
146776
146813
  let statusRes;
146777
146814
  try {
@@ -146813,7 +146850,7 @@ async function discoverMetro(port) {
146813
146850
  }
146814
146851
  );
146815
146852
  }
146816
- const projectRoot = statusRes.headers.get("X-React-Native-Project-Root") ?? "";
146853
+ const projectRoot = decodeProjectRoot(statusRes.headers.get("X-React-Native-Project-Root") ?? "");
146817
146854
  let listRes;
146818
146855
  try {
146819
146856
  listRes = await fetch(`http://localhost:${port}/json/list`);
@@ -149421,7 +149458,7 @@ function clearLostProfilerRun(port, deviceId) {
149421
149458
 
149422
149459
  // ../tool-server/src/tools/devices/boot-device.ts
149423
149460
  var import_node_child_process34 = require("node:child_process");
149424
- var import_node_fs14 = require("node:fs");
149461
+ var import_node_fs15 = require("node:fs");
149425
149462
  var import_promises13 = require("node:fs/promises");
149426
149463
  var import_node_os14 = require("node:os");
149427
149464
  var import_node_path19 = require("node:path");
@@ -149534,7 +149571,7 @@ function readMb(config2, key2) {
149534
149571
 
149535
149572
  // ../tool-server/src/utils/simulator-app-launch.ts
149536
149573
  var import_node_child_process32 = require("node:child_process");
149537
- var import_node_fs13 = __toESM(require("node:fs"));
149574
+ var import_node_fs14 = __toESM(require("node:fs"));
149538
149575
  var import_node_os13 = __toESM(require("node:os"));
149539
149576
  var import_node_path18 = __toESM(require("node:path"));
149540
149577
  var import_node_util23 = require("node:util");
@@ -149548,7 +149585,7 @@ function verdictFilePath() {
149548
149585
  }
149549
149586
  function loadVerdicts() {
149550
149587
  try {
149551
- const parsed = JSON.parse(import_node_fs13.default.readFileSync(verdictFilePath(), "utf8"));
149588
+ const parsed = JSON.parse(import_node_fs14.default.readFileSync(verdictFilePath(), "utf8"));
149552
149589
  return parsed && typeof parsed === "object" ? parsed : {};
149553
149590
  } catch {
149554
149591
  return {};
@@ -149556,13 +149593,13 @@ function loadVerdicts() {
149556
149593
  }
149557
149594
  function persistVerdict(key2, verdict) {
149558
149595
  const filePath = verdictFilePath();
149559
- import_node_fs13.default.mkdirSync(import_node_path18.default.dirname(filePath), { recursive: true });
149596
+ import_node_fs14.default.mkdirSync(import_node_path18.default.dirname(filePath), { recursive: true });
149560
149597
  const tmpPath = `${filePath}.${process.pid}.tmp`;
149561
149598
  try {
149562
- import_node_fs13.default.writeFileSync(tmpPath, JSON.stringify({ ...loadVerdicts(), [key2]: verdict }, null, 2));
149563
- import_node_fs13.default.renameSync(tmpPath, filePath);
149599
+ import_node_fs14.default.writeFileSync(tmpPath, JSON.stringify({ ...loadVerdicts(), [key2]: verdict }, null, 2));
149600
+ import_node_fs14.default.renameSync(tmpPath, filePath);
149564
149601
  } catch (err) {
149565
- import_node_fs13.default.rmSync(tmpPath, { force: true });
149602
+ import_node_fs14.default.rmSync(tmpPath, { force: true });
149566
149603
  throw err;
149567
149604
  }
149568
149605
  }
@@ -150344,9 +150381,9 @@ async function bootIos(udid, registry2, force, headless) {
150344
150381
  async function openSimulatorWindow(udid) {
150345
150382
  const timeout = 5e3;
150346
150383
  const { stdout } = await execFileAsync24("xcode-select", ["-p"], { timeout });
150347
- const developerDir2 = (0, import_node_fs14.realpathSync)(stdout.trim());
150384
+ const developerDir2 = (0, import_node_fs15.realpathSync)(stdout.trim());
150348
150385
  const simulatorApp = (0, import_node_path19.join)(developerDir2, "Applications", "Simulator.app");
150349
- if ((0, import_node_fs14.existsSync)(simulatorApp)) {
150386
+ if ((0, import_node_fs15.existsSync)(simulatorApp)) {
150350
150387
  const launched = await launchSimulatorApp(
150351
150388
  simulatorApp,
150352
150389
  () => execFileAsync24("open", ["-a", simulatorApp], { timeout })
@@ -150354,7 +150391,7 @@ async function openSimulatorWindow(udid) {
150354
150391
  return launched ? void 0 : `${simulatorApp} exits right after launch on this host, so Argent no longer opens it and the device runs without a window. Delete ~/.argent/simulator-app-launch.json to try opening it again.`;
150355
150392
  }
150356
150393
  const deviceHubApp = (0, import_node_path19.join)(developerDir2, "..", "Applications", "DeviceHub.app");
150357
- if ((0, import_node_fs14.existsSync)(deviceHubApp)) {
150394
+ if ((0, import_node_fs15.existsSync)(deviceHubApp)) {
150358
150395
  const url2 = `devices://device/open?id=${encodeURIComponent(udid)}`;
150359
150396
  await execFileAsync24("open", ["-a", deviceHubApp, url2], { timeout });
150360
150397
  }
@@ -150402,7 +150439,7 @@ async function attemptBoot(params) {
150402
150439
  if (process.platform === "win32") {
150403
150440
  const safeName = params.avdName.replace(/[^\w.-]/g, "_");
150404
150441
  const logPath = (0, import_node_path19.join)((0, import_node_os14.tmpdir)(), `argent-emulator-${safeName}.log`);
150405
- emulatorLogFd = (0, import_node_fs14.openSync)(logPath, "w");
150442
+ emulatorLogFd = (0, import_node_fs15.openSync)(logPath, "w");
150406
150443
  stdio = ["ignore", emulatorLogFd, emulatorLogFd];
150407
150444
  }
150408
150445
  const child = (0, import_node_child_process34.spawn)(params.emulatorBinary, params.emulatorArgs, {
@@ -150412,7 +150449,7 @@ async function attemptBoot(params) {
150412
150449
  child.unref();
150413
150450
  if (emulatorLogFd !== void 0) {
150414
150451
  try {
150415
- (0, import_node_fs14.closeSync)(emulatorLogFd);
150452
+ (0, import_node_fs15.closeSync)(emulatorLogFd);
150416
150453
  } catch {
150417
150454
  }
150418
150455
  }
@@ -150930,11 +150967,11 @@ async function startHarmonyEmulator(instanceName) {
150930
150967
  });
150931
150968
  }
150932
150969
  try {
150933
- for (const entry of (0, import_node_fs14.readdirSync)((0, import_node_os14.tmpdir)())) {
150970
+ for (const entry of (0, import_node_fs15.readdirSync)((0, import_node_os14.tmpdir)())) {
150934
150971
  if (!entry.startsWith("argent-harmony-") || !entry.endsWith(".log")) continue;
150935
150972
  try {
150936
- if (Date.now() - (0, import_node_fs14.statSync)((0, import_node_path19.join)((0, import_node_os14.tmpdir)(), entry)).mtimeMs > HARMONY_LOG_TTL_MS) {
150937
- (0, import_node_fs14.rmSync)((0, import_node_path19.join)((0, import_node_os14.tmpdir)(), entry), { force: true });
150973
+ if (Date.now() - (0, import_node_fs15.statSync)((0, import_node_path19.join)((0, import_node_os14.tmpdir)(), entry)).mtimeMs > HARMONY_LOG_TTL_MS) {
150974
+ (0, import_node_fs15.rmSync)((0, import_node_path19.join)((0, import_node_os14.tmpdir)(), entry), { force: true });
150938
150975
  }
150939
150976
  } catch {
150940
150977
  }
@@ -150945,7 +150982,7 @@ async function startHarmonyEmulator(instanceName) {
150945
150982
  const logPath = (0, import_node_path19.join)((0, import_node_os14.tmpdir)(), `argent-harmony-${safeName}-${process.hrtime.bigint()}.log`);
150946
150983
  let logFd;
150947
150984
  try {
150948
- logFd = (0, import_node_fs14.openSync)(logPath, "w");
150985
+ logFd = (0, import_node_fs15.openSync)(logPath, "w");
150949
150986
  } catch {
150950
150987
  logFd = null;
150951
150988
  }
@@ -150956,7 +150993,7 @@ async function startHarmonyEmulator(instanceName) {
150956
150993
  child.unref();
150957
150994
  if (logFd !== null) {
150958
150995
  try {
150959
- (0, import_node_fs14.closeSync)(logFd);
150996
+ (0, import_node_fs15.closeSync)(logFd);
150960
150997
  } catch {
150961
150998
  }
150962
150999
  }
@@ -150965,7 +151002,7 @@ async function startHarmonyEmulator(instanceName) {
150965
151002
  if (exit) return;
150966
151003
  let output2 = "";
150967
151004
  try {
150968
- output2 = (0, import_node_fs14.readFileSync)(logPath, "utf8");
151005
+ output2 = (0, import_node_fs15.readFileSync)(logPath, "utf8");
150969
151006
  } catch {
150970
151007
  }
150971
151008
  exit = { reason: reason2, output: output2 };
@@ -153521,7 +153558,7 @@ init_device_info();
153521
153558
  init_adb();
153522
153559
 
153523
153560
  // ../tool-server/src/utils/device-orientation.ts
153524
- var import_node_fs15 = require("node:fs");
153561
+ var import_node_fs16 = require("node:fs");
153525
153562
  init_adb();
153526
153563
  var SURFACE_ROTATION_TO_NAME = {
153527
153564
  0: "Portrait",
@@ -153566,7 +153603,7 @@ function captureRotationForSurface(rotation) {
153566
153603
  async function readPngSize2(path63) {
153567
153604
  let handle;
153568
153605
  try {
153569
- handle = await import_node_fs15.promises.open(path63, "r");
153606
+ handle = await import_node_fs16.promises.open(path63, "r");
153570
153607
  const buf = Buffer.alloc(24);
153571
153608
  const { bytesRead } = await handle.read(buf, 0, 24, 0);
153572
153609
  if (bytesRead < 24) return null;
@@ -154060,8 +154097,7 @@ var gestureTapTool = {
154060
154097
  description: `Press the device screen (iOS simulator or physical device, Android emulator, <flag:harmonyos>HarmonyOS device, </flag:harmonyos><flag:macos-apps>Mac app, </flag:macos-apps>or Chromium app) at a point given as fractions of the screen width and height (not pixels): a Down event followed by an Up event at the same spot.<flag:macos-apps> On a Mac app it is a click, and x/y are fractions of the area describe reports, not of the window.</flag:macos-apps>
154061
154098
  Use when tapping a button, link, or any tappable element on the screen.
154062
154099
  Returns { tapped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the device backend (simulator-server / emulator / Chromium CDP<flag:harmonyos> / \`hdc\`</flag:harmonyos>) is unreachable.
154063
- On a physical iPhone use \`describe\`; \`native-describe-screen\` is simulator-only.
154064
- Before tapping, determine the correct coordinates by using discovery tools. Pick by platform: iOS / Android use \`describe\` (on an iOS simulator, also \`native-describe-screen\`); Chromium uses \`describe\` (the DOM walker)<flag:harmonyos> and HarmonyOS uses \`describe\` (the \`uitest\` layout dump)</flag:harmonyos>, since the native discovery tools don't apply<flag:harmonyos> to either</flag:harmonyos><flag:macos-apps>; a Mac app uses \`describe\`</flag:macos-apps>. More information in \`argent-device-interact\` skill`,
154100
+ Before tapping, take the coordinates from \`describe\` on every platform (on Chromium it walks the DOM<flag:harmonyos>, on HarmonyOS it reads the \`uitest\` layout dump</flag:harmonyos>). More information in \`argent-device-interact\` skill`,
154065
154101
  zodSchema: zodSchema18,
154066
154102
  alwaysLoad: true,
154067
154103
  // A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
@@ -157723,8 +157759,9 @@ var zodSchema33 = external_exports.object({
157723
157759
  var debuggerEvaluateTool = {
157724
157760
  id: "debugger-evaluate",
157725
157761
  description: `Execute arbitrary JavaScript in the app's JS runtime via CDP: Hermes on iOS / Android / Vega, V8 on Chromium.
157726
- Returns the result serialized by value as JSON, with deviceName, appName, and logicalDeviceId. Use when you need to read app state, call app functions, or test logic at runtime. Cyclic objects, which many RN runtime values are (fiber nodes, navigation refs, global), fail with a serialization error. Fails if the expression throws or the runtime is not connected.`,
157762
+ Returns the result serialized by value as JSON, with deviceName, appName, and logicalDeviceId. Use when you need to read app state, including localStorage and sessionStorage on Chromium, call app functions, or test logic at runtime. Cyclic objects, which many RN runtime values are (fiber nodes, navigation refs, global), fail with a serialization error. Fails if the expression throws or the runtime is not connected.`,
157727
157763
  zodSchema: zodSchema33,
157764
+ searchHint: "javascript js eval expression runtime app state localstorage sessionstorage web storage",
157728
157765
  interaction: {
157729
157766
  startedMsg: () => "Running JavaScript in the app",
157730
157767
  completedMsg: () => "Ran JavaScript in the app",
@@ -160064,19 +160101,24 @@ function hasContent(n) {
160064
160101
  function shouldEmit(n, contentRoles) {
160065
160102
  return hasContent(n) || contentRoles.has(n.role);
160066
160103
  }
160104
+ function hasIosState(n) {
160105
+ return Boolean(n.hint || n.disabled || n.selected);
160106
+ }
160067
160107
  function formatLine(n, indent, source) {
160068
160108
  const pad = " ".repeat(indent);
160069
160109
  const dedupedValue = n.value && n.value !== n.label ? n.value : void 0;
160110
+ const dedupedHint = n.hint && n.hint !== n.label ? n.hint : void 0;
160070
160111
  const labelPart = formatLabel(n.label);
160071
160112
  const valuePart = formatAttr("value", dedupedValue);
160072
160113
  const idPart = formatAttr("id", n.identifier);
160114
+ const hintPart = formatAttr("hint", dedupedHint);
160073
160115
  const flagPart = formatFlags(n, source);
160074
- const annotations = `${labelPart}${valuePart}${idPart}${flagPart}`.trim();
160116
+ const annotations = `${labelPart}${valuePart}${idPart}${hintPart}${flagPart}`.trim();
160075
160117
  const annotated = annotations ? ` ${annotations}` : "";
160076
160118
  return `${pad}${n.role}${annotated} ${fmtFrame(n.frame)}`;
160077
160119
  }
160078
160120
  function renderFlat(root, contentRoles, source) {
160079
- return root.children.filter((n) => shouldEmit(n, contentRoles)).slice().sort((a, b) => a.frame.y - b.frame.y || a.frame.x - b.frame.x).map((n) => formatLine(n, 1, source));
160121
+ return root.children.filter((n) => shouldEmit(n, contentRoles) || hasIosState(n)).slice().sort((a, b) => a.frame.y - b.frame.y || a.frame.x - b.frame.x).map((n) => formatLine(n, 1, source));
160080
160122
  }
160081
160123
  function renderNested(root, contentRoles, source) {
160082
160124
  const lines = [];
@@ -160292,11 +160334,10 @@ On HarmonyOS it runs the device's \`uitest dumpLayout\` (\`source: "harmony-uite
160292
160334
  On a Mac app it reads the app's accessibility tree with web view content and React Native testIDs merged in; frames are fractions of the app window, grown to include sheets and menus past it.</flag:macos-apps>
160293
160335
  On a TV target (Apple TV / Android TV: a \`list-devices\` entry with runtimeKind 'tv') it returns the FOCUSED element and the FOCUSABLE elements instead, since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\`, then call describe again to confirm where focus landed.
160294
160336
 
160295
- Returns \`{ description, source }\`: \`description\` renders the tree one line per element, with its role, label/value/id, interactivity flags and frame. Frames are normalized [0,1] fractions of the screen / window width and height (not pixels); tap an element at the centre of its frame. The tree has no z-order or occlusion information: an element may be covered by an overlay (e.g. a toolbar over list rows), so check a screenshot when a tap lands unexpectedly.
160337
+ Returns \`{ description, source }\`: \`description\` renders the tree one line per element, with its role, label/value/id, VoiceOver hint (iOS simulator), interactivity flags and frame. Frames are normalized [0,1] fractions of the screen / window width and height (not pixels); tap an element at the centre of its frame. The tree has no z-order or occlusion information: an element may be covered by an overlay (e.g. a toolbar over list rows), so check a screenshot when a tap lands unexpectedly.
160296
160338
  Fails if the tree cannot be read, e.g. on a physical iOS device before launch-app has started an app.
160297
160339
 
160298
- For app-scoped inspection with full UIKit properties (accessibilityIdentifier, viewClassName),
160299
- use native-describe-screen with an explicit bundleId instead (iOS simulator only).
160340
+ For UIKit properties of a view (class name, accessibilityIdentifier), use native-find-views (iOS simulator only).
160300
160341
  For React Native component names, or a testID describe does not list, use debugger-component-tree.`,
160301
160342
  zodSchema: zodSchema40,
160302
160343
  alwaysLoad: true,
@@ -162694,7 +162735,7 @@ function createReactProfilerStopTool(registry2) {
162694
162735
  return {
162695
162736
  id: "react-profiler-stop",
162696
162737
  description: `Stop CPU profiling and collect the cpuProfile + React commit tree.
162697
- Stores the results for react-profiler-analyze or react-profiler-cpu-summary.
162738
+ Stores the results for react-profiler-analyze, profiler-commit-query and profiler-cpu-query.
162698
162739
  Call react-profiler-start first, then exercise the app, then call this.
162699
162740
  Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices, react_render_ms, react_render_share_pct, react_render_peak_1s_pct }.
162700
162741
  If some fibers' display names could not be resolved (typically modals, tooltips or animations that unmounted before stop), it also returns { unattributed_ms, unattributed_fiber_count, unattributed_commit_count }: the work missing from the per-component breakdown. Per-commit durations stay correct.
@@ -163201,6 +163242,7 @@ function createReactProfilerStatusTool(registry2) {
163201
163242
  // ../tool-server/src/tools/profiler/react/react-profiler-analyze.ts
163202
163243
  init_zod();
163203
163244
  var import_fs5 = require("fs");
163245
+ var import_path6 = require("path");
163204
163246
  init_src2();
163205
163247
 
163206
163248
  // ../tool-server/src/utils/react-profiler/pipeline/session-context.ts
@@ -163830,6 +163872,7 @@ var EXCLUDE_DIRS = /* @__PURE__ */ new Set([
163830
163872
  var TEST_FILE = /\.(test|spec)\.[jt]sx?$/;
163831
163873
  async function findSourceFiles(dir) {
163832
163874
  const result = [];
163875
+ const nestedPackages = [];
163833
163876
  async function walk(current) {
163834
163877
  let entries;
163835
163878
  try {
@@ -163837,6 +163880,9 @@ async function findSourceFiles(dir) {
163837
163880
  } catch {
163838
163881
  return;
163839
163882
  }
163883
+ if (current !== dir && entries.some((e) => e.isFile() && e.name === "package.json")) {
163884
+ nestedPackages.push(current + import_path4.sep);
163885
+ }
163840
163886
  for (const entry of entries) {
163841
163887
  if (entry.isDirectory()) {
163842
163888
  if (!EXCLUDE_DIRS.has(entry.name)) {
@@ -163851,7 +163897,7 @@ async function findSourceFiles(dir) {
163851
163897
  }
163852
163898
  }
163853
163899
  await walk(dir);
163854
- return result;
163900
+ return { files: result, nestedPackages };
163855
163901
  }
163856
163902
  function isCapitalized(name) {
163857
163903
  if (name.length === 0) return false;
@@ -163898,12 +163944,47 @@ function collectMemoizedNames(root) {
163898
163944
  return names;
163899
163945
  }
163900
163946
  var PLATFORM_SUFFIX = /\.(web|ios|android|native)\.[jt]sx?$/;
163901
- function isPlatformVariant(file2) {
163902
- return PLATFORM_SUFFIX.test(file2);
163947
+ var EXTENSION = /\.[jt]sx?$/;
163948
+ var NOT_APP_CODE = /\.(test|spec|stories)\.[jt]sx?$/;
163949
+ var NOT_BUNDLED = 3;
163950
+ function variantRank(file2, platform) {
163951
+ const suffix = PLATFORM_SUFFIX.exec(file2)?.[1];
163952
+ if (!platform) return suffix ? 1 : 0;
163953
+ if (suffix === platform) return 0;
163954
+ if (suffix === "native") return 1;
163955
+ return suffix ? NOT_BUNDLED : 2;
163956
+ }
163957
+ function moduleOf(file2) {
163958
+ return file2.replace(PLATFORM_SUFFIX, "").replace(EXTENSION, "");
163959
+ }
163960
+ function bundledFilter(files, platform) {
163961
+ if (!platform) return () => true;
163962
+ const best = /* @__PURE__ */ new Map();
163963
+ for (const file2 of files) {
163964
+ const module2 = moduleOf(file2);
163965
+ best.set(module2, Math.min(best.get(module2) ?? NOT_BUNDLED, variantRank(file2, platform)));
163966
+ }
163967
+ return (file2) => {
163968
+ const rank2 = variantRank(file2, platform);
163969
+ return rank2 !== NOT_BUNDLED && rank2 === best.get(moduleOf(file2));
163970
+ };
163971
+ }
163972
+ function fileNameKey(name) {
163973
+ return name.replace(/[-_]/g, "").toLowerCase();
163903
163974
  }
163904
- function pickPrimary(entries) {
163975
+ function isNamedAfter(file2, component) {
163976
+ const base = (0, import_path4.basename)(moduleOf(file2));
163977
+ const stem = base === "index" ? (0, import_path4.basename)((0, import_path4.dirname)(file2)) : base;
163978
+ return fileNameKey(stem) === fileNameKey(component);
163979
+ }
163980
+ function pickPrimary(name, entries, platform, nestedPackages) {
163981
+ const foreign = (file2) => NOT_APP_CODE.test(file2) || nestedPackages.some((dir) => file2.startsWith(dir)) ? 1 : 0;
163905
163982
  const sorted = entries.slice().sort((a, b) => {
163906
- const variantDelta = Number(isPlatformVariant(a.file)) - Number(isPlatformVariant(b.file));
163983
+ const foreignDelta = foreign(a.file) - foreign(b.file);
163984
+ if (foreignDelta !== 0) return foreignDelta;
163985
+ const nameDelta = Number(isNamedAfter(b.file, name)) - Number(isNamedAfter(a.file, name));
163986
+ if (nameDelta !== 0) return nameDelta;
163987
+ const variantDelta = variantRank(a.file, platform) - variantRank(b.file, platform);
163907
163988
  if (variantDelta !== 0) return variantDelta;
163908
163989
  if (a.file !== b.file) return a.file < b.file ? -1 : 1;
163909
163990
  if (a.line !== b.line) return a.line - b.line;
@@ -163917,12 +163998,12 @@ function pickPrimary(entries) {
163917
163998
  }
163918
163999
  var DEFAULT_PARSE_BUFFER_CHARS = 32 * 1024 - 1;
163919
164000
  var MAX_JSX_FILE_CHARS = 512 * 1024;
163920
- async function buildAstIndexWithDiagnostics(projectRoot) {
164001
+ async function buildAstIndexWithDiagnostics(projectRoot, platform) {
163921
164002
  const index = /* @__PURE__ */ new Map();
163922
164003
  const ts = loadTreeSitter();
163923
164004
  if (!ts) return { index, treeSitterAvailable: false, indexedFiles: 0 };
163924
164005
  const { ParserClass, ts: tsLang, tsx: tsxLang } = ts;
163925
- const files = await findSourceFiles(projectRoot);
164006
+ const { files, nestedPackages } = await findSourceFiles(projectRoot);
163926
164007
  const candidates = /* @__PURE__ */ new Map();
163927
164008
  function addCandidate(name, entry) {
163928
164009
  const existing = candidates.get(name);
@@ -163993,8 +164074,11 @@ async function buildAstIndexWithDiagnostics(projectRoot) {
163993
164074
  } catch {
163994
164075
  }
163995
164076
  }
164077
+ const isBundled = bundledFilter(files, platform);
163996
164078
  for (const [name, entries] of candidates) {
163997
- const { primary, others } = pickPrimary(entries);
164079
+ const bundled = entries.filter(({ file: file2 }) => isBundled(file2));
164080
+ if (bundled.length === 0) continue;
164081
+ const { primary, others } = pickPrimary(name, bundled, platform, nestedPackages);
163998
164082
  index.set(name, others.length > 0 ? { ...primary, otherMatches: others } : primary);
163999
164083
  }
164000
164084
  return { index, treeSitterAvailable: true, indexedFiles: files.length };
@@ -164066,6 +164150,7 @@ function createComponentOriginClassifier(index) {
164066
164150
 
164067
164151
  // ../tool-server/src/utils/react-profiler/pipeline/05-render.ts
164068
164152
  var MAX_INLINE_COMMITS = 10;
164153
+ var MAX_OTHER_MATCHES = 3;
164069
164154
  var MAX_OUTSIDE_SOURCE_NAMES = 5;
164070
164155
  var REPORT_FILENAME = "react-profiler-report.md";
164071
164156
  async function renderProfilingReport(input2) {
@@ -164163,7 +164248,15 @@ function renderNoHotCommits(input2, maxMs) {
164163
164248
  lines.push(``, `No component in this session could be named, so there is nothing to list.`);
164164
164249
  }
164165
164250
  const { rows, cut } = frequentRerenderRows(input2);
164166
- lines.push(...renderFrequentRerenders(summary, rows, frequentOutsideSource(input2), cut));
164251
+ lines.push(
164252
+ ...renderFrequentRerenders(
164253
+ summary,
164254
+ rows,
164255
+ frequentOutsideSource(input2),
164256
+ input2.sessionContext.projectRoot,
164257
+ cut
164258
+ )
164259
+ );
164167
164260
  lines.push(``, `---`, `## Next Steps`, ``);
164168
164261
  if (rows.length > 0) {
164169
164262
  lines.push(
@@ -164200,7 +164293,7 @@ function frequentOutsideSource(input2) {
164200
164293
  input2.componentOrigin ?? createComponentOriginClassifier(null)
164201
164294
  ) : [];
164202
164295
  }
164203
- function renderFrequentRerenders(summary, rows, outsideSource, cut = []) {
164296
+ function renderFrequentRerenders(summary, rows, outsideSource, projectRoot, cut = []) {
164204
164297
  if (!summary) return [];
164205
164298
  const outsideNote = outsideSource.length > 0 ? [``, renderOutsideSourceNote(outsideSource)] : [];
164206
164299
  const cutNote = cut.length > 0 ? [``, renderCutNote(cut)] : [];
@@ -164215,7 +164308,7 @@ function renderFrequentRerenders(summary, rows, outsideSource, cut = []) {
164215
164308
  ``,
164216
164309
  `| Component | Re-renders | Per second | Self ms/s | Self total | Reason | File |`,
164217
164310
  `|---|---|---|---|---|---|---|`,
164218
- ...rows.map(renderFrequentRow),
164311
+ ...rows.map((row) => renderFrequentRow(row, projectRoot)),
164219
164312
  ...cutNote,
164220
164313
  ...outsideNote
164221
164314
  ];
@@ -164230,10 +164323,10 @@ function renderOutsideSourceNote(names) {
164230
164323
  const more = names.length > MAX_OUTSIDE_SOURCE_NAMES ? ` and ${names.length - MAX_OUTSIDE_SOURCE_NAMES} more` : "";
164231
164324
  return `Frequent re-renders left out because the source index has no definition for the name: ${shown}${more}. These are usually library components. Class components, components made by a wrapper such as \`observer()\`, and all of your components when \`project_root\` is wrong land here too. \`profiler-commit-query\` mode=\`render_counts\` has the counts.`;
164232
164325
  }
164233
- function renderFrequentRow(row) {
164326
+ function renderFrequentRow(row, projectRoot) {
164234
164327
  const c = row.component;
164235
164328
  const ann = annotateComponentName(c.name);
164236
- const file2 = row.origin.file !== void 0 ? `\`${shortenPath(row.origin.file)}${row.origin.line !== void 0 ? `:${row.origin.line}` : ""}\`` : "\u2014";
164329
+ const file2 = row.origin.file !== void 0 ? `\`${pathFromProject(row.origin.file, projectRoot)}${row.origin.line !== void 0 ? `:${row.origin.line}` : ""}\`` : "\u2014";
164237
164330
  return `| \`${ann.displayName}\`${ann.tag} | ${formatCount(c.rerenders)} | ${row.perSecond.toFixed(1)} | ${row.selfMsPerSecond.toFixed(1)} | ${c.rerenderSelfMs.toFixed(1)}ms | ${formatRenderSummaryReason(c)} | ${file2} |`;
164238
164331
  }
164239
164332
  function renderCompilerStatus(enabled, detectedAtRuntime) {
@@ -164283,7 +164376,7 @@ function buildFullMarkdown(input2, annotations, totalHotCommits) {
164283
164376
  lines.push("| Component | Renders | Total | Avg | Max | Reason | File |");
164284
164377
  lines.push("|---|---|---|---|---|---|---|");
164285
164378
  for (const f of input2.componentFindings) {
164286
- const file2 = f.sourceLocation ? `\`${shortenPath(f.sourceLocation.file)}:${f.sourceLocation.line}\`` : "\u2014";
164379
+ const file2 = f.sourceLocation ? formatLocation(f.sourceLocation, sessionContext.projectRoot) : "\u2014";
164287
164380
  const reasonStr = formatReason(f.dominantReason, f.topChangedProps, f.topChangedHookNames);
164288
164381
  const compilerFlag = f.compilerBailoutSuspected ? " \u26A0\uFE0F" : f.isCompilerOptimized ? " \u2713" : "";
164289
164382
  const ann = annotateComponentName(f.component);
@@ -164311,13 +164404,15 @@ function buildFullMarkdown(input2, annotations, totalHotCommits) {
164311
164404
  input2.renderSummary ?? null,
164312
164405
  tableAddsRow ? frequent : [],
164313
164406
  outsideSource,
164407
+ sessionContext.projectRoot,
164314
164408
  cutNew
164315
164409
  )
164316
164410
  );
164317
164411
  }
164318
164412
  const suggestionsSection = renderSuggestedImprovements(
164319
164413
  input2.componentFindings,
164320
- sessionContext.reactCompilerEnabled
164414
+ sessionContext.reactCompilerEnabled,
164415
+ sessionContext.projectRoot
164321
164416
  );
164322
164417
  if (suggestionsSection) {
164323
164418
  lines.push(suggestionsSection);
@@ -164491,12 +164586,12 @@ function findPriorAnnotation(annotations, relativeMs) {
164491
164586
  }
164492
164587
  return result;
164493
164588
  }
164494
- function renderSuggestedImprovements(findings, compilerEnabled) {
164589
+ function renderSuggestedImprovements(findings, compilerEnabled, projectRoot) {
164495
164590
  if (findings.length === 0) return "";
164496
164591
  const topFindings = findings.slice().sort((a, b) => b.totalMs - a.totalMs).slice(0, 5);
164497
164592
  const lines = ["", "---", "## Suggested Improvements", ""];
164498
164593
  for (const f of topFindings) {
164499
- const loc = f.sourceLocation ? `\`${shortenPath(f.sourceLocation.file)}:${f.sourceLocation.line}\`` : null;
164594
+ const loc = f.sourceLocation ? formatLocation(f.sourceLocation, projectRoot) : null;
164500
164595
  const ann = annotateComponentName(f.component);
164501
164596
  const heading = `\`${ann.displayName}\`${ann.tag}`;
164502
164597
  lines.push(loc ? `### ${heading} \u2014 ${loc}` : `### ${heading}`);
@@ -164560,7 +164655,7 @@ function renderSuggestedImprovements(findings, compilerEnabled) {
164560
164655
  }
164561
164656
  }
164562
164657
  if (f.sourceSnippet && f.sourceLocation) {
164563
- const snippetPath = `${shortenPath(f.sourceLocation.file)}:${f.sourceLocation.line}`;
164658
+ const snippetPath = `${pathFromProject(f.sourceLocation.file, projectRoot)}:${f.sourceLocation.line}`;
164564
164659
  lines.push("");
164565
164660
  lines.push(`<details><summary>Source \u2014 \`${snippetPath}\`</summary>`);
164566
164661
  lines.push("");
@@ -164574,10 +164669,23 @@ function renderSuggestedImprovements(findings, compilerEnabled) {
164574
164669
  }
164575
164670
  return lines.join("\n");
164576
164671
  }
164672
+ function formatLocation(loc, projectRoot) {
164673
+ const main = `\`${pathFromProject(loc.file, projectRoot)}:${loc.line}\``;
164674
+ const others = loc.otherMatches ?? [];
164675
+ if (others.length === 0) return main;
164676
+ const shown = others.slice(0, MAX_OTHER_MATCHES).map((m) => `${pathFromProject(m.file, projectRoot)}:${m.line}`);
164677
+ const rest = others.length - shown.length;
164678
+ return `${main} (name also in ${shown.join(", ")}${rest > 0 ? `, +${rest} more` : ""})`;
164679
+ }
164577
164680
  function shortenPath(file2) {
164578
164681
  const parts2 = file2.replace(/\\/g, "/").split("/");
164579
164682
  return parts2.slice(-2).join("/");
164580
164683
  }
164684
+ function pathFromProject(file2, projectRoot) {
164685
+ const fromRoot = (0, import_path5.relative)(projectRoot, file2);
164686
+ const outsideRoot = !fromRoot || fromRoot.split(import_path5.sep)[0] === ".." || (0, import_path5.isAbsolute)(fromRoot);
164687
+ return outsideRoot ? file2 : fromRoot;
164688
+ }
164581
164689
  async function writeReport(path63, content) {
164582
164690
  try {
164583
164691
  await import_fs4.promises.writeFile(path63, content, "utf8");
@@ -164591,6 +164699,21 @@ async function writeReport(path63, content) {
164591
164699
  async function fileArtifact(store, p, kind) {
164592
164700
  return p ? store.register({ hostPath: p, kind }) : null;
164593
164701
  }
164702
+ function recordedPlatform(profile) {
164703
+ for (const node2 of profile?.nodes ?? []) {
164704
+ const match = /[?&]platform=(ios|android)\b/.exec(node2.callFrame.url);
164705
+ if (match) return match[1];
164706
+ }
164707
+ return void 0;
164708
+ }
164709
+ async function resolvedPath(path63) {
164710
+ return import_fs5.promises.realpath(path63).catch(() => path63);
164711
+ }
164712
+ async function unrelatedPaths(a, b) {
164713
+ const [from2, to] = await Promise.all([resolvedPath(a), resolvedPath(b)]);
164714
+ const outside = (rel) => rel.startsWith("..") || (0, import_path6.isAbsolute)(rel);
164715
+ return outside((0, import_path6.relative)(from2, to)) && outside((0, import_path6.relative)(to, from2));
164716
+ }
164594
164717
  var annotationSchema = external_exports.object({
164595
164718
  offsetMs: external_exports.coerce.number().describe(
164596
164719
  "Milliseconds since profiling started: tapTimestampMs - startedAtEpochMs, where tapTimestampMs is the timestampMs a tap/swipe tool returned and startedAtEpochMs is the value react-profiler-start returned."
@@ -164603,7 +164726,7 @@ var zodSchema48 = external_exports.object({
164603
164726
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
164604
164727
  ),
164605
164728
  project_root: external_exports.string().describe("Absolute path to the RN project root for session context detection"),
164606
- platform: external_exports.enum(["ios", "android"]).default("ios").describe("Target platform"),
164729
+ platform: external_exports.enum(["ios", "android"]).optional().describe("Target platform"),
164607
164730
  rn_version: external_exports.coerce.string().default("unknown").describe('React Native version (e.g. "0.73.4")'),
164608
164731
  annotations: external_exports.array(annotationSchema).optional().describe(
164609
164732
  "User actions to annotate the report's commits with: each commit shows the action that preceded it."
@@ -164652,6 +164775,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164652
164775
  }
164653
164776
  let commitTree;
164654
164777
  let unattributedByCommit;
164778
+ let metroRoot;
164655
164779
  let renderSummary = null;
164656
164780
  if (sessionPaths.commitsPath) {
164657
164781
  const onDisk = await readCommitTree(sessionPaths.commitsPath);
@@ -164659,11 +164783,13 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164659
164783
  if (onDisk.meta?.unattributedByCommit) {
164660
164784
  unattributedByCommit = onDisk.meta.unattributedByCommit;
164661
164785
  }
164786
+ metroRoot = onDisk.meta?.projectRoot || void 0;
164662
164787
  renderSummary = parseRenderSummary(onDisk.meta?.renderSummary);
164663
164788
  } else {
164664
164789
  commitTree = { commits: [], hookNames: /* @__PURE__ */ new Map() };
164665
164790
  }
164666
164791
  const { detectedArchitecture, anyCompilerOptimized, hotCommitIndices, totalReactCommits } = sessionPaths;
164792
+ const platform = recordedPlatform(cpuProfile) ?? params.platform;
164667
164793
  const recordingDurationMs = cpuProfile ? (cpuProfile.endTime - cpuProfile.startTime) / 1e3 : 0;
164668
164794
  const input2 = {
164669
164795
  ...cpuProfile !== null && { flamegraph: cpuProfile },
@@ -164671,7 +164797,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164671
164797
  sessionMeta: {
164672
164798
  recordingDurationMs,
164673
164799
  deviceId: "simulator",
164674
- platform: params.platform,
164800
+ platform: platform ?? "ios",
164675
164801
  rnVersion: params.rn_version,
164676
164802
  projectRoot: params.project_root,
164677
164803
  ...detectedArchitecture !== null && {
@@ -164703,8 +164829,18 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164703
164829
  }
164704
164830
  const needsSourceIndex = pipelineOutput.componentFindings.length > 0 || renderSummary !== null && selectFrequentRerenders(renderSummary, createComponentOriginClassifier(null)).length > 0;
164705
164831
  let sourceIndex = null;
164832
+ let sourceWarning;
164833
+ let sourceRoot = params.project_root;
164706
164834
  try {
164707
- const astIndex = needsSourceIndex ? await buildAstIndexWithDiagnostics(params.project_root) : null;
164835
+ let astIndex = needsSourceIndex ? await buildAstIndexWithDiagnostics(sourceRoot, platform) : null;
164836
+ if (astIndex && astIndex.index.size === 0 && metroRoot && metroRoot !== sourceRoot) {
164837
+ const fromMetro = await buildAstIndexWithDiagnostics(metroRoot, platform);
164838
+ if (fromMetro.index.size > 0) {
164839
+ astIndex = fromMetro;
164840
+ sourceRoot = metroRoot;
164841
+ sourceWarning = `project_root "${params.project_root}" holds no components on the tool-server host, so the File column comes from Metro's project root "${metroRoot}".`;
164842
+ }
164843
+ }
164708
164844
  if (astIndex?.treeSitterAvailable) sourceIndex = astIndex.index;
164709
164845
  for (const finding of pipelineOutput.componentFindings) {
164710
164846
  const entry = astLookupCandidates(finding.component).map((k) => astIndex?.index.get(k)).find(Boolean);
@@ -164715,11 +164851,24 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164715
164851
  col: entry.col,
164716
164852
  isMemoized: entry.isMemoized,
164717
164853
  hasUseCallback: entry.hasUseCallback,
164718
- hasUseMemo: entry.hasUseMemo
164854
+ hasUseMemo: entry.hasUseMemo,
164855
+ ...entry.otherMatches?.length ? { otherMatches: entry.otherMatches } : {}
164719
164856
  };
164720
164857
  }
164721
164858
  }
164859
+ const findings = pipelineOutput.componentFindings;
164860
+ if (!astIndex) {
164861
+ } else if (!astIndex.treeSitterAvailable) {
164862
+ sourceWarning = "The tree-sitter parser could not be loaded, so the report gives no file for any component.";
164863
+ } else if (findings.length > 0 && !findings.some((f) => f.sourceLocation)) {
164864
+ const searched = sourceRoot === params.project_root ? "project_root" : "Metro's project root";
164865
+ const noFile = `No component in the report's table is defined under ${searched} "${sourceRoot}" (${astIndex.indexedFiles} source files on the tool-server host, ${astIndex.index.size} components), so the report gives no file for any of them. They may all be library components. If any of them is from the app, check project_root.`;
164866
+ sourceWarning = sourceWarning ? `${sourceWarning} ${noFile}` : noFile;
164867
+ } else if (metroRoot && await unrelatedPaths(metroRoot, sourceRoot)) {
164868
+ sourceWarning = `Metro serves this app from "${metroRoot}", but project_root is "${sourceRoot}", so the files in this report may be from another project.`;
164869
+ }
164722
164870
  } catch {
164871
+ sourceWarning = "Reading the project's source failed, so the report may lack file locations.";
164723
164872
  }
164724
164873
  const top5 = pipelineOutput.componentFindings.slice().sort((a, b) => b.totalMs - a.totalMs).slice(0, 5);
164725
164874
  await Promise.all(
@@ -164739,7 +164888,8 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164739
164888
  const { report, reportFile, hotCommitsTotal, hotCommitsShown } = await renderProfilingReport({
164740
164889
  hotCommitSummaries: pipelineOutput.hotCommitSummaries,
164741
164890
  componentFindings: pipelineOutput.componentFindings,
164742
- sessionContext: pipelineOutput.sessionContext,
164891
+ // Paths in the report count from the root the files were read from.
164892
+ sessionContext: { ...pipelineOutput.sessionContext, projectRoot: sourceRoot },
164743
164893
  recordingMs: pipelineOutput.recordingMs,
164744
164894
  anyRuntimeCompilerDetected: pipelineOutput.anyRuntimeCompilerDetected,
164745
164895
  reactCommits: pipelineOutput.reactCommits,
@@ -164753,6 +164903,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164753
164903
  });
164754
164904
  const artifacts = requireArtifacts(ctx);
164755
164905
  const result = {
164906
+ ...sourceWarning ? { warning: sourceWarning } : {},
164756
164907
  report,
164757
164908
  reportFile: await fileArtifact(artifacts, reportFile, "react-profile-report"),
164758
164909
  hotCommitsTotal,
@@ -164764,7 +164915,8 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
164764
164915
  }
164765
164916
  };
164766
164917
  if (hotCommitIndices === null) {
164767
- result["warning"] = "No React commit data \u2014 the DevTools hook may not be present in this runtime, or the commit-capture script failed to inject (check react-profiler-start output for errors).";
164918
+ const noCommits = "No React commit data \u2014 the DevTools hook may not be present in this runtime, or the commit-capture script failed to inject (check react-profiler-start output for errors).";
164919
+ result["warning"] = sourceWarning ? `${noCommits} ${sourceWarning}` : noCommits;
164768
164920
  }
164769
164921
  return result;
164770
164922
  }
@@ -164788,6 +164940,11 @@ Returns found: false if the component is not found in user-owned code (e.g. live
164788
164940
  When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col). Check it before assuming the returned file is the one you meant.`,
164789
164941
  zodSchema: zodSchema49,
164790
164942
  readOnly: true,
164943
+ // react-profiler-analyze runs the same AST lookup for each component in its
164944
+ // table (file, line and other matches) and adds the source of the located ones
164945
+ // among the top five; agents read any other file themselves. The SDK still
164946
+ // calls it.
164947
+ hideFromMcp: true,
164791
164948
  interaction: {
164792
164949
  startedMsg: ({ params }) => `Finding source for ${params.component_name}`,
164793
164950
  completedMsg: ({ params, result }) => `${result.found ? "Found" : "Could not find"} source for ${params.component_name}`,
@@ -164902,11 +165059,11 @@ function buildHotspots(nodes, samples, timeDeltas, topN2, reactOnly) {
164902
165059
  function renderMarkdownTable(entries) {
164903
165060
  if (entries.length === 0) return "_No hotspots found._";
164904
165061
  const header = "| Function | Location | Self (ms) | Total (ms) | Self % |";
164905
- const sep8 = "|---|---|---|---|---|";
165062
+ const sep10 = "|---|---|---|---|---|";
164906
165063
  const rows = entries.map(
164907
165064
  (e) => `| \`${e.function}\` | ${e.url || "\u2014"} | ${e.self_ms} | ${e.total_ms} | ${e.self_pct} |`
164908
165065
  );
164909
- return [header, sep8, ...rows].join("\n");
165066
+ return [header, sep10, ...rows].join("\n");
164910
165067
  }
164911
165068
  var zodSchema50 = external_exports.object({
164912
165069
  port: metroPortField,
@@ -164925,6 +165082,11 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
164925
165082
  Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
164926
165083
  zodSchema: zodSchema50,
164927
165084
  readOnly: true,
165085
+ // Agents use profiler-cpu-query mode top_functions, which reads the same
165086
+ // profile with per-sample intervals and idle filtered out, and has the same
165087
+ // react_only filter and Self % column. The SDK and the e2e-full suite still
165088
+ // call it.
165089
+ hideFromMcp: true,
164928
165090
  interaction: {
164929
165091
  startedMsg: () => "Summarizing React CPU profile",
164930
165092
  completedMsg: () => "Summarized React CPU profile",
@@ -165019,11 +165181,11 @@ function renderMarkdownTable2(entries) {
165019
165181
  if (entries.length === 0)
165020
165182
  return "_No render data found. Ensure React DevTools global hook is present._";
165021
165183
  const header = "| Component | Instances | Total (ms) | Self Base (ms) |";
165022
- const sep8 = "|---|---|---|---|";
165184
+ const sep10 = "|---|---|---|---|";
165023
165185
  const rows = entries.map(
165024
165186
  (e) => `| \`${e.component}\` | ${e.renderCount} | ${e.totalActualDuration_ms.toFixed(2)} | ${e.selfBaseDuration_ms.toFixed(2)} |`
165025
165187
  );
165026
- return [header, sep8, ...rows].join("\n");
165188
+ return [header, sep10, ...rows].join("\n");
165027
165189
  }
165028
165190
  var zodSchema51 = external_exports.object({
165029
165191
  port: metroPortField,
@@ -165503,7 +165665,7 @@ init_capability();
165503
165665
  var import_child_process4 = require("child_process");
165504
165666
  init_src2();
165505
165667
  var import_fs9 = require("fs");
165506
- var import_node_fs16 = require("node:fs");
165668
+ var import_node_fs17 = require("node:fs");
165507
165669
  var path40 = __toESM(require("path"));
165508
165670
  init_external_devices();
165509
165671
 
@@ -167174,7 +167336,7 @@ function resolveDefaultTemplatePath() {
167174
167336
  )
167175
167337
  ];
167176
167338
  for (const candidate of candidates) {
167177
- if ((0, import_node_fs16.existsSync)(candidate)) return candidate;
167339
+ if ((0, import_node_fs17.existsSync)(candidate)) return candidate;
167178
167340
  }
167179
167341
  throw new FailureError(
167180
167342
  `Argent.tracetemplate not found. Looked in:
@@ -169729,7 +169891,7 @@ var import_fs16 = require("fs");
169729
169891
  var import_child_process6 = require("child_process");
169730
169892
  var import_util15 = require("util");
169731
169893
  var import_os2 = __toESM(require("os"));
169732
- var import_path6 = __toESM(require("path"));
169894
+ var import_path7 = __toESM(require("path"));
169733
169895
 
169734
169896
  // ../tool-server/src/tools/screen-recording/watermark-asset.ts
169735
169897
  var WATERMARK_PNG_WIDTH = 900;
@@ -169831,7 +169993,7 @@ function buildWatermarkGraph(dims, opts) {
169831
169993
  ].join(";");
169832
169994
  }
169833
169995
  async function writeLogoTemp() {
169834
- const file2 = import_path6.default.join(
169996
+ const file2 = import_path7.default.join(
169835
169997
  import_os2.default.tmpdir(),
169836
169998
  `argent-watermark-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.png`
169837
169999
  );
@@ -171349,12 +171511,18 @@ function explainEmptyWindow(res, startMs, endMs) {
171349
171511
  }
171350
171512
  return `_No CPU samples fell inside ${window2} (${(endMs - startMs).toFixed(1)}ms wide), although it lies within the recorded range (${range}). The sampler runs roughly every ${res.medianIntervalMs > 0 ? res.medianIntervalMs.toFixed(1) : "13"}ms, so a window this narrow can contain none at all. **Absence of samples is not evidence that this commit was cheap.** Widen the window, or use \`mode=component_cpu\`._`;
171351
171513
  }
171352
- function coverageNote(res, startMs, endMs) {
171514
+ function isReactComponentName(name) {
171515
+ return /^[A-Z][A-Za-z0-9]*$/.test(name);
171516
+ }
171517
+ function coverageNote(res, startMs, endMs, reactOnly) {
171353
171518
  const widthMs = endMs - startMs;
171354
171519
  const lines = [
171355
171520
  `**Window:** ${startMs.toFixed(1)}ms \u2192 ${endMs.toFixed(1)}ms (${widthMs.toFixed(1)}ms)`,
171356
- `**Samples:** ${res.samplesInWindow} covering ${res.coveredMs.toFixed(1)}ms` + (res.idleMs > 0 ? `, of which ${res.idleMs.toFixed(1)}ms idle` : "") + ` \u2014 sampling interval ~${res.medianIntervalMs.toFixed(1)}ms. Self-times sum to sampled coverage, not to the window width.`
171521
+ `**Samples:** ${res.samplesInWindow} covering ${res.coveredMs.toFixed(1)}ms` + (res.idleMs > 0 ? `, of which ${res.idleMs.toFixed(1)}ms idle` : "") + ` \u2014 sampling interval ~${res.medianIntervalMs.toFixed(1)}ms. Self-times sum to sampled coverage, not to the window width. Self % is a share of that coverage.`
171357
171522
  ];
171523
+ if (reactOnly) {
171524
+ lines.push("**Filter:** React components only (PascalCase function names)");
171525
+ }
171358
171526
  if (widthMs > 0 && widthMs < 3 * res.medianIntervalMs) {
171359
171527
  lines.push(
171360
171528
  `> This window is narrower than ~3 sampling intervals, so every figure carries \xB11 sample (\u2248${res.medianIntervalMs.toFixed(1)}ms).`
@@ -171367,23 +171535,28 @@ function coverageNote(res, startMs, endMs) {
171367
171535
  }
171368
171536
  return lines.join("\n\n");
171369
171537
  }
171370
- function renderTopFunctions(index, topN2, startMs, endMs) {
171538
+ function renderTopFunctions(index, topN2, startMs, endMs, reactOnly = false) {
171371
171539
  const windowStart = startMs ?? index.intervalStartsMs[0] ?? 0;
171372
171540
  const windowEnd = endMs ?? index.timestampsMs[index.timestampsMs.length - 1] ?? 0;
171373
- const res = queryCpuWindow(index, windowStart, windowEnd, topN2);
171541
+ const res = queryCpuWindow(index, windowStart, windowEnd, reactOnly ? Infinity : topN2);
171374
171542
  if (res.hotspots.length === 0) return explainEmptyWindow(res, windowStart, windowEnd);
171375
- const header = "| Function | Self (ms) | Total (ms) | Location |";
171376
- const sep8 = "|---|---|---|---|";
171377
- const rows = res.hotspots.map((hs) => {
171543
+ const hotspots = reactOnly ? res.hotspots.filter((hs) => isReactComponentName(hs.name)).slice(0, topN2) : res.hotspots;
171544
+ if (hotspots.length === 0) {
171545
+ return `_No function sampled in ${windowStart.toFixed(1)}\u2013${windowEnd.toFixed(1)}ms has a PascalCase (React component) name. Query again without react_only to see the JS work._`;
171546
+ }
171547
+ const header = "| Function | Self (ms) | Self % | Total (ms) | Location |";
171548
+ const sep10 = "|---|---|---|---|---|";
171549
+ const rows = hotspots.map((hs) => {
171378
171550
  const loc = hs.url ? `${shortenUrl(hs.url)}${hs.lineNumber != null ? `:${hs.lineNumber}` : ""}` : "\u2014";
171379
- return `| \`${hs.name}\` | ${hs.selfMs} | ${hs.totalMs} | ${loc} |`;
171551
+ const selfPct = res.coveredMs > 0 ? `${(hs.selfMs / res.coveredMs * 100).toFixed(1)}%` : "\u2014";
171552
+ return `| \`${hs.name}\` | ${hs.selfMs} | ${selfPct} | ${hs.totalMs} | ${loc} |`;
171380
171553
  });
171381
171554
  return `## CPU Hotspots
171382
171555
 
171383
- ${coverageNote(res, windowStart, windowEnd)}
171556
+ ${coverageNote(res, windowStart, windowEnd, reactOnly)}
171384
171557
 
171385
171558
  ${header}
171386
- ${sep8}
171559
+ ${sep10}
171387
171560
  ${rows.join("\n")}`;
171388
171561
  }
171389
171562
  function renderCallTree(index, functionName, topN2, includeCallers) {
@@ -171587,7 +171760,10 @@ var zodSchema59 = external_exports.object({
171587
171760
  component_name: external_exports.string().optional().describe("Component name"),
171588
171761
  function_name: external_exports.string().optional().describe("Function name"),
171589
171762
  top_n: external_exports.coerce.number().int().positive().default(15).describe("Number of results to return"),
171590
- include_callers: external_exports.boolean().default(false).describe("Also show callers of the function")
171763
+ include_callers: external_exports.boolean().default(false).describe("Also show callers of the function"),
171764
+ react_only: external_exports.boolean().default(false).describe(
171765
+ "top_functions and time_window: list only React component functions (PascalCase names)"
171766
+ )
171591
171767
  });
171592
171768
  var profilerCpuQueryTool = {
171593
171769
  id: "profiler-cpu-query",
@@ -171600,6 +171776,7 @@ Modes:
171600
171776
  In top_functions and time_window, self-times are the summed sampling intervals of the samples that
171601
171777
  landed in the window, so they measure sampled coverage rather than the window's width and do not
171602
171778
  change if you widen the query. Their tables state how many samples they cover and how much was idle.
171779
+ Each row is one call path, so a function can have several rows and top_n counts rows.
171603
171780
  Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
171604
171781
  Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
171605
171782
  Fails if no CPU profile is stored; run react-profiler-stop (and ideally react-profiler-analyze) first.`,
@@ -171633,7 +171810,8 @@ Fails if no CPU profile is stored; run react-profiler-stop (and ideally react-pr
171633
171810
  index,
171634
171811
  params.top_n,
171635
171812
  params.time_window_ms?.start,
171636
- params.time_window_ms?.end
171813
+ params.time_window_ms?.end,
171814
+ params.react_only
171637
171815
  );
171638
171816
  case "time_window": {
171639
171817
  if (!params.time_window_ms) {
@@ -171648,7 +171826,8 @@ Fails if no CPU profile is stored; run react-profiler-stop (and ideally react-pr
171648
171826
  index,
171649
171827
  params.top_n,
171650
171828
  params.time_window_ms.start,
171651
- params.time_window_ms.end
171829
+ params.time_window_ms.end,
171830
+ params.react_only
171652
171831
  );
171653
171832
  }
171654
171833
  case "call_tree": {
@@ -173059,7 +173238,7 @@ Fails if the input has an unknown key (e.g. \`udids\` instead of \`devices\`); o
173059
173238
  // ../tool-server/src/tools/simulator/stop-metro.ts
173060
173239
  init_zod();
173061
173240
  var import_node_child_process47 = require("node:child_process");
173062
- var import_node_fs17 = require("node:fs");
173241
+ var import_node_fs18 = require("node:fs");
173063
173242
  init_src2();
173064
173243
  function parseNetstatListeningPids(netstatOutput, port) {
173065
173244
  const pids = /* @__PURE__ */ new Set();
@@ -173079,7 +173258,7 @@ function procListeningPids(port, proc = "/proc") {
173079
173258
  for (const table of ["tcp", "tcp6"]) {
173080
173259
  let rows;
173081
173260
  try {
173082
- rows = (0, import_node_fs17.readFileSync)(`${proc}/net/${table}`, "utf-8");
173261
+ rows = (0, import_node_fs18.readFileSync)(`${proc}/net/${table}`, "utf-8");
173083
173262
  } catch (error63) {
173084
173263
  if (table === "tcp6" && error63.code === "ENOENT") continue;
173085
173264
  throw error63;
@@ -173094,11 +173273,11 @@ function procListeningPids(port, proc = "/proc") {
173094
173273
  if (inodes.size === 0) return [];
173095
173274
  const owned = /* @__PURE__ */ new Set();
173096
173275
  const pids = [];
173097
- for (const entry of (0, import_node_fs17.readdirSync)(proc)) {
173276
+ for (const entry of (0, import_node_fs18.readdirSync)(proc)) {
173098
173277
  if (!/^\d+$/.test(entry)) continue;
173099
173278
  let fds;
173100
173279
  try {
173101
- fds = (0, import_node_fs17.readdirSync)(`${proc}/${entry}/fd`);
173280
+ fds = (0, import_node_fs18.readdirSync)(`${proc}/${entry}/fd`);
173102
173281
  } catch {
173103
173282
  continue;
173104
173283
  }
@@ -173106,7 +173285,7 @@ function procListeningPids(port, proc = "/proc") {
173106
173285
  for (const fd of fds) {
173107
173286
  let target;
173108
173287
  try {
173109
- target = (0, import_node_fs17.readlinkSync)(`${proc}/${entry}/fd/${fd}`);
173288
+ target = (0, import_node_fs18.readlinkSync)(`${proc}/${entry}/fd/${fd}`);
173110
173289
  } catch {
173111
173290
  continue;
173112
173291
  }
@@ -173125,8 +173304,8 @@ function procListeningPids(port, proc = "/proc") {
173125
173304
  }
173126
173305
  return pids;
173127
173306
  }
173128
- var LSOF_BIN = ["/usr/sbin/lsof", "/usr/bin/lsof"].find((p) => (0, import_node_fs17.existsSync)(p)) ?? "lsof";
173129
- var DARWIN_NETSTAT_BIN = (0, import_node_fs17.existsSync)("/usr/sbin/netstat") ? "/usr/sbin/netstat" : "netstat";
173307
+ var LSOF_BIN = ["/usr/sbin/lsof", "/usr/bin/lsof"].find((p) => (0, import_node_fs18.existsSync)(p)) ?? "lsof";
173308
+ var DARWIN_NETSTAT_BIN = (0, import_node_fs18.existsSync)("/usr/sbin/netstat") ? "/usr/sbin/netstat" : "netstat";
173130
173309
  function parseDarwinNetstatHasListener(netstatOutput, port) {
173131
173310
  return netstatOutput.split("\n").some((line) => {
173132
173311
  const cols = line.trim().split(/\s+/);
@@ -173245,7 +173424,7 @@ init_zod();
173245
173424
  // ../tool-server/src/tools/flows/flow-utils.ts
173246
173425
  var path48 = __toESM(require("node:path"));
173247
173426
  var fs63 = __toESM(require("node:fs/promises"));
173248
- var import_node_fs18 = require("node:fs");
173427
+ var import_node_fs19 = require("node:fs");
173249
173428
  init_src();
173250
173429
  init_src2();
173251
173430
  var import_yaml = __toESM(require_dist8());
@@ -175486,7 +175665,7 @@ async function followDanglingLink(linkPath) {
175486
175665
  return current;
175487
175666
  }
175488
175667
  async function isWritable(filePath) {
175489
- return fs63.access(filePath, import_node_fs18.constants.W_OK).then(
175668
+ return fs63.access(filePath, import_node_fs19.constants.W_OK).then(
175490
175669
  () => true,
175491
175670
  () => false
175492
175671
  );
@@ -180441,9 +180620,9 @@ function readableFrame(frame2, roots) {
180441
180620
  return match;
180442
180621
  }
180443
180622
  for (const root of roots) {
180444
- const relative7 = path54.relative(root, file2);
180445
- if (relative7 !== "" && !relative7.startsWith("..") && !path54.isAbsolute(relative7)) {
180446
- return `${relative7}${position}`;
180623
+ const relative9 = path54.relative(root, file2);
180624
+ if (relative9 !== "" && !relative9.startsWith("..") && !path54.isAbsolute(relative9)) {
180625
+ return `${relative9}${position}`;
180447
180626
  }
180448
180627
  }
180449
180628
  return `${file2}${position}`;
@@ -180790,7 +180969,7 @@ init_src2();
180790
180969
 
180791
180970
  // ../tool-server/src/tools/screenshot-diff/screenshot-diff.ts
180792
180971
  var import_promises18 = __toESM(require("fs/promises"));
180793
- var import_path7 = __toESM(require("path"));
180972
+ var import_path8 = __toESM(require("path"));
180794
180973
  var import_pngjs6 = __toESM(require_png());
180795
180974
  init_src2();
180796
180975
 
@@ -182511,12 +182690,12 @@ function topRegionsByPixelCount(regions, limit) {
182511
182690
  function resolveDiffArtifactPaths(options) {
182512
182691
  const currentName = outputArtifactBaseName(options.currentPath);
182513
182692
  return {
182514
- diffPath: import_path7.default.join(options.outputDir, `${currentName}-diff.png`),
182515
- contextDiffPath: import_path7.default.join(options.outputDir, `${currentName}-context-diff.png`)
182693
+ diffPath: import_path8.default.join(options.outputDir, `${currentName}-diff.png`),
182694
+ contextDiffPath: import_path8.default.join(options.outputDir, `${currentName}-context-diff.png`)
182516
182695
  };
182517
182696
  }
182518
182697
  function outputArtifactBaseName(filePath) {
182519
- const parsed = import_path7.default.parse(import_path7.default.basename(filePath));
182698
+ const parsed = import_path8.default.parse(import_path8.default.basename(filePath));
182520
182699
  return parsed.name || parsed.base;
182521
182700
  }
182522
182701
  async function writeDiffArtifacts(params) {
@@ -182589,7 +182768,7 @@ function luminanceFromOffset(data, offset) {
182589
182768
  return 0.2126 * data[offset] + 0.7152 * data[offset + 1] + 0.0722 * data[offset + 2];
182590
182769
  }
182591
182770
  async function writePngFile(filePath, png) {
182592
- await import_promises18.default.mkdir(import_path7.default.dirname(filePath), { recursive: true });
182771
+ await import_promises18.default.mkdir(import_path8.default.dirname(filePath), { recursive: true });
182593
182772
  await import_promises18.default.writeFile(filePath, import_pngjs6.PNG.sync.write(png));
182594
182773
  }
182595
182774
  function downscalePng(source, scale) {
@@ -183722,7 +183901,7 @@ var zodSchema71 = external_exports.object({
183722
183901
  "Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them, also in the e2e tests that tool: e2e-execute steps run, unless such a step sets updateBaselines itself. Over a link, the client writes the new baselines when the run ends."
183723
183902
  ),
183724
183903
  prerequisiteAcknowledged: external_exports.boolean().optional().describe(
183725
- "Set to true to confirm the execution prerequisite has been met. Required when a fragment defines an executionPrerequisite."
183904
+ "Set to true to confirm the execution prerequisite has been met. Required when a fragment defines an executionPrerequisite: without it, the call runs no step and returns the prerequisite text. Not a dry run: an e2e test with no prerequisite runs in full. To read a prerequisite without running, read executionPrerequisite in the YAML file."
183726
183905
  )
183727
183906
  }).superRefine((params, ctx) => {
183728
183907
  if (params.name === void 0 === (params.e2e_test_path === void 0)) {
@@ -184843,6 +185022,12 @@ Fails if the e2e test file does not exist.
184843
185022
  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.`,
184844
185023
  zodSchema: zodSchema72,
184845
185024
  readOnly: true,
185025
+ // When its gates pass, e2e-execute without prerequisiteAcknowledged returns
185026
+ // the same executionPrerequisite, from the same resolveFlowSource, before any
185027
+ // device work. An invalid test gets the gate's error, and a test with no
185028
+ // prerequisite runs. The SDK, `argent run` and e2e tool: steps still call it,
185029
+ // by its id or its alias.
185030
+ hideFromMcp: true,
184846
185031
  aliases: ["flow-read-prerequisite"],
184847
185032
  interaction: {
184848
185033
  startedMsg: () => "Reading e2e test prerequisite",
@@ -185364,12 +185549,15 @@ var updateArgentTool = {
185364
185549
 
185365
185550
  // ../tool-server/src/tools/system/dismiss-update.ts
185366
185551
  init_zod();
185552
+ var MAX_HOURS = 24 * 365 * 10;
185367
185553
  var zodSchema75 = external_exports.object({
185368
- hours: external_exports.number().min(0).describe("Number of hours to suppress the update notification")
185554
+ hours: external_exports.number().min(0).describe(
185555
+ "Hours until reminders resume: 168 is a week, 87600 is the longest, 0 turns them back on"
185556
+ )
185369
185557
  });
185370
185558
  var dismissUpdateTool = {
185371
185559
  id: "dismiss-update",
185372
- description: "Clear the Argent update notification for a number of hours. Use when the user asks to postpone or silence update reminders. Returns { message } confirming the suppression duration. Fails if the suppression state cannot be persisted.",
185560
+ description: "Postpone the Argent update reminder, on every tool-server on this machine, when the user wants it later or tomorrow, wants it stopped, or never wants it (87600 hours). Installs nothing. A memory or a reminder of your own does not change it. Returns { message, remindersResumeAt, persisted, pendingVersion }: tell the user when reminders resume, and if persisted is false, that it did not fully hold.",
185373
185561
  zodSchema: zodSchema75,
185374
185562
  interaction: {
185375
185563
  startedMsg: () => "Dismissing Argent update",
@@ -185378,10 +185566,27 @@ var dismissUpdateTool = {
185378
185566
  },
185379
185567
  services: () => ({}),
185380
185568
  async execute(_services, params, _options) {
185381
- const durationMs = params.hours * 60 * 60 * 1e3;
185382
- suppressUpdateNote(durationMs);
185569
+ const hours = Math.min(params.hours, MAX_HOURS);
185570
+ const { until, persisted } = suppressUpdateNote(hours * 60 * 60 * 1e3);
185571
+ const { updateInstallable, installableVersion } = getUpdateState();
185572
+ const pendingVersion = updateInstallable ? installableVersion : null;
185573
+ const end = new Date(until);
185574
+ const local = end.toLocaleString("en-US", { dateStyle: "medium", timeStyle: "short" });
185575
+ if (hours === 0) {
185576
+ return {
185577
+ message: pendingVersion ? `Update reminders are back on, so the reminder for v${pendingVersion} shows again.` : "Update reminders are back on. No update is pending right now.",
185578
+ remindersResumeAt: null,
185579
+ persisted,
185580
+ pendingVersion
185581
+ };
185582
+ }
185583
+ const pending = pendingVersion ? `v${pendingVersion} stays available and nothing was installed.` : `No update is pending right now; one that appears before then stays silent too.`;
185584
+ const scope = persisted ? `on every Argent tool-server on this machine` : `in this tool-server only, and only until it restarts: ~/.argent could not be written, so other tool-servers still show reminders`;
185383
185585
  return {
185384
- message: params.hours > 0 ? `Update notification dismissed for ${params.hours} hour(s).` : "Update notification suppression cleared. The notification will appear on the next tool call if an update is still available."
185586
+ message: `Update reminders are off until ${local} (${end.toISOString()}) ${scope}. ${pending} Tell the user when reminders resume. Remove any saved reminder about this update from your task list and do not bring it up again unless the user asks.`,
185587
+ remindersResumeAt: end.toISOString(),
185588
+ persisted,
185589
+ pendingVersion
185385
185590
  };
185386
185591
  }
185387
185592
  };
@@ -185390,7 +185595,7 @@ var dismissUpdateTool = {
185390
185595
  var import_node_crypto16 = __toESM(require("node:crypto"));
185391
185596
  var import_promises20 = __toESM(require("fs/promises"));
185392
185597
  var import_node_os17 = __toESM(require("node:os"));
185393
- var import_path8 = __toESM(require("path"));
185598
+ var import_path9 = __toESM(require("path"));
185394
185599
  init_zod();
185395
185600
  init_src2();
185396
185601
  init_device_info();
@@ -185539,7 +185744,7 @@ async function resolveOutputDir(params, options) {
185539
185744
  if (err.code === "EEXIST") return params.outputDir;
185540
185745
  }
185541
185746
  }
185542
- const dir = import_path8.default.join(
185747
+ const dir = import_path9.default.join(
185543
185748
  import_node_os17.default.tmpdir(),
185544
185749
  "argent-screenshot-diff",
185545
185750
  import_node_crypto16.default.randomBytes(6).toString("hex")
@@ -185648,7 +185853,7 @@ async function captureIosDeviceLiveInput(params) {
185648
185853
  }
185649
185854
  async function writeLivePng(outputDir, name, png) {
185650
185855
  const suffix = import_node_crypto16.default.randomBytes(4).toString("hex");
185651
- const destination = import_path8.default.join(outputDir, `${name}-${suffix}.live.png`);
185856
+ const destination = import_path9.default.join(outputDir, `${name}-${suffix}.live.png`);
185652
185857
  await import_promises20.default.mkdir(outputDir, { recursive: true });
185653
185858
  await import_promises20.default.writeFile(destination, png);
185654
185859
  return destination;
@@ -185666,7 +185871,7 @@ async function captureHarmonyLiveInput(params) {
185666
185871
  await ensureDep("hdc");
185667
185872
  const captured = await captureHarmonyScreenshotPng({ connectKey: params.connectKey, scale: 1 });
185668
185873
  const suffix = import_node_crypto16.default.randomBytes(4).toString("hex");
185669
- const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
185874
+ const destination = import_path9.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
185670
185875
  try {
185671
185876
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
185672
185877
  await import_promises20.default.copyFile(captured, destination);
@@ -185702,7 +185907,7 @@ async function captureLiveInput(params) {
185702
185907
  );
185703
185908
  }
185704
185909
  const suffix = import_node_crypto16.default.randomBytes(4).toString("hex");
185705
- const destination = import_path8.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
185910
+ const destination = import_path9.default.join(params.outputDir, `${params.name}-${suffix}.live.png`);
185706
185911
  await import_promises20.default.mkdir(params.outputDir, { recursive: true });
185707
185912
  await import_promises20.default.copyFile(capture.path, destination);
185708
185913
  return {
@@ -186220,6 +186425,9 @@ Use when seeding feature flags / auth tokens before an e2e test or asserting per
186220
186425
  Returns { value } for one key, { entries, count } for all keys, and { set } / { removed } / { cleared } for the writes. Fails if the device is not a Chromium (CDP) device, or the action is missing the \`key\` / \`value\` it needs.`,
186221
186426
  zodSchema: zodSchema81,
186222
186427
  searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
186428
+ // Agents read and write Web Storage with debugger-evaluate, which runs the same
186429
+ // Runtime.evaluate on the active page. The SDK and the e2e-full suite still call it.
186430
+ hideFromMcp: true,
186223
186431
  interaction: {
186224
186432
  startedMsg: ({ params }) => `${storageAction[params.action].started} ${params.store} storage`,
186225
186433
  completedMsg: ({ params }) => `${storageAction[params.action].completed} ${params.store} storage`,