@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.
- package/dist/cli-cmds.mjs +1 -1
- package/dist/installer.mjs +1 -1
- package/dist/tool-args.generated.d.ts +10 -8
- package/dist/tool-server.cjs +443 -235
- package/package.json +1 -1
- package/skills/argent-create-e2e/references/reliability-and-recovery.md +3 -3
- package/skills/argent-device-interact/SKILL.md +1 -1
- package/skills/argent-device-interact/references/chromium.md +1 -1
- package/skills/argent-device-interact/references/harmonyos.md +1 -1
- package/skills/argent-react-native-profiler/SKILL.md +2 -3
- package/skills/argent-screenshot-diff/SKILL.md +1 -1
- package/skills/argent-test-ui-flow/SKILL.md +1 -1
package/dist/tool-server.cjs
CHANGED
|
@@ -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
|
|
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@" +
|
|
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 " +
|
|
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" +
|
|
24843
|
+
formatted += " \x1B[36m" + formatLocation2(caller) + "\x1B[39m";
|
|
24844
24844
|
}
|
|
24845
24845
|
return formatted;
|
|
24846
24846
|
}
|
|
24847
|
-
function
|
|
24848
|
-
return
|
|
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
|
|
43052
|
-
var
|
|
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 =
|
|
43091
|
-
var file2 =
|
|
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,
|
|
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
|
|
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("." +
|
|
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(
|
|
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(
|
|
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] ===
|
|
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
|
|
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(
|
|
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 ?
|
|
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,
|
|
86687
|
+
fs78.readlink(link, function(err, resolvedPath2) {
|
|
86688
86688
|
if (err) {
|
|
86689
86689
|
return onError(err);
|
|
86690
86690
|
}
|
|
86691
|
-
checkLink(
|
|
86691
|
+
checkLink(resolvedPath2, target);
|
|
86692
86692
|
});
|
|
86693
86693
|
}
|
|
86694
|
-
function checkLink(
|
|
86694
|
+
function checkLink(resolvedPath2, target) {
|
|
86695
86695
|
if (dereference) {
|
|
86696
|
-
|
|
86696
|
+
resolvedPath2 = path63.resolve(basePath, resolvedPath2);
|
|
86697
86697
|
}
|
|
86698
86698
|
isWritable2(target, function(writable) {
|
|
86699
86699
|
if (writable) {
|
|
86700
|
-
return makeLink(
|
|
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 ===
|
|
86709
|
+
if (targetDest === resolvedPath2) {
|
|
86710
86710
|
return cb();
|
|
86711
86711
|
}
|
|
86712
86712
|
return rmFile(target, function() {
|
|
86713
|
-
makeLink(
|
|
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
|
|
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 (
|
|
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
|
|
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 (
|
|
87950
|
-
if (!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 &&
|
|
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
|
|
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 (
|
|
88470
|
-
if (!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 &&
|
|
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:
|
|
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 ??
|
|
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 && !
|
|
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(
|
|
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,
|
|
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
|
|
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 +=
|
|
94488
|
-
|
|
94487
|
+
comment += sep10 + cb;
|
|
94488
|
+
sep10 = "";
|
|
94489
94489
|
break;
|
|
94490
94490
|
}
|
|
94491
94491
|
case "newline":
|
|
94492
94492
|
if (comment)
|
|
94493
|
-
|
|
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:
|
|
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 ??
|
|
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 && !
|
|
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 && !
|
|
94602
|
-
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end,
|
|
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(
|
|
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 (
|
|
94626
|
-
for (const st of
|
|
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,
|
|
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
|
|
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 +=
|
|
94841
|
-
|
|
94840
|
+
value += sep10 + indent.slice(trimIndent) + content;
|
|
94841
|
+
sep10 = "\n";
|
|
94842
94842
|
} else if (indent.length > trimIndent || content[0] === " ") {
|
|
94843
|
-
if (
|
|
94844
|
-
|
|
94845
|
-
else if (!prevMoreIndented &&
|
|
94846
|
-
|
|
94847
|
-
value +=
|
|
94848
|
-
|
|
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 (
|
|
94851
|
+
if (sep10 === "\n")
|
|
94852
94852
|
value += "\n";
|
|
94853
94853
|
else
|
|
94854
|
-
|
|
94854
|
+
sep10 = "\n";
|
|
94855
94855
|
} else {
|
|
94856
|
-
value +=
|
|
94857
|
-
|
|
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
|
|
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 (
|
|
95046
|
-
res +=
|
|
95045
|
+
if (sep10 === "\n")
|
|
95046
|
+
res += sep10;
|
|
95047
95047
|
else
|
|
95048
|
-
|
|
95048
|
+
sep10 = "\n";
|
|
95049
95049
|
} else {
|
|
95050
|
-
res +=
|
|
95051
|
-
|
|
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 +
|
|
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:
|
|
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 (
|
|
95875
|
-
for (const st of
|
|
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
|
|
97042
|
+
let sep10;
|
|
97043
97043
|
if (scalar.end) {
|
|
97044
|
-
|
|
97045
|
-
|
|
97044
|
+
sep10 = scalar.end;
|
|
97045
|
+
sep10.push(this.sourceToken);
|
|
97046
97046
|
delete scalar.end;
|
|
97047
97047
|
} else
|
|
97048
|
-
|
|
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:
|
|
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
|
|
97207
|
-
|
|
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:
|
|
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
|
|
97409
|
-
|
|
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:
|
|
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.
|
|
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(
|
|
102537
|
+
async function resolveDevecoBinary(relative9) {
|
|
102538
102538
|
for (const root of devecoRoots()) {
|
|
102539
|
-
const candidate = (0, import_node_path6.join)(root,
|
|
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
|
-
|
|
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
|
|
103067
|
+
var unpersistedUntil = 0;
|
|
103061
103068
|
function getUpdateState() {
|
|
103062
103069
|
return { ...state2 };
|
|
103063
103070
|
}
|
|
103064
103071
|
function isUpdateNoteSuppressed() {
|
|
103065
|
-
return Date.now() <
|
|
103072
|
+
return Date.now() < Math.max(loadSuppressUntil(), unpersistedUntil);
|
|
103066
103073
|
}
|
|
103067
103074
|
function suppressUpdateNote(durationMs) {
|
|
103068
|
-
const
|
|
103069
|
-
|
|
103070
|
-
|
|
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
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
|
128078
|
-
if (
|
|
128079
|
-
const type = line.slice(0,
|
|
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(
|
|
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
|
|
131398
|
-
if (
|
|
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,
|
|
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
|
|
137889
|
-
const isDefault =
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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-
|
|
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
|
|
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,
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
149563
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
150937
|
-
(0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
163902
|
-
|
|
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
|
|
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
|
|
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 {
|
|
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(
|
|
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 ? `\`${
|
|
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 ?
|
|
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 ?
|
|
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 = `${
|
|
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"]).
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
171376
|
-
|
|
171377
|
-
|
|
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
|
-
|
|
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
|
-
${
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
173129
|
-
var DARWIN_NETSTAT_BIN = (0,
|
|
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
|
|
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,
|
|
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
|
|
180445
|
-
if (
|
|
180446
|
-
return `${
|
|
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
|
|
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:
|
|
182515
|
-
contextDiffPath:
|
|
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 =
|
|
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(
|
|
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(
|
|
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: "
|
|
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
|
|
185382
|
-
suppressUpdateNote(
|
|
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:
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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`,
|