@swmansion/argent 0.25.2-next.1 → 0.25.2-next.10
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 +36 -12
- package/dist/installer.mjs +1 -1
- package/dist/mcp-server.mjs +10 -2
- package/dist/tool-server.cjs +206 -150
- package/package.json +1 -1
- package/skills/argent-screen-recording/SKILL.md +1 -1
package/dist/cli-cmds.mjs
CHANGED
|
@@ -21872,7 +21872,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
21872
21872
|
var SESSION_ID2 = randomUUID5();
|
|
21873
21873
|
function readCliVersion() {
|
|
21874
21874
|
if (true) {
|
|
21875
|
-
return "0.25.2-next.
|
|
21875
|
+
return "0.25.2-next.10";
|
|
21876
21876
|
}
|
|
21877
21877
|
return "0.0.0";
|
|
21878
21878
|
}
|
|
@@ -23182,6 +23182,13 @@ function stepIndent(depth) {
|
|
|
23182
23182
|
if (typeof depth !== "number" || !Number.isInteger(depth) || depth <= 0) return "";
|
|
23183
23183
|
return " ".repeat(Math.min(depth, MAX_RENDER_DEPTH));
|
|
23184
23184
|
}
|
|
23185
|
+
function durationSuffix(ms) {
|
|
23186
|
+
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) return "";
|
|
23187
|
+
const tenths = Math.round(ms / 100);
|
|
23188
|
+
if (tenths < 600) return ` (${(tenths / 10).toFixed(1)}s)`;
|
|
23189
|
+
const seconds = Math.round(ms / 1e3);
|
|
23190
|
+
return ` (${Math.floor(seconds / 60)}m ${seconds % 60}s)`;
|
|
23191
|
+
}
|
|
23185
23192
|
function printHelp(toStderr = false) {
|
|
23186
23193
|
const print = toStderr ? console.error : console.log;
|
|
23187
23194
|
print(`Usage: argent flow <subcommand> [options]
|
|
@@ -23305,7 +23312,7 @@ function renderStepLine(s, n2, topFlow) {
|
|
|
23305
23312
|
const label = what ? `${s.kind} ${what}` : s.kind;
|
|
23306
23313
|
const reason = s.reason ? ` \u2014 ${s.reason}` : "";
|
|
23307
23314
|
const glyph = s.status === "pass" && s.warning ? "\u26A0" : STATUS_GLYPH[s.status];
|
|
23308
|
-
return ` ${glyph} ${String(n2).padStart(2)} ${stepIndent(s.depth)}${label}${where}${reason}`;
|
|
23315
|
+
return ` ${glyph} ${String(n2).padStart(2)} ${stepIndent(s.depth)}${label}${where}${durationSuffix(s.durationMs)}${reason}`;
|
|
23309
23316
|
}
|
|
23310
23317
|
function renderUnderStepLine(s, n2, text2) {
|
|
23311
23318
|
return `${" ".repeat(5 + Math.max(2, String(n2).length))}${stepIndent(s.depth)}${text2}`;
|
|
@@ -23328,7 +23335,7 @@ function renderSummary(report, opts = {}) {
|
|
|
23328
23335
|
const where = opts.withDevice && report.device ? ` (started on ${report.device})` : "";
|
|
23329
23336
|
const nothingCounted = report.ok && report.passed + report.failed + report.errored + report.skipped === 0;
|
|
23330
23337
|
const note = nothingCounted ? " (no test steps)" : "";
|
|
23331
|
-
return `${report.ok ? "PASS" : "FAIL"}${where} \u2014 ${report.passed} passed, ${report.failed} failed, ${report.errored} errored, ${report.skipped} skipped${warningsNote}${note}`;
|
|
23338
|
+
return `${report.ok ? "PASS" : "FAIL"}${where} \u2014 ${report.passed} passed, ${report.failed} failed, ${report.errored} errored, ${report.skipped} skipped${warningsNote}${note}${durationSuffix(report.durationMs)}`;
|
|
23332
23339
|
}
|
|
23333
23340
|
function renderArtifactLines(report) {
|
|
23334
23341
|
const lines = [];
|
|
@@ -23366,8 +23373,8 @@ function renderFailedSteps(report) {
|
|
|
23366
23373
|
}
|
|
23367
23374
|
return lines;
|
|
23368
23375
|
}
|
|
23369
|
-
function renderBatchSummary(counts) {
|
|
23370
|
-
return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} flow${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped`;
|
|
23376
|
+
function renderBatchSummary(counts, durationMs) {
|
|
23377
|
+
return `${counts.failed === 0 ? "PASS" : "FAIL"} \u2014 ${counts.total} flow${counts.total === 1 ? "" : "s"}: ${counts.passed} passed, ${counts.failed} failed, ${counts.skipped} skipped${durationSuffix(durationMs)}`;
|
|
23371
23378
|
}
|
|
23372
23379
|
var SAFE_ARTIFACT_NAME = FLOW_NAME_PATTERN;
|
|
23373
23380
|
var SAFE_FLOW_NAME = FLOW_NAME_PATTERN;
|
|
@@ -23682,6 +23689,7 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
|
|
|
23682
23689
|
const { callTool, baseUrl } = createToolsClient({ paths: options.paths });
|
|
23683
23690
|
const outputBase = args.output ? path14.resolve(args.output) : void 0;
|
|
23684
23691
|
const results = [];
|
|
23692
|
+
const batchStartedAt = Date.now();
|
|
23685
23693
|
let stopped = false;
|
|
23686
23694
|
for (const [i2, rel] of flows.entries()) {
|
|
23687
23695
|
if (!args.json) console.log(`[${i2 + 1}/${flows.length}] ${rel}`);
|
|
@@ -23737,11 +23745,14 @@ async function runFlowDirectory(dir, args, projectRoot, options) {
|
|
|
23737
23745
|
failed: results.filter((r2) => r2.status === "fail").length,
|
|
23738
23746
|
skipped: results.filter((r2) => r2.status === "skip").length
|
|
23739
23747
|
};
|
|
23748
|
+
const durationMs = Date.now() - batchStartedAt;
|
|
23740
23749
|
if (args.json) {
|
|
23741
|
-
console.log(
|
|
23750
|
+
console.log(
|
|
23751
|
+
JSON.stringify({ ok: counts.failed === 0, ...counts, durationMs, flows: results }, null, 2)
|
|
23752
|
+
);
|
|
23742
23753
|
} else {
|
|
23743
23754
|
console.log(`
|
|
23744
|
-
${renderBatchSummary(counts)}`);
|
|
23755
|
+
${renderBatchSummary(counts, durationMs)}`);
|
|
23745
23756
|
}
|
|
23746
23757
|
return exitAfterFlush(counts.failed === 0 ? 0 : 1);
|
|
23747
23758
|
}
|
|
@@ -25795,12 +25806,25 @@ function reportError(err, suggest) {
|
|
|
25795
25806
|
}
|
|
25796
25807
|
process.exit(2);
|
|
25797
25808
|
}
|
|
25809
|
+
function wrapText(text2, indent, width = 80) {
|
|
25810
|
+
const lines = [];
|
|
25811
|
+
let line = "";
|
|
25812
|
+
for (const word of text2.split(/\s+/).filter(Boolean)) {
|
|
25813
|
+
if (line && indent.length + line.length + 1 + word.length > width) {
|
|
25814
|
+
lines.push(indent + line);
|
|
25815
|
+
line = word;
|
|
25816
|
+
} else {
|
|
25817
|
+
line = line ? `${line} ${word}` : word;
|
|
25818
|
+
}
|
|
25819
|
+
}
|
|
25820
|
+
if (line) lines.push(indent + line);
|
|
25821
|
+
return lines;
|
|
25822
|
+
}
|
|
25798
25823
|
function printUsage() {
|
|
25799
|
-
const keys = CONFIG_SCHEMA.map((d) => d.key);
|
|
25800
|
-
const maxKey = keys.reduce((m, k) => Math.max(m, k.length), 0);
|
|
25801
25824
|
const keyLines = CONFIG_SCHEMA.map((d) => {
|
|
25802
|
-
const
|
|
25803
|
-
|
|
25825
|
+
const lines = [` ${d.key}`, ...wrapText(d.description, " ")];
|
|
25826
|
+
if (d.manageCommand) lines.push(import_picocolors2.default.dim(` [managed by \`${d.manageCommand}\`]`));
|
|
25827
|
+
return lines.join("\n");
|
|
25804
25828
|
});
|
|
25805
25829
|
console.log(`Usage: argent config <command> [options]
|
|
25806
25830
|
|
|
@@ -25816,7 +25840,7 @@ Commands:
|
|
|
25816
25840
|
unset <key> Remove a value at a scope (default global)
|
|
25817
25841
|
|
|
25818
25842
|
Recognized keys:
|
|
25819
|
-
${keyLines.join("\n")}
|
|
25843
|
+
${keyLines.join("\n\n")}
|
|
25820
25844
|
|
|
25821
25845
|
Run \`argent config <command> --help\` for command-specific help.`);
|
|
25822
25846
|
}
|
package/dist/installer.mjs
CHANGED
|
@@ -16725,7 +16725,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
16725
16725
|
var SESSION_ID = randomUUID4();
|
|
16726
16726
|
function readCliVersion() {
|
|
16727
16727
|
if (true) {
|
|
16728
|
-
return "0.25.2-next.
|
|
16728
|
+
return "0.25.2-next.10";
|
|
16729
16729
|
}
|
|
16730
16730
|
return "0.0.0";
|
|
16731
16731
|
}
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -18542,6 +18542,13 @@ function stepIndent(depth) {
|
|
|
18542
18542
|
if (typeof depth !== "number" || !Number.isInteger(depth) || depth <= 0) return "";
|
|
18543
18543
|
return " ".repeat(Math.min(depth, MAX_RENDER_DEPTH));
|
|
18544
18544
|
}
|
|
18545
|
+
function durationSuffix(ms) {
|
|
18546
|
+
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0) return "";
|
|
18547
|
+
const tenths = Math.round(ms / 100);
|
|
18548
|
+
if (tenths < 600) return ` (${(tenths / 10).toFixed(1)}s)`;
|
|
18549
|
+
const seconds = Math.round(ms / 1e3);
|
|
18550
|
+
return ` (${Math.floor(seconds / 60)}m ${seconds % 60}s)`;
|
|
18551
|
+
}
|
|
18545
18552
|
function stepLabel(step) {
|
|
18546
18553
|
if (step.kind === "echo") return step.message ?? "";
|
|
18547
18554
|
if (step.tool) return step.tool;
|
|
@@ -18565,9 +18572,10 @@ async function flowRunToMcpContent(result, ctx) {
|
|
|
18565
18572
|
const reason = step.reason ?? step.error;
|
|
18566
18573
|
const suffix = reason ? ` \u2014 ${reason}` : "";
|
|
18567
18574
|
const warning = step.warning ? ` \u26A0 ${step.warning}` : "";
|
|
18575
|
+
const timing = step.kind === "echo" ? "" : durationSuffix(step.durationMs);
|
|
18568
18576
|
blocks.push({
|
|
18569
18577
|
type: "text",
|
|
18570
|
-
text: `[${num}] ${glyph}${stepIndent(step.depth)}${stepLabel(step)}${suffix}${warning}`
|
|
18578
|
+
text: `[${num}] ${glyph}${stepIndent(step.depth)}${stepLabel(step)}${timing}${suffix}${warning}`
|
|
18571
18579
|
});
|
|
18572
18580
|
const scriptLog = typeof step.scriptLog === "string" ? step.scriptLog : "";
|
|
18573
18581
|
const scriptLogTruncated = step.scriptLogTruncated === true;
|
|
@@ -18589,7 +18597,7 @@ async function flowRunToMcpContent(result, ctx) {
|
|
|
18589
18597
|
const note = result.ok && counted === 0 ? " (no test steps)" : "";
|
|
18590
18598
|
blocks.push({
|
|
18591
18599
|
type: "text",
|
|
18592
|
-
text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped${note}`
|
|
18600
|
+
text: `${result.ok ? "PASS" : "FAIL"} \u2014 ${result.passed ?? 0} passed, ${result.failed ?? 0} failed, ${result.errored ?? 0} errored, ${result.skipped ?? 0} skipped${note}${durationSuffix(result.durationMs)}`
|
|
18593
18601
|
});
|
|
18594
18602
|
} else {
|
|
18595
18603
|
blocks.push({ type: "text", text: `Flow "${result.flow}" complete.` });
|
package/dist/tool-server.cjs
CHANGED
|
@@ -7599,51 +7599,51 @@ var init_he = __esm({
|
|
|
7599
7599
|
}
|
|
7600
7600
|
case "too_big": {
|
|
7601
7601
|
const sizing = getSizing(issue2.origin);
|
|
7602
|
-
const
|
|
7602
|
+
const subject2 = withDefinite(issue2.origin ?? "value");
|
|
7603
7603
|
if (issue2.origin === "string") {
|
|
7604
|
-
return `${sizing?.longLabel ?? "\u05D0\u05E8\u05D5\u05DA"} \u05DE\u05D3\u05D9: ${
|
|
7604
|
+
return `${sizing?.longLabel ?? "\u05D0\u05E8\u05D5\u05DA"} \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.maximum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA" : "\u05DC\u05DB\u05DC \u05D4\u05D9\u05D5\u05EA\u05E8"}`.trim();
|
|
7605
7605
|
}
|
|
7606
7606
|
if (issue2.origin === "number") {
|
|
7607
7607
|
const comparison = issue2.inclusive ? `\u05E7\u05D8\u05DF \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue2.maximum}` : `\u05E7\u05D8\u05DF \u05DE-${issue2.maximum}`;
|
|
7608
|
-
return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${
|
|
7608
|
+
return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
|
|
7609
7609
|
}
|
|
7610
7610
|
if (issue2.origin === "array" || issue2.origin === "set") {
|
|
7611
7611
|
const verb = issue2.origin === "set" ? "\u05E6\u05E8\u05D9\u05DB\u05D4" : "\u05E6\u05E8\u05D9\u05DA";
|
|
7612
7612
|
const comparison = issue2.inclusive ? `${issue2.maximum} ${sizing?.unit ?? ""} \u05D0\u05D5 \u05E4\u05D7\u05D5\u05EA` : `\u05E4\u05D7\u05D5\u05EA \u05DE-${issue2.maximum} ${sizing?.unit ?? ""}`;
|
|
7613
|
-
return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${
|
|
7613
|
+
return `\u05D2\u05D3\u05D5\u05DC \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
|
|
7614
7614
|
}
|
|
7615
7615
|
const adj = issue2.inclusive ? "<=" : "<";
|
|
7616
7616
|
const be = verbFor(issue2.origin ?? "value");
|
|
7617
7617
|
if (sizing?.unit) {
|
|
7618
|
-
return `${sizing.longLabel} \u05DE\u05D3\u05D9: ${
|
|
7618
|
+
return `${sizing.longLabel} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.maximum.toString()} ${sizing.unit}`;
|
|
7619
7619
|
}
|
|
7620
|
-
return `${sizing?.longLabel ?? "\u05D2\u05D3\u05D5\u05DC"} \u05DE\u05D3\u05D9: ${
|
|
7620
|
+
return `${sizing?.longLabel ?? "\u05D2\u05D3\u05D5\u05DC"} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.maximum.toString()}`;
|
|
7621
7621
|
}
|
|
7622
7622
|
case "too_small": {
|
|
7623
7623
|
const sizing = getSizing(issue2.origin);
|
|
7624
|
-
const
|
|
7624
|
+
const subject2 = withDefinite(issue2.origin ?? "value");
|
|
7625
7625
|
if (issue2.origin === "string") {
|
|
7626
|
-
return `${sizing?.shortLabel ?? "\u05E7\u05E6\u05E8"} \u05DE\u05D3\u05D9: ${
|
|
7626
|
+
return `${sizing?.shortLabel ?? "\u05E7\u05E6\u05E8"} \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05DB\u05D9\u05DC ${issue2.minimum.toString()} ${sizing?.unit ?? ""} ${issue2.inclusive ? "\u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8" : "\u05DC\u05E4\u05D7\u05D5\u05EA"}`.trim();
|
|
7627
7627
|
}
|
|
7628
7628
|
if (issue2.origin === "number") {
|
|
7629
7629
|
const comparison = issue2.inclusive ? `\u05D2\u05D3\u05D5\u05DC \u05D0\u05D5 \u05E9\u05D5\u05D5\u05D4 \u05DC-${issue2.minimum}` : `\u05D2\u05D3\u05D5\u05DC \u05DE-${issue2.minimum}`;
|
|
7630
|
-
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${
|
|
7630
|
+
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} \u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA ${comparison}`;
|
|
7631
7631
|
}
|
|
7632
7632
|
if (issue2.origin === "array" || issue2.origin === "set") {
|
|
7633
7633
|
const verb = issue2.origin === "set" ? "\u05E6\u05E8\u05D9\u05DB\u05D4" : "\u05E6\u05E8\u05D9\u05DA";
|
|
7634
7634
|
if (issue2.minimum === 1 && issue2.inclusive) {
|
|
7635
7635
|
const singularPhrase = issue2.origin === "set" ? "\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3" : "\u05DC\u05E4\u05D7\u05D5\u05EA \u05E4\u05E8\u05D9\u05D8 \u05D0\u05D7\u05D3";
|
|
7636
|
-
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${
|
|
7636
|
+
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${singularPhrase}`;
|
|
7637
7637
|
}
|
|
7638
7638
|
const comparison = issue2.inclusive ? `${issue2.minimum} ${sizing?.unit ?? ""} \u05D0\u05D5 \u05D9\u05D5\u05EA\u05E8` : `\u05D9\u05D5\u05EA\u05E8 \u05DE-${issue2.minimum} ${sizing?.unit ?? ""}`;
|
|
7639
|
-
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${
|
|
7639
|
+
return `\u05E7\u05D8\u05DF \u05DE\u05D3\u05D9: ${subject2} ${verb} \u05DC\u05D4\u05DB\u05D9\u05DC ${comparison}`.trim();
|
|
7640
7640
|
}
|
|
7641
7641
|
const adj = issue2.inclusive ? ">=" : ">";
|
|
7642
7642
|
const be = verbFor(issue2.origin ?? "value");
|
|
7643
7643
|
if (sizing?.unit) {
|
|
7644
|
-
return `${sizing.shortLabel} \u05DE\u05D3\u05D9: ${
|
|
7644
|
+
return `${sizing.shortLabel} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.minimum.toString()} ${sizing.unit}`;
|
|
7645
7645
|
}
|
|
7646
|
-
return `${sizing?.shortLabel ?? "\u05E7\u05D8\u05DF"} \u05DE\u05D3\u05D9: ${
|
|
7646
|
+
return `${sizing?.shortLabel ?? "\u05E7\u05D8\u05DF"} \u05DE\u05D3\u05D9: ${subject2} ${be} ${adj}${issue2.minimum.toString()}`;
|
|
7647
7647
|
}
|
|
7648
7648
|
case "invalid_format": {
|
|
7649
7649
|
const _issue = issue2;
|
|
@@ -70657,8 +70657,13 @@ function defaultAndroidRoots() {
|
|
|
70657
70657
|
"/opt/android-sdk",
|
|
70658
70658
|
"/usr/lib/android-sdk",
|
|
70659
70659
|
// Debian/Ubuntu `android-sdk` apt package
|
|
70660
|
-
"/usr/local/share/android-sdk"
|
|
70661
|
-
// Homebrew cask
|
|
70660
|
+
"/usr/local/share/android-sdk",
|
|
70661
|
+
// Homebrew cask (Intel prefix)
|
|
70662
|
+
// Where `brew install --cask android-commandlinetools` roots the SDK, so an
|
|
70663
|
+
// `sdkmanager`-installed platform-tools is found without setting ANDROID_HOME
|
|
70664
|
+
// — otherwise following the missing-adb hint still leaves the tool failing.
|
|
70665
|
+
"/opt/homebrew/share/android-commandlinetools",
|
|
70666
|
+
"/usr/local/share/android-commandlinetools"
|
|
70662
70667
|
];
|
|
70663
70668
|
if (process.platform === "win32") {
|
|
70664
70669
|
const localAppData = process.env.LOCALAPPDATA?.trim();
|
|
@@ -94799,7 +94804,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
94799
94804
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
94800
94805
|
function readCliVersion() {
|
|
94801
94806
|
if (true) {
|
|
94802
|
-
return "0.25.2-next.
|
|
94807
|
+
return "0.25.2-next.10";
|
|
94803
94808
|
}
|
|
94804
94809
|
return "0.0.0";
|
|
94805
94810
|
}
|
|
@@ -96058,8 +96063,8 @@ var DependencyMissingError = class extends Error {
|
|
|
96058
96063
|
var CACHE_TTL_MS2 = 6e4;
|
|
96059
96064
|
var cache3 = /* @__PURE__ */ new Map();
|
|
96060
96065
|
var INSTALL_HINTS = {
|
|
96061
|
-
"xcrun": "Xcode command-line tools
|
|
96062
|
-
"adb": "Android SDK Platform Tools not found. Install
|
|
96066
|
+
"xcrun": "Xcode command-line tools not found \u2014 iOS/tvOS simulators need a macOS host with them installed. On macOS, run `xcode-select --install` (or install Xcode from the App Store) and retry.",
|
|
96067
|
+
"adb": "Android SDK Platform Tools not found. Install `platform-tools` via Android Studio \u2192 SDK Manager or `sdkmanager 'platform-tools'` (`brew install --cask android-platform-tools` on macOS). If installed, ensure `adb` is on PATH or point `$ANDROID_HOME` (or the `android.sdkRoot` config key) at the SDK root (the resolver checks `<root>/platform-tools/adb`). Only required for Android devices and emulators.",
|
|
96063
96068
|
"emulator": "Android Emulator not found. Install via Android Studio \u2192 SDK Manager \u2192 Emulator, or `sdkmanager 'emulator'`. If installed, ensure `emulator` is on PATH or point `$ANDROID_HOME` (or the `android.sdkRoot` config key) at the SDK root (the resolver checks `<root>/emulator/emulator`). Only required to launch new Android emulators via `boot-device`.",
|
|
96064
96069
|
"sim-remote": "`sim-remote` CLI not found on PATH. Install via the radon-cloud project (see its README) and run `sim-remote login` before invoking any ios-remote tool. Only required for remote iOS simulators.",
|
|
96065
96070
|
"vega": "Vega SDK CLI not found. Install the Amazon Vega SDK and run `source ~/vega/env` so `vega` (or its `kepler` alias) is on PATH; the resolver also checks `~/vega/bin/vega`. Only required for Vega (Fire TV) devices."
|
|
@@ -96335,8 +96340,8 @@ async function listCertificatePem(commonName) {
|
|
|
96335
96340
|
}
|
|
96336
96341
|
}
|
|
96337
96342
|
var PEM_BLOCK_RE = /-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g;
|
|
96338
|
-
function subjectValue(
|
|
96339
|
-
for (const line of
|
|
96343
|
+
function subjectValue(subject2, key2) {
|
|
96344
|
+
for (const line of subject2.split("\n")) {
|
|
96340
96345
|
if (line.startsWith(`${key2}=`)) {
|
|
96341
96346
|
return line.slice(key2.length + 1).trim() || null;
|
|
96342
96347
|
}
|
|
@@ -109688,23 +109693,34 @@ async function captureScreenshot(ctx, opts = {}) {
|
|
|
109688
109693
|
let bytes = Buffer.from(cdpResult.data, "base64");
|
|
109689
109694
|
const rotation = opts.rotation && opts.rotation !== "Portrait" ? opts.rotation : null;
|
|
109690
109695
|
const scale = opts.scale != null && opts.scale > 0 && opts.scale < 1 ? opts.scale : null;
|
|
109696
|
+
const dropped = [];
|
|
109697
|
+
let dropReason;
|
|
109691
109698
|
if (rotation || scale) {
|
|
109692
109699
|
const sharp = tryLoadSharp();
|
|
109693
109700
|
if (!sharp) {
|
|
109694
109701
|
const features = [rotation && "rotation", scale && "scale"].filter(Boolean).join(" + ");
|
|
109695
109702
|
warnSharpMissingOnce(features);
|
|
109703
|
+
if (rotation) dropped.push("rotation");
|
|
109704
|
+
if (scale) dropped.push("scale");
|
|
109705
|
+
dropReason = "sharp-missing";
|
|
109696
109706
|
} else {
|
|
109697
109707
|
let pipeline = sharp(bytes);
|
|
109698
109708
|
if (rotation) pipeline = pipeline.rotate(ROTATION_DEGREES2[rotation]);
|
|
109699
109709
|
if (scale) {
|
|
109700
109710
|
const dims = readPngSize(bytes);
|
|
109701
109711
|
if (dims) {
|
|
109702
|
-
const
|
|
109703
|
-
const
|
|
109712
|
+
const quarterTurn = rotation === "LandscapeLeft" || rotation === "LandscapeRight";
|
|
109713
|
+
const rotatedW = quarterTurn ? dims.height : dims.width;
|
|
109714
|
+
const rotatedH = quarterTurn ? dims.width : dims.height;
|
|
109715
|
+
const targetW = Math.max(1, Math.round(rotatedW * scale));
|
|
109716
|
+
const targetH = Math.max(1, Math.round(rotatedH * scale));
|
|
109704
109717
|
pipeline = pipeline.resize(targetW, targetH, {
|
|
109705
109718
|
kernel: DOWNSCALER_TO_KERNEL[opts.downscaler ?? "lanczos3"],
|
|
109706
109719
|
fit: "fill"
|
|
109707
109720
|
});
|
|
109721
|
+
} else {
|
|
109722
|
+
dropped.push("scale");
|
|
109723
|
+
dropReason = "png-header-unreadable";
|
|
109708
109724
|
}
|
|
109709
109725
|
}
|
|
109710
109726
|
bytes = Buffer.from(await pipeline.png({ compressionLevel: 6 }).toBuffer());
|
|
@@ -109714,7 +109730,11 @@ async function captureScreenshot(ctx, opts = {}) {
|
|
|
109714
109730
|
const safeDeviceId = ctx.deviceId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
109715
109731
|
const filePath = path16.join(mediaDir(), `argent-screenshot-${safeDeviceId}-${stem}.png`);
|
|
109716
109732
|
fs18.writeFileSync(filePath, bytes);
|
|
109717
|
-
return {
|
|
109733
|
+
return {
|
|
109734
|
+
url: `file://${filePath}`,
|
|
109735
|
+
path: filePath,
|
|
109736
|
+
...dropped.length > 0 ? { droppedFeatures: dropped, dropReason } : {}
|
|
109737
|
+
};
|
|
109718
109738
|
}
|
|
109719
109739
|
function readPngSize(buf) {
|
|
109720
109740
|
const signature = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
@@ -114635,6 +114655,31 @@ async function handleWsCommand(msg, server) {
|
|
|
114635
114655
|
|
|
114636
114656
|
// ../tool-server/src/http.ts
|
|
114637
114657
|
init_device_info();
|
|
114658
|
+
|
|
114659
|
+
// ../tool-server/src/tools/screenshot/dropped-geometry.ts
|
|
114660
|
+
var RESULT_NOTE_KEY = "__argentNote";
|
|
114661
|
+
function requestedGeometry(params) {
|
|
114662
|
+
const requested = [];
|
|
114663
|
+
if (params.rotation !== void 0 && params.rotation !== "Portrait") requested.push("rotation");
|
|
114664
|
+
if (params.scale !== void 0 && params.scale > 0 && params.scale < 1) requested.push("scale");
|
|
114665
|
+
return requested;
|
|
114666
|
+
}
|
|
114667
|
+
function subject(dropped) {
|
|
114668
|
+
return dropped.length === 2 ? "scale and rotation were" : `${dropped[0]} was`;
|
|
114669
|
+
}
|
|
114670
|
+
function chromiumDropNote(dropped, reason = "sharp-missing") {
|
|
114671
|
+
if (dropped.length === 0) return void 0;
|
|
114672
|
+
if (reason === "png-header-unreadable") {
|
|
114673
|
+
return `${subject(dropped)} not applied: the PNG header could not be read. Any rotation was applied.`;
|
|
114674
|
+
}
|
|
114675
|
+
return `${subject(dropped)} not applied: install the optional \`sharp\` package in the tool-server environment.`;
|
|
114676
|
+
}
|
|
114677
|
+
function unsupportedDropNote(dropped, target) {
|
|
114678
|
+
if (dropped.length === 0) return void 0;
|
|
114679
|
+
return `${subject(dropped)} not applied: ${target} screenshots cannot be rotated.`;
|
|
114680
|
+
}
|
|
114681
|
+
|
|
114682
|
+
// ../tool-server/src/http.ts
|
|
114638
114683
|
var AUTO_SUPPRESS_MS = 30 * 60 * 1e3;
|
|
114639
114684
|
var AUTH_TOKEN_ENV = "ARGENT_AUTH_TOKEN";
|
|
114640
114685
|
var BEARER_PREFIX = "Bearer ";
|
|
@@ -114796,6 +114841,14 @@ function isWebsocketUpgradeAllowed(headers, policy) {
|
|
|
114796
114841
|
var UPLOAD_TTL_MS = 15 * 60 * 1e3;
|
|
114797
114842
|
var MAX_UPLOAD_STREAM_BYTES = 2 * 1024 * 1024 * 1024;
|
|
114798
114843
|
var MAX_PENDING_UPLOAD_BYTES = 8 * 1024 * 1024 * 1024;
|
|
114844
|
+
function takeToolNote(data) {
|
|
114845
|
+
if (typeof data !== "object" || data === null) return void 0;
|
|
114846
|
+
const bag = data;
|
|
114847
|
+
if (!(RESULT_NOTE_KEY in bag)) return void 0;
|
|
114848
|
+
const note = bag[RESULT_NOTE_KEY];
|
|
114849
|
+
delete bag[RESULT_NOTE_KEY];
|
|
114850
|
+
return typeof note === "string" && note.length > 0 ? note : void 0;
|
|
114851
|
+
}
|
|
114799
114852
|
function createHttpApp(registry2, options) {
|
|
114800
114853
|
const app = (0, import_express3.default)();
|
|
114801
114854
|
app.use(import_express3.default.json({ limit: "48mb" }));
|
|
@@ -115206,6 +115259,8 @@ function createHttpApp(registry2, options) {
|
|
|
115206
115259
|
if (signingNote) {
|
|
115207
115260
|
notes.push(signingNote);
|
|
115208
115261
|
}
|
|
115262
|
+
const toolNote = takeToolNote(data);
|
|
115263
|
+
if (toolNote) notes.push(toolNote);
|
|
115209
115264
|
const notePayload = notes.length > 0 ? { note: notes.join("\n\n") } : {};
|
|
115210
115265
|
if (wantsStream) {
|
|
115211
115266
|
writeLine({ event: "result", data, ...notePayload });
|
|
@@ -120038,11 +120093,11 @@ function clearCachedProfilerPaths(port, deviceId) {
|
|
|
120038
120093
|
}
|
|
120039
120094
|
|
|
120040
120095
|
// ../tool-server/src/tools/devices/boot-device.ts
|
|
120041
|
-
var
|
|
120096
|
+
var import_node_child_process24 = require("node:child_process");
|
|
120042
120097
|
var import_node_fs12 = require("node:fs");
|
|
120043
120098
|
var import_node_os11 = require("node:os");
|
|
120044
120099
|
var import_node_path15 = require("node:path");
|
|
120045
|
-
var
|
|
120100
|
+
var import_node_util17 = require("node:util");
|
|
120046
120101
|
init_zod();
|
|
120047
120102
|
init_src();
|
|
120048
120103
|
init_src2();
|
|
@@ -120128,39 +120183,6 @@ function androidHeadlessFromEnv() {
|
|
|
120128
120183
|
init_device_info();
|
|
120129
120184
|
init_external_devices();
|
|
120130
120185
|
|
|
120131
|
-
// ../tool-server/src/utils/hid-suppression.ts
|
|
120132
|
-
var import_node_child_process23 = require("node:child_process");
|
|
120133
|
-
var import_node_util17 = require("node:util");
|
|
120134
|
-
var execFileAsync17 = (0, import_node_util17.promisify)(import_node_child_process23.execFile);
|
|
120135
|
-
var WARMUP_TIMEOUT_MS = 4e4;
|
|
120136
|
-
var errText = (err) => err instanceof Error ? err.message : String(err);
|
|
120137
|
-
function startHidWarmUp(udid, deviceSet) {
|
|
120138
|
-
let binary;
|
|
120139
|
-
try {
|
|
120140
|
-
binary = simulatorServerBinaryPath();
|
|
120141
|
-
} catch (err) {
|
|
120142
|
-
process.stderr.write(
|
|
120143
|
-
`[hid-warmup ${udid.slice(0, 8)}] simulator-server binary not found (${errText(err)}); HID suppression protection is not active for this boot.
|
|
120144
|
-
`
|
|
120145
|
-
);
|
|
120146
|
-
return Promise.resolve();
|
|
120147
|
-
}
|
|
120148
|
-
const args = ["hid_warmup", "--id", udid];
|
|
120149
|
-
if (deviceSet) args.push("--device-set", deviceSet);
|
|
120150
|
-
return execFileAsync17(binary, args, {
|
|
120151
|
-
timeout: WARMUP_TIMEOUT_MS,
|
|
120152
|
-
// It prints CoreSimulator noise on every failed attach attempt — ~80KB
|
|
120153
|
-
// against a device that never comes up. Well under Node's 1MB default, but
|
|
120154
|
-
// the default is the only headroom there is, so name one.
|
|
120155
|
-
maxBuffer: 4 * 1024 * 1024
|
|
120156
|
-
}).then(() => void 0).catch((err) => {
|
|
120157
|
-
process.stderr.write(
|
|
120158
|
-
`[hid-warmup ${udid.slice(0, 8)}] warm-up did not run (${errText(err)}); input may be silently dropped on this simulator.
|
|
120159
|
-
`
|
|
120160
|
-
);
|
|
120161
|
-
});
|
|
120162
|
-
}
|
|
120163
|
-
|
|
120164
120186
|
// ../tool-server/src/utils/vega-vvd.ts
|
|
120165
120187
|
init_src2();
|
|
120166
120188
|
init_adb();
|
|
@@ -120291,7 +120313,7 @@ async function waitForVvdRunning(timeoutMs) {
|
|
|
120291
120313
|
}
|
|
120292
120314
|
|
|
120293
120315
|
// ../tool-server/src/tools/devices/boot-electron.ts
|
|
120294
|
-
var
|
|
120316
|
+
var import_node_child_process23 = require("node:child_process");
|
|
120295
120317
|
var fs31 = __toESM(require("node:fs"));
|
|
120296
120318
|
var path26 = __toESM(require("node:path"));
|
|
120297
120319
|
init_src2();
|
|
@@ -120487,7 +120509,7 @@ async function bootElectronApp(options) {
|
|
|
120487
120509
|
];
|
|
120488
120510
|
let child;
|
|
120489
120511
|
try {
|
|
120490
|
-
child = (0,
|
|
120512
|
+
child = (0, import_node_child_process23.spawn)(launcher.command, args, {
|
|
120491
120513
|
detached: true,
|
|
120492
120514
|
// stdout is discarded, not piped: nothing reads it, and an unread pipe
|
|
120493
120515
|
// blocks the child's writes once the OS buffer fills. The
|
|
@@ -120609,7 +120631,7 @@ async function bootElectronApp(options) {
|
|
|
120609
120631
|
}
|
|
120610
120632
|
|
|
120611
120633
|
// ../tool-server/src/tools/devices/boot-device.ts
|
|
120612
|
-
var
|
|
120634
|
+
var execFileAsync17 = (0, import_node_util17.promisify)(import_node_child_process24.execFile);
|
|
120613
120635
|
var zodSchema9 = external_exports.object({
|
|
120614
120636
|
udid: external_exports.string().optional().describe(
|
|
120615
120637
|
"iOS: simulator UDID to boot (from `list-devices`). Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`."
|
|
@@ -120813,7 +120835,7 @@ async function bootIos(udid, registry2, force, headless) {
|
|
|
120813
120835
|
const deviceSet = await deviceSetForUdid(udid);
|
|
120814
120836
|
const prefix = simctlPrefix(deviceSet);
|
|
120815
120837
|
if (force && simState === "Booted") {
|
|
120816
|
-
await
|
|
120838
|
+
await execFileAsync17("xcrun", [...prefix, "shutdown", udid]);
|
|
120817
120839
|
}
|
|
120818
120840
|
const needsPreBoot = simState === "Shutdown" || force && simState === "Booted";
|
|
120819
120841
|
if (needsPreBoot) {
|
|
@@ -120824,15 +120846,13 @@ async function bootIos(udid, registry2, force, headless) {
|
|
|
120824
120846
|
);
|
|
120825
120847
|
});
|
|
120826
120848
|
}
|
|
120827
|
-
|
|
120828
|
-
const hidWarmUp = alreadyUp || isTvOs ? Promise.resolve() : startHidWarmUp(udid, deviceSet);
|
|
120829
|
-
await execFileAsync18("xcrun", [...prefix, "boot", udid]).catch((err) => {
|
|
120849
|
+
await execFileAsync17("xcrun", [...prefix, "boot", udid]).catch((err) => {
|
|
120830
120850
|
const message = err instanceof Error ? err.message : String(err);
|
|
120831
120851
|
if (!message.includes("Unable to boot device in current state: Booted")) {
|
|
120832
120852
|
throw err;
|
|
120833
120853
|
}
|
|
120834
120854
|
});
|
|
120835
|
-
await
|
|
120855
|
+
await execFileAsync17("xcrun", [...prefix, "bootstatus", udid, "-b"]);
|
|
120836
120856
|
if (isTvOs && needsPreBoot) {
|
|
120837
120857
|
await registry2.disposeService(`${TV_CONTROL_NAMESPACE}:${udid}`).catch((err) => {
|
|
120838
120858
|
if (err instanceof ServiceNotFoundError) return;
|
|
@@ -120851,7 +120871,6 @@ async function bootIos(udid, registry2, force, headless) {
|
|
|
120851
120871
|
});
|
|
120852
120872
|
}
|
|
120853
120873
|
await ensureAutomationEnabled(udid).catch(() => void 0);
|
|
120854
|
-
await hidWarmUp;
|
|
120855
120874
|
const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
|
|
120856
120875
|
const ndApi = await registry2.resolveService(ndRef.urn, ndRef.options);
|
|
120857
120876
|
await ndApi.reverifyEnv().catch(() => {
|
|
@@ -120861,7 +120880,7 @@ async function bootIos(udid, registry2, force, headless) {
|
|
|
120861
120880
|
return buildInitFailedResult(udid, initFailure);
|
|
120862
120881
|
}
|
|
120863
120882
|
if (!deviceSet) {
|
|
120864
|
-
await
|
|
120883
|
+
await execFileAsync17("defaults", [
|
|
120865
120884
|
"write",
|
|
120866
120885
|
"com.apple.iphonesimulator",
|
|
120867
120886
|
"CurrentDeviceUDID",
|
|
@@ -120870,7 +120889,7 @@ async function bootIos(udid, registry2, force, headless) {
|
|
|
120870
120889
|
});
|
|
120871
120890
|
}
|
|
120872
120891
|
if (!headless && !iosHeadlessFromEnv() && !deviceSet) {
|
|
120873
|
-
await
|
|
120892
|
+
await execFileAsync17("open", ["-a", "Simulator.app"]).catch(() => execFileAsync17("open", ["-b", "com.apple.dt.Devices"])).catch(() => {
|
|
120874
120893
|
});
|
|
120875
120894
|
}
|
|
120876
120895
|
return { platform: "ios", udid, booted: true };
|
|
@@ -120917,7 +120936,7 @@ async function attemptBoot(params) {
|
|
|
120917
120936
|
emulatorLogFd = (0, import_node_fs12.openSync)(logPath, "w");
|
|
120918
120937
|
stdio = ["ignore", emulatorLogFd, emulatorLogFd];
|
|
120919
120938
|
}
|
|
120920
|
-
const child = (0,
|
|
120939
|
+
const child = (0, import_node_child_process24.spawn)(params.emulatorBinary, params.emulatorArgs, {
|
|
120921
120940
|
detached: true,
|
|
120922
120941
|
stdio
|
|
120923
120942
|
});
|
|
@@ -121542,11 +121561,11 @@ var BUNDLE_ID_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9._-]*$/;
|
|
|
121542
121561
|
var BUNDLE_ID_MESSAGE = "bundleId may only contain letters, digits, '.', '_' and '-', and may not start with '-' or '.'";
|
|
121543
121562
|
|
|
121544
121563
|
// ../tool-server/src/tools/launch-app/platforms/ios.ts
|
|
121545
|
-
var
|
|
121546
|
-
var
|
|
121564
|
+
var import_node_child_process25 = require("node:child_process");
|
|
121565
|
+
var import_node_util18 = require("node:util");
|
|
121547
121566
|
init_src2();
|
|
121548
121567
|
init_external_devices();
|
|
121549
|
-
var
|
|
121568
|
+
var execFileAsync18 = (0, import_node_util18.promisify)(import_node_child_process25.execFile);
|
|
121550
121569
|
function makeIosImpl(registry2) {
|
|
121551
121570
|
return {
|
|
121552
121571
|
requires: ["xcrun"],
|
|
@@ -121561,7 +121580,7 @@ function makeIosImpl(registry2) {
|
|
|
121561
121580
|
if (blocked) return blocked;
|
|
121562
121581
|
}
|
|
121563
121582
|
try {
|
|
121564
|
-
await
|
|
121583
|
+
await execFileAsync18(
|
|
121565
121584
|
"xcrun",
|
|
121566
121585
|
await simctlArgsForUdid(params.udid, ["launch", params.udid, params.bundleId])
|
|
121567
121586
|
);
|
|
@@ -121853,11 +121872,11 @@ init_zod();
|
|
|
121853
121872
|
init_device_info();
|
|
121854
121873
|
|
|
121855
121874
|
// ../tool-server/src/tools/restart-app/platforms/ios.ts
|
|
121856
|
-
var
|
|
121857
|
-
var
|
|
121875
|
+
var import_node_child_process26 = require("node:child_process");
|
|
121876
|
+
var import_node_util19 = require("node:util");
|
|
121858
121877
|
init_src2();
|
|
121859
121878
|
init_external_devices();
|
|
121860
|
-
var
|
|
121879
|
+
var execFileAsync19 = (0, import_node_util19.promisify)(import_node_child_process26.execFile);
|
|
121861
121880
|
function makeIosImpl2(registry2) {
|
|
121862
121881
|
return {
|
|
121863
121882
|
requires: ["xcrun"],
|
|
@@ -121873,11 +121892,11 @@ function makeIosImpl2(registry2) {
|
|
|
121873
121892
|
if (blocked) return blocked;
|
|
121874
121893
|
}
|
|
121875
121894
|
try {
|
|
121876
|
-
await
|
|
121895
|
+
await execFileAsync19("xcrun", await simctlArgsForUdid(udid, ["terminate", udid, bundleId]));
|
|
121877
121896
|
} catch {
|
|
121878
121897
|
}
|
|
121879
121898
|
try {
|
|
121880
|
-
await
|
|
121899
|
+
await execFileAsync19("xcrun", await simctlArgsForUdid(udid, ["launch", udid, bundleId]));
|
|
121881
121900
|
} catch (err) {
|
|
121882
121901
|
throw new FailureError(
|
|
121883
121902
|
`Failed to restart iOS app ${bundleId} on ${udid}.`,
|
|
@@ -122055,11 +122074,11 @@ Returns { restarted, bundleId }. Fails if the app is not installed.`,
|
|
|
122055
122074
|
init_zod();
|
|
122056
122075
|
|
|
122057
122076
|
// ../tool-server/src/tools/reinstall-app/platforms/ios.ts
|
|
122058
|
-
var
|
|
122059
|
-
var
|
|
122077
|
+
var import_node_child_process27 = require("node:child_process");
|
|
122078
|
+
var import_node_util20 = require("node:util");
|
|
122060
122079
|
var import_node_path16 = require("node:path");
|
|
122061
122080
|
init_src2();
|
|
122062
|
-
var
|
|
122081
|
+
var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process27.execFile);
|
|
122063
122082
|
var iosImpl = {
|
|
122064
122083
|
requires: ["xcrun"],
|
|
122065
122084
|
handler: async (_services, params) => {
|
|
@@ -122067,11 +122086,11 @@ var iosImpl = {
|
|
|
122067
122086
|
const absolute = (0, import_node_path16.resolve)(appPath);
|
|
122068
122087
|
const { nativeId, prefix } = await simctlTargetForUdid(udid);
|
|
122069
122088
|
try {
|
|
122070
|
-
await
|
|
122089
|
+
await execFileAsync20("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
|
|
122071
122090
|
} catch {
|
|
122072
122091
|
}
|
|
122073
122092
|
try {
|
|
122074
|
-
await
|
|
122093
|
+
await execFileAsync20("xcrun", [...prefix, "install", nativeId, absolute]);
|
|
122075
122094
|
} catch (err) {
|
|
122076
122095
|
throw new FailureError(
|
|
122077
122096
|
`Failed to install iOS app bundle on ${udid}.`,
|
|
@@ -122248,10 +122267,10 @@ var PERMISSION_NAMES = [
|
|
|
122248
122267
|
];
|
|
122249
122268
|
|
|
122250
122269
|
// ../tool-server/src/tools/settings-permissions/platforms/ios.ts
|
|
122251
|
-
var
|
|
122252
|
-
var
|
|
122270
|
+
var import_node_child_process28 = require("node:child_process");
|
|
122271
|
+
var import_node_util21 = require("node:util");
|
|
122253
122272
|
init_src2();
|
|
122254
|
-
var
|
|
122273
|
+
var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
|
|
122255
122274
|
var SIMCTL_ACTION = {
|
|
122256
122275
|
grant: "grant",
|
|
122257
122276
|
deny: "revoke",
|
|
@@ -122276,7 +122295,7 @@ var NON_TCC_GRANT_NEEDS_INSTALL = /* @__PURE__ */ new Set([
|
|
|
122276
122295
|
]);
|
|
122277
122296
|
var localBackend = {
|
|
122278
122297
|
async run(udid, simctlAction, service, bundleId) {
|
|
122279
|
-
await
|
|
122298
|
+
await execFileAsync21(
|
|
122280
122299
|
"xcrun",
|
|
122281
122300
|
await simctlArgsForUdid(udid, ["privacy", udid, simctlAction, service, bundleId]),
|
|
122282
122301
|
{ timeout: 3e4 }
|
|
@@ -122284,7 +122303,7 @@ var localBackend = {
|
|
|
122284
122303
|
},
|
|
122285
122304
|
async isInstalled(udid, bundleId) {
|
|
122286
122305
|
try {
|
|
122287
|
-
await
|
|
122306
|
+
await execFileAsync21(
|
|
122288
122307
|
"xcrun",
|
|
122289
122308
|
await simctlArgsForUdid(udid, ["get_app_container", udid, bundleId]),
|
|
122290
122309
|
{ timeout: 15e3 }
|
|
@@ -122567,8 +122586,8 @@ init_zod();
|
|
|
122567
122586
|
init_device_info();
|
|
122568
122587
|
|
|
122569
122588
|
// ../tool-server/src/tools/open-url/platforms/ios.ts
|
|
122570
|
-
var
|
|
122571
|
-
var
|
|
122589
|
+
var import_node_child_process29 = require("node:child_process");
|
|
122590
|
+
var import_node_util22 = require("node:util");
|
|
122572
122591
|
init_src2();
|
|
122573
122592
|
|
|
122574
122593
|
// ../tool-server/src/tools/open-url/deep-link-note.ts
|
|
@@ -122578,12 +122597,12 @@ function httpDeepLinkNote(url2) {
|
|
|
122578
122597
|
}
|
|
122579
122598
|
|
|
122580
122599
|
// ../tool-server/src/tools/open-url/platforms/ios.ts
|
|
122581
|
-
var
|
|
122600
|
+
var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
|
|
122582
122601
|
var iosImpl3 = {
|
|
122583
122602
|
requires: ["xcrun"],
|
|
122584
122603
|
handler: async (_services, params) => {
|
|
122585
122604
|
try {
|
|
122586
|
-
await
|
|
122605
|
+
await execFileAsync22(
|
|
122587
122606
|
"xcrun",
|
|
122588
122607
|
await simctlArgsForUdid(params.udid, ["openurl", params.udid, params.url])
|
|
122589
122608
|
);
|
|
@@ -122739,8 +122758,8 @@ Returns { opened, url, note? }. note carries the deep-linking caveat when a web
|
|
|
122739
122758
|
};
|
|
122740
122759
|
|
|
122741
122760
|
// ../tool-server/src/tools/screenshot/index.ts
|
|
122742
|
-
var
|
|
122743
|
-
var
|
|
122761
|
+
var import_node_child_process30 = require("node:child_process");
|
|
122762
|
+
var import_node_util23 = require("node:util");
|
|
122744
122763
|
var os13 = __toESM(require("node:os"));
|
|
122745
122764
|
var path27 = __toESM(require("node:path"));
|
|
122746
122765
|
init_zod();
|
|
@@ -123312,7 +123331,7 @@ function scalePng(src, scale) {
|
|
|
123312
123331
|
|
|
123313
123332
|
// ../tool-server/src/tools/screenshot/index.ts
|
|
123314
123333
|
var fs33 = __toESM(require("node:fs/promises"));
|
|
123315
|
-
var
|
|
123334
|
+
var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
|
|
123316
123335
|
var zodSchema15 = external_exports.object({
|
|
123317
123336
|
udid: external_exports.string().describe(
|
|
123318
123337
|
"Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, or Chromium id)."
|
|
@@ -123353,11 +123372,11 @@ async function tvScreenshot(udid, scale, signal) {
|
|
|
123353
123372
|
os13.tmpdir(),
|
|
123354
123373
|
`argent-tv-screenshot-${udid.slice(0, 8)}-${process.hrtime.bigint()}.png`
|
|
123355
123374
|
);
|
|
123356
|
-
await
|
|
123375
|
+
await execFileAsync23("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
|
|
123357
123376
|
signal
|
|
123358
123377
|
});
|
|
123359
123378
|
if (scale < 1) {
|
|
123360
|
-
await
|
|
123379
|
+
await execFileAsync23("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
|
|
123361
123380
|
signal
|
|
123362
123381
|
}).catch(() => {
|
|
123363
123382
|
});
|
|
@@ -123367,7 +123386,7 @@ async function tvScreenshot(udid, scale, signal) {
|
|
|
123367
123386
|
async function tvTargetLongSide(file2, scale) {
|
|
123368
123387
|
let longSide = 3840;
|
|
123369
123388
|
try {
|
|
123370
|
-
const { stdout } = await
|
|
123389
|
+
const { stdout } = await execFileAsync23("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
|
|
123371
123390
|
const width = Number(/pixelWidth:\s*(\d+)/.exec(stdout)?.[1]);
|
|
123372
123391
|
const height = Number(/pixelHeight:\s*(\d+)/.exec(stdout)?.[1]);
|
|
123373
123392
|
if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
|
|
@@ -123381,7 +123400,7 @@ async function downscalePngInPlace(file2, scale, signal) {
|
|
|
123381
123400
|
if (scale >= 1) {
|
|
123382
123401
|
return;
|
|
123383
123402
|
}
|
|
123384
|
-
await
|
|
123403
|
+
await execFileAsync23("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
|
|
123385
123404
|
signal
|
|
123386
123405
|
}).catch(() => {
|
|
123387
123406
|
});
|
|
@@ -123413,17 +123432,20 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
|
|
|
123413
123432
|
if (device.platform === "chromium") {
|
|
123414
123433
|
const ref2 = chromiumCdpRef(device);
|
|
123415
123434
|
const chromium = await registry2.resolveService(ref2.urn, ref2.options);
|
|
123416
|
-
const
|
|
123435
|
+
const captured = await chromium.captureScreenshot({
|
|
123417
123436
|
rotation: params.rotation,
|
|
123418
123437
|
scale: params.scale,
|
|
123419
123438
|
downscaler: params.downscaler
|
|
123420
123439
|
});
|
|
123421
123440
|
const image2 = await requireArtifacts(ctx).register({
|
|
123422
|
-
hostPath:
|
|
123441
|
+
hostPath: captured.path,
|
|
123423
123442
|
kind: "screenshot",
|
|
123424
123443
|
mimeType: "image/png"
|
|
123425
123444
|
});
|
|
123426
|
-
|
|
123445
|
+
const requested = requestedGeometry(params);
|
|
123446
|
+
const dropped = (captured.droppedFeatures ?? []).filter((f) => requested.includes(f));
|
|
123447
|
+
const note = chromiumDropNote(dropped, captured.dropReason);
|
|
123448
|
+
return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
|
|
123427
123449
|
}
|
|
123428
123450
|
if (isIosPhysicalDevice(device)) {
|
|
123429
123451
|
const pngPath = await iosPhysicalScreenshot(registry2, device, scale);
|
|
@@ -123432,7 +123454,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
|
|
|
123432
123454
|
kind: "screenshot",
|
|
123433
123455
|
mimeType: "image/png"
|
|
123434
123456
|
});
|
|
123435
|
-
|
|
123457
|
+
const note = unsupportedDropNote(
|
|
123458
|
+
requestedGeometry(params).filter((f) => f === "rotation"),
|
|
123459
|
+
"physical iPhone"
|
|
123460
|
+
);
|
|
123461
|
+
return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
|
|
123436
123462
|
}
|
|
123437
123463
|
if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
|
|
123438
123464
|
const pngPath = await tvScreenshot(params.udid, scale, signal);
|
|
@@ -123441,7 +123467,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
|
|
|
123441
123467
|
kind: "screenshot",
|
|
123442
123468
|
mimeType: "image/png"
|
|
123443
123469
|
});
|
|
123444
|
-
|
|
123470
|
+
const note = unsupportedDropNote(
|
|
123471
|
+
requestedGeometry(params).filter((f) => f === "rotation"),
|
|
123472
|
+
"Apple TV"
|
|
123473
|
+
);
|
|
123474
|
+
return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
|
|
123445
123475
|
}
|
|
123446
123476
|
if (device.platform === "vega") {
|
|
123447
123477
|
const pngPath = await captureVegaScreenshotPng({ scale: params.scale });
|
|
@@ -123450,7 +123480,11 @@ Fails if the simulator-server / emulator backend / Chromium CDP is not reachable
|
|
|
123450
123480
|
kind: "screenshot",
|
|
123451
123481
|
mimeType: "image/png"
|
|
123452
123482
|
});
|
|
123453
|
-
|
|
123483
|
+
const note = unsupportedDropNote(
|
|
123484
|
+
requestedGeometry(params).filter((f) => f === "rotation"),
|
|
123485
|
+
"Vega (Fire TV)"
|
|
123486
|
+
);
|
|
123487
|
+
return { image: image2, ...note ? { [RESULT_NOTE_KEY]: note } : {} };
|
|
123454
123488
|
}
|
|
123455
123489
|
const ref = simulatorServerRef(device);
|
|
123456
123490
|
const api = await registry2.resolveService(ref.urn, ref.options);
|
|
@@ -125373,12 +125407,12 @@ var shakeZodSchema = external_exports.object({
|
|
|
125373
125407
|
});
|
|
125374
125408
|
|
|
125375
125409
|
// ../tool-server/src/tools/shake/platforms/ios.ts
|
|
125376
|
-
var
|
|
125377
|
-
var
|
|
125410
|
+
var import_node_child_process32 = require("node:child_process");
|
|
125411
|
+
var import_node_util24 = require("node:util");
|
|
125378
125412
|
init_src2();
|
|
125379
125413
|
|
|
125380
125414
|
// ../tool-server/src/utils/window-shake.ts
|
|
125381
|
-
var
|
|
125415
|
+
var import_node_child_process31 = require("node:child_process");
|
|
125382
125416
|
init_src();
|
|
125383
125417
|
var MICROINTERACTIONS_FLAG = "microinteractions";
|
|
125384
125418
|
var AMPLITUDE = 22;
|
|
@@ -125485,7 +125519,7 @@ end run
|
|
|
125485
125519
|
}
|
|
125486
125520
|
function runOsascript(script) {
|
|
125487
125521
|
return new Promise((resolve14, reject) => {
|
|
125488
|
-
const child = (0,
|
|
125522
|
+
const child = (0, import_node_child_process31.execFile)(
|
|
125489
125523
|
"/usr/bin/osascript",
|
|
125490
125524
|
["-"],
|
|
125491
125525
|
{ timeout: OSASCRIPT_TIMEOUT_MS },
|
|
@@ -125578,7 +125612,7 @@ async function prepareHostWindowShake(target) {
|
|
|
125578
125612
|
}
|
|
125579
125613
|
|
|
125580
125614
|
// ../tool-server/src/tools/shake/platforms/ios.ts
|
|
125581
|
-
var
|
|
125615
|
+
var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process32.execFile);
|
|
125582
125616
|
var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
|
|
125583
125617
|
var SHAKE_INTERVAL_MS = 400;
|
|
125584
125618
|
var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -125618,7 +125652,7 @@ var iosImpl4 = {
|
|
|
125618
125652
|
if (i > 0) await sleep11(SHAKE_INTERVAL_MS);
|
|
125619
125653
|
shaker.begin();
|
|
125620
125654
|
try {
|
|
125621
|
-
await
|
|
125655
|
+
await execFileAsync24("xcrun", args, { timeout: 15e3 });
|
|
125622
125656
|
} catch (err) {
|
|
125623
125657
|
const error52 = err instanceof Error ? err : new Error(String(err));
|
|
125624
125658
|
throw shakeFailure(udid, error52.message, error52);
|
|
@@ -138460,8 +138494,8 @@ var import_util8 = require("util");
|
|
|
138460
138494
|
var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
|
|
138461
138495
|
var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
|
|
138462
138496
|
async function execFileAsyncWithTimeout(file2, args, options = {}) {
|
|
138463
|
-
const
|
|
138464
|
-
const { stdout, stderr } = await
|
|
138497
|
+
const execFileAsync29 = (0, import_util8.promisify)(import_child_process2.execFile);
|
|
138498
|
+
const { stdout, stderr } = await execFileAsync29(file2, args, {
|
|
138465
138499
|
encoding: "utf-8",
|
|
138466
138500
|
...options,
|
|
138467
138501
|
// Applied after ...options so a caller cannot weaken the guards; maxBuffer
|
|
@@ -142487,7 +142521,7 @@ var WATERMARK_PNG_HEIGHT = 277;
|
|
|
142487
142521
|
var WATERMARK_PNG_BASE64 = "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";
|
|
142488
142522
|
|
|
142489
142523
|
// ../tool-server/src/tools/screen-recording/watermark.ts
|
|
142490
|
-
var
|
|
142524
|
+
var execFileAsync25 = (0, import_util9.promisify)(import_child_process6.execFile);
|
|
142491
142525
|
var OUTPUT_FPS = 30;
|
|
142492
142526
|
var FFMPEG_FALLBACK_PATHS = [
|
|
142493
142527
|
"/opt/homebrew/bin/ffmpeg",
|
|
@@ -142504,7 +142538,7 @@ var MASK_DARK_MAX_LUMA = 90;
|
|
|
142504
142538
|
var MASK_LIGHT_MIN_LUMA = 165;
|
|
142505
142539
|
async function resolveBinary(name, fallbacks) {
|
|
142506
142540
|
try {
|
|
142507
|
-
await
|
|
142541
|
+
await execFileAsync25("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
|
|
142508
142542
|
return name;
|
|
142509
142543
|
} catch {
|
|
142510
142544
|
}
|
|
@@ -142703,7 +142737,7 @@ async function startCaptureLocked(api, params) {
|
|
|
142703
142737
|
const ffmpeg = await resolveFfmpeg();
|
|
142704
142738
|
if (!ffmpeg) {
|
|
142705
142739
|
throw new FailureError(
|
|
142706
|
-
"`ffmpeg` was not found on PATH. Install
|
|
142740
|
+
"`ffmpeg` was not found on PATH. Install a build with libx264 (`brew install ffmpeg` on macOS, `apt install ffmpeg` on Debian/Ubuntu) and retry.",
|
|
142707
142741
|
{
|
|
142708
142742
|
error_code: FAILURE_CODES.SCREEN_RECORDING_FFMPEG_NOT_FOUND,
|
|
142709
142743
|
failure_stage: "screen_recording_resolve_ffmpeg",
|
|
@@ -145204,7 +145238,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
|
|
|
145204
145238
|
|
|
145205
145239
|
// ../tool-server/src/tools/simulator/stop-metro.ts
|
|
145206
145240
|
init_zod();
|
|
145207
|
-
var
|
|
145241
|
+
var import_node_child_process33 = require("node:child_process");
|
|
145208
145242
|
function parseNetstatListeningPids(netstatOutput, port) {
|
|
145209
145243
|
const pids = /* @__PURE__ */ new Set();
|
|
145210
145244
|
for (const line of netstatOutput.split(/\r?\n/)) {
|
|
@@ -145220,7 +145254,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
|
|
|
145220
145254
|
}
|
|
145221
145255
|
function listeningPids(port) {
|
|
145222
145256
|
if (process.platform === "win32") {
|
|
145223
|
-
const output2 = (0,
|
|
145257
|
+
const output2 = (0, import_node_child_process33.execFileSync)("netstat", ["-ano"], {
|
|
145224
145258
|
encoding: "utf-8",
|
|
145225
145259
|
timeout: 5e3,
|
|
145226
145260
|
// `netstat -ano` dumps every socket on the host; overflowing Node's
|
|
@@ -145229,7 +145263,7 @@ function listeningPids(port) {
|
|
|
145229
145263
|
});
|
|
145230
145264
|
return parseNetstatListeningPids(output2, port);
|
|
145231
145265
|
}
|
|
145232
|
-
const output = (0,
|
|
145266
|
+
const output = (0, import_node_child_process33.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
|
|
145233
145267
|
encoding: "utf-8",
|
|
145234
145268
|
timeout: 5e3
|
|
145235
145269
|
}).trim();
|
|
@@ -150346,7 +150380,7 @@ var import_node_url4 = require("node:url");
|
|
|
150346
150380
|
init_src2();
|
|
150347
150381
|
|
|
150348
150382
|
// ../tool-server/src/tools/flows/script/flow-script-executor.ts
|
|
150349
|
-
var
|
|
150383
|
+
var import_node_child_process34 = require("node:child_process");
|
|
150350
150384
|
var fs56 = __toESM(require("node:fs"));
|
|
150351
150385
|
var os17 = __toESM(require("node:os"));
|
|
150352
150386
|
var path41 = __toESM(require("node:path"));
|
|
@@ -150731,7 +150765,7 @@ var FlowScriptExecutor = class {
|
|
|
150731
150765
|
detached: process.platform !== "win32",
|
|
150732
150766
|
windowsHide: process.platform === "win32"
|
|
150733
150767
|
};
|
|
150734
|
-
child = (0,
|
|
150768
|
+
child = (0, import_node_child_process34.fork)(scriptPath, [], forkOptions);
|
|
150735
150769
|
} catch (err) {
|
|
150736
150770
|
return emptyResult(
|
|
150737
150771
|
{ kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
|
|
@@ -151172,7 +151206,7 @@ async function stopProcessTree(child, graceMs) {
|
|
|
151172
151206
|
if (process.platform === "win32") {
|
|
151173
151207
|
if (hasExited(child)) return;
|
|
151174
151208
|
tryKill(() => {
|
|
151175
|
-
const killer = (0,
|
|
151209
|
+
const killer = (0, import_node_child_process34.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
|
|
151176
151210
|
windowsHide: true,
|
|
151177
151211
|
stdio: "ignore"
|
|
151178
151212
|
});
|
|
@@ -151966,7 +152000,7 @@ init_src2();
|
|
|
151966
152000
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
151967
152001
|
var import_child_process8 = require("child_process");
|
|
151968
152002
|
var import_util10 = require("util");
|
|
151969
|
-
var
|
|
152003
|
+
var execFileAsync26 = (0, import_util10.promisify)(import_child_process8.execFile);
|
|
151970
152004
|
var OCR_TIMEOUT_MS = 1e4;
|
|
151971
152005
|
var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
151972
152006
|
var TESSERACT_BINARY = "tesseract";
|
|
@@ -152011,7 +152045,7 @@ async function extractOcrTextBlocks(imagePath) {
|
|
|
152011
152045
|
}
|
|
152012
152046
|
}
|
|
152013
152047
|
async function recognizeTsv(imagePath) {
|
|
152014
|
-
const { stdout } = await
|
|
152048
|
+
const { stdout } = await execFileAsync26(
|
|
152015
152049
|
TESSERACT_BINARY,
|
|
152016
152050
|
[
|
|
152017
152051
|
imagePath,
|
|
@@ -154236,11 +154270,11 @@ async function runSnapshot(env, opts) {
|
|
|
154236
154270
|
}
|
|
154237
154271
|
|
|
154238
154272
|
// ../tool-server/src/utils/status-bar.ts
|
|
154239
|
-
var
|
|
154240
|
-
var
|
|
154273
|
+
var import_node_child_process35 = require("node:child_process");
|
|
154274
|
+
var import_node_util25 = require("node:util");
|
|
154241
154275
|
init_adb();
|
|
154242
154276
|
init_device_info();
|
|
154243
|
-
var
|
|
154277
|
+
var execFileAsync27 = (0, import_node_util25.promisify)(import_node_child_process35.execFile);
|
|
154244
154278
|
var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
|
|
154245
154279
|
var IOS_STATUS_BAR_OVERRIDE = [
|
|
154246
154280
|
"override",
|
|
@@ -154264,7 +154298,7 @@ async function pinStatusBar(device, signal) {
|
|
|
154264
154298
|
if (isIosPhysicalDevice(device)) return false;
|
|
154265
154299
|
try {
|
|
154266
154300
|
if (device.platform === "ios") {
|
|
154267
|
-
await
|
|
154301
|
+
await execFileAsync27(
|
|
154268
154302
|
"xcrun",
|
|
154269
154303
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
|
|
154270
154304
|
);
|
|
@@ -154300,7 +154334,7 @@ async function pinStatusBar(device, signal) {
|
|
|
154300
154334
|
async function restoreStatusBar(device) {
|
|
154301
154335
|
try {
|
|
154302
154336
|
if (device.platform === "ios") {
|
|
154303
|
-
await
|
|
154337
|
+
await execFileAsync27(
|
|
154304
154338
|
"xcrun",
|
|
154305
154339
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
|
|
154306
154340
|
);
|
|
@@ -154764,6 +154798,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
|
|
|
154764
154798
|
fileInputs: fileInputs3,
|
|
154765
154799
|
services: () => ({}),
|
|
154766
154800
|
async execute(_services, params, ctx) {
|
|
154801
|
+
const runStartedAt = Date.now();
|
|
154767
154802
|
const signal = ctx?.signal;
|
|
154768
154803
|
const { filePath, flowName, viaUpload } = await resolveFlowSource(
|
|
154769
154804
|
params,
|
|
@@ -154806,6 +154841,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
|
|
|
154806
154841
|
executionPrerequisite: flow.executionPrerequisite
|
|
154807
154842
|
};
|
|
154808
154843
|
}
|
|
154844
|
+
const resolveStartedAt = Date.now();
|
|
154809
154845
|
const resolved = await resolveRunDevice(
|
|
154810
154846
|
registry2,
|
|
154811
154847
|
ctx,
|
|
@@ -154838,6 +154874,7 @@ Returns a per-step report: the first failure stops the run and the rest report a
|
|
|
154838
154874
|
stopped: false,
|
|
154839
154875
|
pinned: statusBarPinned,
|
|
154840
154876
|
owned: resolved.booted ? [resolved.booted] : [],
|
|
154877
|
+
...resolved.booted ? { hoistedBootMs: Date.now() - resolveStartedAt } : {},
|
|
154841
154878
|
chromiumLaunched: false,
|
|
154842
154879
|
snapshotApps: /* @__PURE__ */ new Map(),
|
|
154843
154880
|
projectRoot: params.project_root,
|
|
@@ -154863,7 +154900,8 @@ Returns a per-step report: the first failure stops the run and the rest report a
|
|
|
154863
154900
|
device?.id ?? "",
|
|
154864
154901
|
flow.executionPrerequisite,
|
|
154865
154902
|
state3.reports,
|
|
154866
|
-
aborted2
|
|
154903
|
+
aborted2,
|
|
154904
|
+
{ startedAt: runStartedAt, durationMs: Date.now() - runStartedAt }
|
|
154867
154905
|
);
|
|
154868
154906
|
}
|
|
154869
154907
|
};
|
|
@@ -155004,7 +155042,7 @@ async function frontChromiumPage(registry2, device) {
|
|
|
155004
155042
|
} catch {
|
|
155005
155043
|
}
|
|
155006
155044
|
}
|
|
155007
|
-
function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2) {
|
|
155045
|
+
function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2, timing) {
|
|
155008
155046
|
let passed = 0;
|
|
155009
155047
|
let failed2 = 0;
|
|
155010
155048
|
let skipped = 0;
|
|
@@ -155030,7 +155068,8 @@ function summarize(flowName, deviceId, executionPrerequisite, steps, aborted2) {
|
|
|
155030
155068
|
failed: failed2,
|
|
155031
155069
|
skipped,
|
|
155032
155070
|
errored,
|
|
155033
|
-
steps
|
|
155071
|
+
steps,
|
|
155072
|
+
...timing
|
|
155034
155073
|
};
|
|
155035
155074
|
}
|
|
155036
155075
|
function pushReport(state3, report) {
|
|
@@ -155121,7 +155160,13 @@ async function execSteps(state3, steps, scope) {
|
|
|
155121
155160
|
await execBlockStep(state3, step, scope);
|
|
155122
155161
|
continue;
|
|
155123
155162
|
}
|
|
155163
|
+
let startedAt = Date.now();
|
|
155164
|
+
if (step.kind === "launch" && state3.hoistedBootMs !== void 0) {
|
|
155165
|
+
startedAt -= state3.hoistedBootMs;
|
|
155166
|
+
state3.hoistedBootMs = void 0;
|
|
155167
|
+
}
|
|
155124
155168
|
const report = await execLeafStep(state3, step, index, scope);
|
|
155169
|
+
if (report.status !== "skip") report.durationMs = Date.now() - startedAt;
|
|
155125
155170
|
pushReport(state3, report);
|
|
155126
155171
|
if (report.status === "fail" || report.status === "error") state3.stopped = true;
|
|
155127
155172
|
}
|
|
@@ -155164,6 +155209,7 @@ async function execWhenStep(state3, step, scope) {
|
|
|
155164
155209
|
...depthOf(scope)
|
|
155165
155210
|
};
|
|
155166
155211
|
const inner = childScope(scope);
|
|
155212
|
+
const guardStartedAt = Date.now();
|
|
155167
155213
|
let met;
|
|
155168
155214
|
if (step.condition.kind === "platform") {
|
|
155169
155215
|
const guardEnv = deviceEnv(state3);
|
|
@@ -155180,7 +155226,8 @@ async function execWhenStep(state3, step, scope) {
|
|
|
155180
155226
|
pushReport(state3, {
|
|
155181
155227
|
...marker,
|
|
155182
155228
|
status: "error",
|
|
155183
|
-
reason: `could not evaluate when guard (${label}): ${probe3.reason}
|
|
155229
|
+
reason: `could not evaluate when guard (${label}): ${probe3.reason}`,
|
|
155230
|
+
durationMs: Date.now() - guardStartedAt
|
|
155184
155231
|
});
|
|
155185
155232
|
state3.stopped = true;
|
|
155186
155233
|
reportBlockSkipped(state3, step.steps, inner, "when guard errored");
|
|
@@ -155193,12 +155240,18 @@ async function execWhenStep(state3, step, scope) {
|
|
|
155193
155240
|
pushReport(state3, {
|
|
155194
155241
|
...marker,
|
|
155195
155242
|
status: "skip",
|
|
155196
|
-
reason: `condition not met (${label}) \u2014 block skipped (${n} step${n === 1 ? "" : "s"})
|
|
155243
|
+
reason: `condition not met (${label}) \u2014 block skipped (${n} step${n === 1 ? "" : "s"})`,
|
|
155244
|
+
durationMs: Date.now() - guardStartedAt
|
|
155197
155245
|
});
|
|
155198
155246
|
reportBlockSkipped(state3, step.steps, inner, "when block skipped");
|
|
155199
155247
|
return;
|
|
155200
155248
|
}
|
|
155201
|
-
pushReport(state3, {
|
|
155249
|
+
pushReport(state3, {
|
|
155250
|
+
...marker,
|
|
155251
|
+
status: "pass",
|
|
155252
|
+
reason: `condition met (${label})`,
|
|
155253
|
+
durationMs: Date.now() - guardStartedAt
|
|
155254
|
+
});
|
|
155202
155255
|
await execSteps(state3, step.steps, inner);
|
|
155203
155256
|
}
|
|
155204
155257
|
function baselineKeyFor(canonicalPath, flowName) {
|
|
@@ -155209,6 +155262,7 @@ async function execRunStep(state3, step, scope) {
|
|
|
155209
155262
|
const index = state3.reports.length;
|
|
155210
155263
|
const target = step.flow;
|
|
155211
155264
|
const display = runDisplayName(target, scope);
|
|
155265
|
+
const startedAt = Date.now();
|
|
155212
155266
|
const fail = (reason) => {
|
|
155213
155267
|
pushReport(state3, {
|
|
155214
155268
|
index,
|
|
@@ -155217,7 +155271,8 @@ async function execRunStep(state3, step, scope) {
|
|
|
155217
155271
|
flow: display,
|
|
155218
155272
|
target,
|
|
155219
155273
|
reason,
|
|
155220
|
-
...depthOf(scope)
|
|
155274
|
+
...depthOf(scope),
|
|
155275
|
+
durationMs: Date.now() - startedAt
|
|
155221
155276
|
});
|
|
155222
155277
|
state3.stopped = true;
|
|
155223
155278
|
};
|
|
@@ -155255,7 +155310,8 @@ async function execRunStep(state3, step, scope) {
|
|
|
155255
155310
|
status: "pass",
|
|
155256
155311
|
flow: display,
|
|
155257
155312
|
target,
|
|
155258
|
-
...depthOf(scope)
|
|
155313
|
+
...depthOf(scope),
|
|
155314
|
+
durationMs: Date.now() - startedAt
|
|
155259
155315
|
});
|
|
155260
155316
|
await execSteps(
|
|
155261
155317
|
state3,
|
|
@@ -155645,7 +155701,7 @@ init_zod();
|
|
|
155645
155701
|
// ../tool-server/src/utils/workspace-reader.ts
|
|
155646
155702
|
var import_promises12 = require("node:fs/promises");
|
|
155647
155703
|
var import_node_path23 = require("node:path");
|
|
155648
|
-
var
|
|
155704
|
+
var import_node_child_process36 = require("node:child_process");
|
|
155649
155705
|
var import_dotenv2 = __toESM(require_main());
|
|
155650
155706
|
async function exists(path50) {
|
|
155651
155707
|
try {
|
|
@@ -155689,7 +155745,7 @@ async function listDir(path50) {
|
|
|
155689
155745
|
var COMMAND_TIMEOUT_MS = 3e3;
|
|
155690
155746
|
function runVersionCommand(cmd, args, cwd) {
|
|
155691
155747
|
return new Promise((resolve14) => {
|
|
155692
|
-
const child = (0,
|
|
155748
|
+
const child = (0, import_node_child_process36.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
|
|
155693
155749
|
if (err) {
|
|
155694
155750
|
resolve14(null);
|
|
155695
155751
|
return;
|
|
@@ -155978,7 +156034,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
155978
156034
|
};
|
|
155979
156035
|
|
|
155980
156036
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
155981
|
-
var
|
|
156037
|
+
var import_node_child_process37 = require("node:child_process");
|
|
155982
156038
|
var fs63 = __toESM(require("node:fs"));
|
|
155983
156039
|
var path46 = __toESM(require("node:path"));
|
|
155984
156040
|
init_zod();
|
|
@@ -156113,7 +156169,7 @@ var updateArgentTool = {
|
|
|
156113
156169
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
156114
156170
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
156115
156171
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
156116
|
-
const child = (0,
|
|
156172
|
+
const child = (0, import_node_child_process37.spawn)(cmd, args, {
|
|
156117
156173
|
detached: true,
|
|
156118
156174
|
stdio: "ignore",
|
|
156119
156175
|
env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
|
|
@@ -157115,13 +157171,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
157115
157171
|
|
|
157116
157172
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
157117
157173
|
var fs65 = __toESM(require("node:fs"));
|
|
157118
|
-
var
|
|
157119
|
-
var
|
|
157174
|
+
var import_node_child_process38 = require("node:child_process");
|
|
157175
|
+
var import_node_util26 = require("node:util");
|
|
157120
157176
|
init_external_devices();
|
|
157121
|
-
var
|
|
157177
|
+
var execFileAsync28 = (0, import_node_util26.promisify)(import_node_child_process38.execFile);
|
|
157122
157178
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
157123
157179
|
async function getBootedUdidsInSet(deviceSet) {
|
|
157124
|
-
const { stdout } = await
|
|
157180
|
+
const { stdout } = await execFileAsync28("xcrun", [
|
|
157125
157181
|
...simctlPrefix(deviceSet),
|
|
157126
157182
|
"list",
|
|
157127
157183
|
"devices",
|
|
@@ -157240,7 +157296,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
157240
157296
|
}
|
|
157241
157297
|
|
|
157242
157298
|
// ../tool-server/src/utils/preview-window.ts
|
|
157243
|
-
var
|
|
157299
|
+
var import_node_child_process39 = require("node:child_process");
|
|
157244
157300
|
var fs66 = __toESM(require("node:fs"));
|
|
157245
157301
|
var os20 = __toESM(require("node:os"));
|
|
157246
157302
|
var path48 = __toESM(require("node:path"));
|
|
@@ -157272,10 +157328,10 @@ function ensureLensAppBundle(electronBin) {
|
|
|
157272
157328
|
fs66.copyFileSync(path48.join(realContents, "Info.plist"), plist);
|
|
157273
157329
|
const setPlist = (entry, value) => {
|
|
157274
157330
|
try {
|
|
157275
|
-
(0,
|
|
157331
|
+
(0, import_node_child_process39.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
157276
157332
|
} catch {
|
|
157277
157333
|
try {
|
|
157278
|
-
(0,
|
|
157334
|
+
(0, import_node_child_process39.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
|
|
157279
157335
|
} catch {
|
|
157280
157336
|
}
|
|
157281
157337
|
}
|
|
@@ -157334,7 +157390,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
157334
157390
|
const wrapperBin = ensureLensAppBundle(electronBin);
|
|
157335
157391
|
const launchBin = wrapperBin ?? electronBin;
|
|
157336
157392
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
157337
|
-
const next = (0,
|
|
157393
|
+
const next = (0, import_node_child_process39.spawn)(launchBin, launchArgs, {
|
|
157338
157394
|
// Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
|
|
157339
157395
|
// our env, so the child boots as a GUI app instead of bare Node.
|
|
157340
157396
|
env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),
|
package/package.json
CHANGED
|
@@ -44,5 +44,5 @@ A recording does not stop itself before its `timeLimitSeconds` cap, so a forgott
|
|
|
44
44
|
- **The timeline is paced to a steady 30 fps**: a device only emits a frame when its screen changes, so captured frames are re-paced onto a fixed timeline rather than bunching up. With static-frame trimming off (`trimStatic: false`) that timeline is wall-clock accurate — a completely still screen still comes back as a full-length video (compressing to almost nothing) and `durationMs` matches the time you actually recorded. With trimming on (the default, see §3) still stretches past the grace window are collapsed, so `durationMs` is the trimmed video length and `wallClockMs` carries the real elapsed time.
|
|
45
45
|
- **Android**: records at the device's native resolution; secure screens (DRM, some password fields) come out black.
|
|
46
46
|
- **Unsupported**: tvOS simulators, physical iPhones, Chromium apps, Vega/Fire TV, and remote (`remote:`-prefixed) simulators — none of them expose a readable frame stream. For a single still frame use `screenshot`; for a replayable interaction script use `argent-create-flow` instead of a video.
|
|
47
|
-
- **ffmpeg is required**: it is the encoder, so `screen-recording-start` fails up front with an install hint if it is missing (`brew install ffmpeg`). It is resolved from `PATH` plus the usual Homebrew prefixes.
|
|
47
|
+
- **ffmpeg is required**: it is the encoder, so `screen-recording-start` fails up front with an install hint if it is missing (`brew install ffmpeg` on macOS). It is resolved from `PATH` plus the usual Homebrew prefixes.
|
|
48
48
|
- **Watermark**: the Argent logo + "By @swmansion" is stamped bottom-left while encoding, faint (20% opacity) and per-pixel contrast-matched to the background (light logo over dark UI, dark logo over light UI). On by default — turn it off with `argent disable video-watermark` (re-enable with `argent enable video-watermark`). The flag is read when the recording starts.
|