@swmansion/argent 0.7.0-next.4 → 0.7.1
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/agents/argent-environment-inspector.md +0 -1
- package/bin/ax-service +0 -0
- package/dist/cli.js +2 -10
- package/dist/cli.js.map +1 -1
- package/dist/fatal-handlers.d.ts +3 -0
- package/dist/fatal-handlers.js +75 -0
- package/dist/fatal-handlers.js.map +1 -0
- package/dist/installer.mjs +20 -4
- package/dist/mcp-server.mjs +3 -2
- package/dist/tool-server.cjs +450 -257
- package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/libKeyboardPatch.dylib +0 -0
- package/dylibs/libNativeDevtoolsIos.dylib +0 -0
- package/package.json +1 -1
- package/skills/argent-create-flow/SKILL.md +1 -1
|
@@ -11,7 +11,6 @@ description: >
|
|
|
11
11
|
Use proactively at session start when required to gather the environment information.
|
|
12
12
|
If subagent delegation is not available, run the steps in the main thread instead.
|
|
13
13
|
The main agent is responsible for persisting the result to project memory.
|
|
14
|
-
model: haiku
|
|
15
14
|
---
|
|
16
15
|
|
|
17
16
|
You are the **environment-inspector** subagent. Your job is to inspect a mobile app
|
package/bin/ax-service
CHANGED
|
Binary file
|
package/dist/cli.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import * as fs from "node:fs";
|
|
23
23
|
import * as path from "node:path";
|
|
24
24
|
import { BUNDLED_RUNTIME_PATHS } from "./bundled-paths.js";
|
|
25
|
+
import { installFatalHandlers } from "./fatal-handlers.js";
|
|
25
26
|
const PACKAGE_NAME = "@swmansion/argent";
|
|
26
27
|
function getInstalledVersion() {
|
|
27
28
|
try {
|
|
@@ -37,16 +38,7 @@ function getInstalledVersion() {
|
|
|
37
38
|
}
|
|
38
39
|
const [, , command, ...rest] = process.argv;
|
|
39
40
|
const isMcpServer = command === "mcp";
|
|
40
|
-
|
|
41
|
-
process.stderr.write(`[argent] Uncaught exception: ${err.stack ?? err}\n`);
|
|
42
|
-
if (!isMcpServer)
|
|
43
|
-
process.exit(1);
|
|
44
|
-
});
|
|
45
|
-
process.on("unhandledRejection", (reason) => {
|
|
46
|
-
process.stderr.write(`[argent] Unhandled rejection: ${reason instanceof Error ? (reason.stack ?? reason.message) : reason}\n`);
|
|
47
|
-
if (!isMcpServer)
|
|
48
|
-
process.exit(1);
|
|
49
|
-
});
|
|
41
|
+
installFatalHandlers({ isMcpServer });
|
|
50
42
|
function printHelp() {
|
|
51
43
|
const version = getInstalledVersion() ?? "unknown";
|
|
52
44
|
console.log(`
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEzC,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,uEAAuE;QACvE,oDAAoD;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAyB,CAAC;QACjF,OAAO,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,EAAE,AAAD,EAAG,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAC5C,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,CAAC;AAEtC,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Process-level handlers for uncaughtException and unhandledRejection.
|
|
2
|
+
//
|
|
3
|
+
// In MCP-server mode we do NOT exit on every uncaught error — many are
|
|
4
|
+
// transient and the editor expects the server to keep running. But the naive
|
|
5
|
+
// version (`stderr.write(...); if (!isMcp) exit`) burns 100% CPU when stderr
|
|
6
|
+
// itself is broken (e.g. the parent process is gone): the write emits an
|
|
7
|
+
// async 'error' event on the stream, which without a listener becomes another
|
|
8
|
+
// uncaughtException, runs the handler, writes to the same broken stream, ...
|
|
9
|
+
//
|
|
10
|
+
// The fix has three pieces:
|
|
11
|
+
// 1. `'error'` listeners on stdout/stderr — broken stdio is fatal; exit
|
|
12
|
+
// before the failure round-trips into uncaughtException. This is what
|
|
13
|
+
// breaks the production loop.
|
|
14
|
+
// 2. try/catch around `stderr.write` — synchronous write failures also exit
|
|
15
|
+
// cleanly instead of escaping into another uncaughtException.
|
|
16
|
+
// 3. try/catch around the formatter — a throwing `.stack` getter or
|
|
17
|
+
// `toString` (the production trace pointed at defaultPrepareStackTrace)
|
|
18
|
+
// can't take down the handler.
|
|
19
|
+
//
|
|
20
|
+
// When stdio is unusable we cannot tell the parent process what went wrong,
|
|
21
|
+
// so we leave a breadcrumb on disk at `~/.argent/mcp-fatal.log`. Sibling of
|
|
22
|
+
// the other persistent argent diagnostic logs (`tool-server.log`, etc.).
|
|
23
|
+
import * as fs from "node:fs";
|
|
24
|
+
import * as os from "node:os";
|
|
25
|
+
import * as path from "node:path";
|
|
26
|
+
let installed = false;
|
|
27
|
+
const FATAL_LOG_PATH = path.join(os.homedir(), ".argent", "mcp-fatal.log");
|
|
28
|
+
function appendFatalLog(label, detail) {
|
|
29
|
+
try {
|
|
30
|
+
fs.mkdirSync(path.dirname(FATAL_LOG_PATH), { recursive: true });
|
|
31
|
+
const line = `[${new Date().toISOString()}] pid=${process.pid} ${label}: ${detail}\n`;
|
|
32
|
+
fs.appendFileSync(FATAL_LOG_PATH, line);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Last-resort log — if even this write fails (read-only fs, missing home),
|
|
36
|
+
// there is nothing more we can do. Swallow so we still exit cleanly.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function installFatalHandlers(opts) {
|
|
40
|
+
if (installed)
|
|
41
|
+
return;
|
|
42
|
+
installed = true;
|
|
43
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
44
|
+
const name = stream === process.stdout ? "stdout" : "stderr";
|
|
45
|
+
stream.on("error", (err) => {
|
|
46
|
+
appendFatalLog(`Broken ${name}`, String(err?.stack ?? err));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function reportFatal(label, getDetail) {
|
|
51
|
+
let detail;
|
|
52
|
+
try {
|
|
53
|
+
try {
|
|
54
|
+
detail = getDetail();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
detail = "<failed to format>";
|
|
58
|
+
}
|
|
59
|
+
process.stderr.write(`[argent] ${label}: ${detail}\n`);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
appendFatalLog(label, detail);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (!opts.isMcpServer)
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
process.on("uncaughtException", (err) => {
|
|
69
|
+
reportFatal("Uncaught exception", () => String(err?.stack ?? err));
|
|
70
|
+
});
|
|
71
|
+
process.on("unhandledRejection", (reason) => {
|
|
72
|
+
reportFatal("Unhandled rejection", () => reason instanceof Error ? (reason.stack ?? reason.message) : String(reason));
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=fatal-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fatal-handlers.js","sourceRoot":"","sources":["../src/fatal-handlers.ts"],"names":[],"mappings":"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"}
|
package/dist/installer.mjs
CHANGED
|
@@ -12813,6 +12813,18 @@ function getInstalledVersion() {
|
|
|
12813
12813
|
return null;
|
|
12814
12814
|
}
|
|
12815
12815
|
}
|
|
12816
|
+
function getGloballyInstalledVersion() {
|
|
12817
|
+
const binaryPath = getGlobalBinaryPath();
|
|
12818
|
+
if (!binaryPath) return null;
|
|
12819
|
+
try {
|
|
12820
|
+
const realPath = fs.realpathSync(binaryPath);
|
|
12821
|
+
const pkgRoot = resolvePackageRoot(path.dirname(realPath));
|
|
12822
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(pkgRoot, "package.json"), "utf8"));
|
|
12823
|
+
return pkg.version ?? null;
|
|
12824
|
+
} catch {
|
|
12825
|
+
return null;
|
|
12826
|
+
}
|
|
12827
|
+
}
|
|
12816
12828
|
var PROBE_TIMEOUT_MS = 3e3;
|
|
12817
12829
|
function getLatestVersion() {
|
|
12818
12830
|
const result = execSync(`npm view ${PACKAGE_NAME} version --registry ${NPM_REGISTRY}`, {
|
|
@@ -12835,18 +12847,21 @@ var TEMP_RUNNER_MARKERS = [
|
|
|
12835
12847
|
function isTempRunnerPath(binaryPath) {
|
|
12836
12848
|
return TEMP_RUNNER_MARKERS.some((marker) => binaryPath.includes(marker));
|
|
12837
12849
|
}
|
|
12838
|
-
function
|
|
12850
|
+
function getGlobalBinaryPath() {
|
|
12839
12851
|
try {
|
|
12840
12852
|
const cmd = process.platform === "win32" ? "where" : "which -a";
|
|
12841
12853
|
const output = execSync(`${cmd} ${MCP_BINARY_NAME}`, {
|
|
12842
12854
|
encoding: "utf8",
|
|
12843
12855
|
stdio: ["ignore", "pipe", "ignore"]
|
|
12844
12856
|
});
|
|
12845
|
-
return output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).
|
|
12857
|
+
return output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).find((line) => !isTempRunnerPath(line)) ?? null;
|
|
12846
12858
|
} catch {
|
|
12847
|
-
return
|
|
12859
|
+
return null;
|
|
12848
12860
|
}
|
|
12849
12861
|
}
|
|
12862
|
+
function isGloballyInstalled() {
|
|
12863
|
+
return getGlobalBinaryPath() !== null;
|
|
12864
|
+
}
|
|
12850
12865
|
function isSkillsCliAvailable() {
|
|
12851
12866
|
try {
|
|
12852
12867
|
execSync("npx --no-install skills --version", {
|
|
@@ -14250,7 +14265,7 @@ async function update(args) {
|
|
|
14250
14265
|
const nonInteractive = args.includes("--yes") || args.includes("-y");
|
|
14251
14266
|
Wt2(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" argent update ")));
|
|
14252
14267
|
const globallyInstalled = isGloballyInstalled();
|
|
14253
|
-
const installed = globallyInstalled ?
|
|
14268
|
+
const installed = globallyInstalled ? getGloballyInstalledVersion() : null;
|
|
14254
14269
|
if (globallyInstalled && !installed) {
|
|
14255
14270
|
R2.error("Could not determine installed version.");
|
|
14256
14271
|
process.exit(1);
|
|
@@ -14695,6 +14710,7 @@ export {
|
|
|
14695
14710
|
MCP_BINARY_NAME,
|
|
14696
14711
|
MCP_SERVER_KEY,
|
|
14697
14712
|
PACKAGE_NAME,
|
|
14713
|
+
getGloballyInstalledVersion,
|
|
14698
14714
|
getInstalledVersion,
|
|
14699
14715
|
init,
|
|
14700
14716
|
uninstall,
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -14154,7 +14154,7 @@ async function fetchWithReconnect(getUrl, reconnect, config2) {
|
|
|
14154
14154
|
let lastError;
|
|
14155
14155
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
14156
14156
|
const controller = new AbortController();
|
|
14157
|
-
const timer = setTimeout(() => controller.abort(), fetchTimeoutMs);
|
|
14157
|
+
const timer = fetchTimeoutMs !== null ? setTimeout(() => controller.abort(), fetchTimeoutMs) : void 0;
|
|
14158
14158
|
try {
|
|
14159
14159
|
return await fetch(getUrl(), { ...init, signal: controller.signal });
|
|
14160
14160
|
} catch (err) {
|
|
@@ -14220,7 +14220,8 @@ async function startMcpServer(options) {
|
|
|
14220
14220
|
method: "POST",
|
|
14221
14221
|
headers: { "Content-Type": "application/json" },
|
|
14222
14222
|
body: JSON.stringify(args ?? {})
|
|
14223
|
-
}
|
|
14223
|
+
},
|
|
14224
|
+
fetchTimeoutMs: meta?.longRunning ? null : FETCH_TIMEOUT_MS
|
|
14224
14225
|
});
|
|
14225
14226
|
const json = await res.json();
|
|
14226
14227
|
if (!res.ok) throw new Error(json.error ?? json.message ?? res.statusText);
|
package/dist/tool-server.cjs
CHANGED
|
@@ -18403,7 +18403,7 @@ var require_view = __commonJS({
|
|
|
18403
18403
|
var path11 = require("path");
|
|
18404
18404
|
var fs22 = require("fs");
|
|
18405
18405
|
var dirname3 = path11.dirname;
|
|
18406
|
-
var
|
|
18406
|
+
var basename5 = path11.basename;
|
|
18407
18407
|
var extname = path11.extname;
|
|
18408
18408
|
var join15 = path11.join;
|
|
18409
18409
|
var resolve2 = path11.resolve;
|
|
@@ -18442,7 +18442,7 @@ var require_view = __commonJS({
|
|
|
18442
18442
|
var root = roots[i];
|
|
18443
18443
|
var loc = resolve2(root, name);
|
|
18444
18444
|
var dir = dirname3(loc);
|
|
18445
|
-
var file =
|
|
18445
|
+
var file = basename5(loc);
|
|
18446
18446
|
path12 = this.resolve(dir, file);
|
|
18447
18447
|
}
|
|
18448
18448
|
return path12;
|
|
@@ -18458,7 +18458,7 @@ var require_view = __commonJS({
|
|
|
18458
18458
|
if (stat2 && stat2.isFile()) {
|
|
18459
18459
|
return path12;
|
|
18460
18460
|
}
|
|
18461
|
-
path12 = join15(dir,
|
|
18461
|
+
path12 = join15(dir, basename5(file, ext), "index" + ext);
|
|
18462
18462
|
stat2 = tryStat(path12);
|
|
18463
18463
|
if (stat2 && stat2.isFile()) {
|
|
18464
18464
|
return path12;
|
|
@@ -18539,7 +18539,7 @@ var require_content_disposition = __commonJS({
|
|
|
18539
18539
|
"use strict";
|
|
18540
18540
|
module2.exports = contentDisposition;
|
|
18541
18541
|
module2.exports.parse = parse;
|
|
18542
|
-
var
|
|
18542
|
+
var basename5 = require("path").basename;
|
|
18543
18543
|
var Buffer2 = require_safe_buffer().Buffer;
|
|
18544
18544
|
var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
|
|
18545
18545
|
var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
|
|
@@ -18575,9 +18575,9 @@ var require_content_disposition = __commonJS({
|
|
|
18575
18575
|
if (typeof fallback === "string" && NON_LATIN1_REGEXP.test(fallback)) {
|
|
18576
18576
|
throw new TypeError("fallback must be ISO-8859-1 string");
|
|
18577
18577
|
}
|
|
18578
|
-
var name =
|
|
18578
|
+
var name = basename5(filename);
|
|
18579
18579
|
var isQuotedString = TEXT_REGEXP.test(name);
|
|
18580
|
-
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) :
|
|
18580
|
+
var fallbackName = typeof fallback !== "string" ? fallback && getlatin1(name) : basename5(fallback);
|
|
18581
18581
|
var hasFallback = typeof fallbackName === "string" && fallbackName !== name;
|
|
18582
18582
|
if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
|
|
18583
18583
|
params["filename*"] = name;
|
|
@@ -41478,6 +41478,9 @@ function zodTypeToJsonSchema(type) {
|
|
|
41478
41478
|
if (type instanceof external_exports.ZodNumber) return { type: "number" };
|
|
41479
41479
|
if (type instanceof external_exports.ZodBoolean) return { type: "boolean" };
|
|
41480
41480
|
if (type instanceof external_exports.ZodOptional) return zodTypeToJsonSchema(type.unwrap());
|
|
41481
|
+
if (type instanceof external_exports.ZodDefault) {
|
|
41482
|
+
return { ...zodTypeToJsonSchema(type._def.innerType), default: type._def.defaultValue() };
|
|
41483
|
+
}
|
|
41481
41484
|
if (type instanceof external_exports.ZodArray) {
|
|
41482
41485
|
return { type: "array", items: zodTypeToJsonSchema(type.element) };
|
|
41483
41486
|
}
|
|
@@ -41493,7 +41496,7 @@ function zodTypeToJsonSchema(type) {
|
|
|
41493
41496
|
return {};
|
|
41494
41497
|
}
|
|
41495
41498
|
function isOptional(type) {
|
|
41496
|
-
return type instanceof external_exports.ZodOptional;
|
|
41499
|
+
return type instanceof external_exports.ZodOptional || type instanceof external_exports.ZodDefault;
|
|
41497
41500
|
}
|
|
41498
41501
|
|
|
41499
41502
|
// ../registry/src/registry.ts
|
|
@@ -41948,7 +41951,7 @@ var import_node_https = __toESM(require("node:https"));
|
|
|
41948
41951
|
var import_semver = __toESM(require_semver2());
|
|
41949
41952
|
|
|
41950
41953
|
// ../tool-server/package.json
|
|
41951
|
-
var version = "0.7.
|
|
41954
|
+
var version = "0.7.1";
|
|
41952
41955
|
|
|
41953
41956
|
// ../tool-server/src/utils/update-checker.ts
|
|
41954
41957
|
var PACKAGE_NAME = "@swmansion/argent";
|
|
@@ -42492,11 +42495,15 @@ var ADB_KILL_SIGNAL = "SIGKILL";
|
|
|
42492
42495
|
function describeAdbFailure(args, err) {
|
|
42493
42496
|
const e = err;
|
|
42494
42497
|
const argv = args.join(" ");
|
|
42495
|
-
const
|
|
42496
|
-
|
|
42497
|
-
const
|
|
42498
|
-
|
|
42499
|
-
|
|
42498
|
+
const ioDetail = (e.stderr ?? "").trim() || (e.stdout ?? "").trim();
|
|
42499
|
+
if (ioDetail) return new Error(`adb ${argv} failed: ${ioDetail}`);
|
|
42500
|
+
const meta = [];
|
|
42501
|
+
if (e.killed) meta.push("killed=true");
|
|
42502
|
+
if (e.signal) meta.push(`signal=${e.signal}`);
|
|
42503
|
+
if (e.code) meta.push(`code=${e.code}`);
|
|
42504
|
+
const baseMsg = (e.message ?? String(err)).trim();
|
|
42505
|
+
const suffix = meta.length ? ` (${meta.join(" ")})` : "";
|
|
42506
|
+
return new Error(`adb ${argv} failed: ${baseMsg}${suffix}`);
|
|
42500
42507
|
}
|
|
42501
42508
|
async function runAdb(args, options = {}) {
|
|
42502
42509
|
const adbPath = await resolveAdbOrThrow();
|
|
@@ -42933,6 +42940,7 @@ function createHttpApp(registry, options) {
|
|
|
42933
42940
|
if (def?.outputHint) entry.outputHint = def.outputHint;
|
|
42934
42941
|
if (def?.alwaysLoad) entry.alwaysLoad = true;
|
|
42935
42942
|
if (def?.searchHint) entry.searchHint = def.searchHint;
|
|
42943
|
+
if (def?.longRunning) entry.longRunning = true;
|
|
42936
42944
|
return entry;
|
|
42937
42945
|
});
|
|
42938
42946
|
res.json({ tools });
|
|
@@ -44926,6 +44934,136 @@ var REACT_NATIVE_PROFILER_SETUP_SCRIPT = `
|
|
|
44926
44934
|
});
|
|
44927
44935
|
})();
|
|
44928
44936
|
`;
|
|
44937
|
+
var BOOTSTRAP_DEVTOOLS_BACKEND_SCRIPT = `
|
|
44938
|
+
(function __argent_bootstrapDevtoolsBackend() {
|
|
44939
|
+
var h = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
44940
|
+
if (!h) return JSON.stringify({ ok: false, reason: 'no-hook' });
|
|
44941
|
+
|
|
44942
|
+
function sizeOf(m) {
|
|
44943
|
+
if (!m || typeof m.forEach !== 'function') return 0;
|
|
44944
|
+
var n = 0;
|
|
44945
|
+
m.forEach(function () { n++; });
|
|
44946
|
+
return n;
|
|
44947
|
+
}
|
|
44948
|
+
|
|
44949
|
+
var renderersCount = sizeOf(h.renderers);
|
|
44950
|
+
var rendererInterfacesCount = sizeOf(h.rendererInterfaces);
|
|
44951
|
+
|
|
44952
|
+
if (rendererInterfacesCount > 0) {
|
|
44953
|
+
return JSON.stringify({
|
|
44954
|
+
ok: true,
|
|
44955
|
+
reason: 'already-attached',
|
|
44956
|
+
renderersCount: renderersCount,
|
|
44957
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
44958
|
+
});
|
|
44959
|
+
}
|
|
44960
|
+
|
|
44961
|
+
if (renderersCount === 0) {
|
|
44962
|
+
return JSON.stringify({
|
|
44963
|
+
ok: false,
|
|
44964
|
+
reason: 'no-renderers',
|
|
44965
|
+
renderersCount: renderersCount,
|
|
44966
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
44967
|
+
});
|
|
44968
|
+
}
|
|
44969
|
+
|
|
44970
|
+
if (typeof globalThis.__r !== 'function' || typeof globalThis.__r.getModules !== 'function') {
|
|
44971
|
+
return JSON.stringify({
|
|
44972
|
+
ok: false,
|
|
44973
|
+
reason: 'no-metro-modules',
|
|
44974
|
+
renderersCount: renderersCount,
|
|
44975
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
44976
|
+
});
|
|
44977
|
+
}
|
|
44978
|
+
|
|
44979
|
+
var found = null;
|
|
44980
|
+
var moduleSeenButUnsupported = false;
|
|
44981
|
+
try {
|
|
44982
|
+
var mods = globalThis.__r.getModules();
|
|
44983
|
+
var inspect = function (id, meta) {
|
|
44984
|
+
if (found) return;
|
|
44985
|
+
var name = meta && meta.verboseName;
|
|
44986
|
+
if (typeof name !== 'string') return;
|
|
44987
|
+
if (name.indexOf('react-devtools-core/dist/backend') < 0) return;
|
|
44988
|
+
try {
|
|
44989
|
+
var m = globalThis.__r(id);
|
|
44990
|
+
if (!m) return;
|
|
44991
|
+
if (typeof m.connectWithCustomMessagingProtocol === 'function') {
|
|
44992
|
+
found = m;
|
|
44993
|
+
} else {
|
|
44994
|
+
// Module exists but exposes only legacy WebSocket-based connectToDevTools
|
|
44995
|
+
// (rdt-core <5.1). We can't bootstrap without a real ws endpoint, so the
|
|
44996
|
+
// user has to attach an external backend (\`npx react-devtools\` + reload).
|
|
44997
|
+
moduleSeenButUnsupported = true;
|
|
44998
|
+
}
|
|
44999
|
+
} catch (_e) {
|
|
45000
|
+
// require failure on this id \u2014 keep searching.
|
|
45001
|
+
}
|
|
45002
|
+
};
|
|
45003
|
+
// Metro's getModules() returns a Map<id, meta> in modern versions.
|
|
45004
|
+
// Map#forEach calls back as (value, key); array-like fallback handled below.
|
|
45005
|
+
if (typeof mods.forEach === 'function' && typeof mods.size === 'number') {
|
|
45006
|
+
mods.forEach(function (meta, id) { inspect(id, meta); });
|
|
45007
|
+
} else if (typeof mods.length === 'number') {
|
|
45008
|
+
for (var i = 0; i < mods.length; i++) {
|
|
45009
|
+
if (mods[i]) inspect(i, mods[i]);
|
|
45010
|
+
}
|
|
45011
|
+
} else if (typeof mods.forEach === 'function') {
|
|
45012
|
+
mods.forEach(function (meta, id) { inspect(id, meta); });
|
|
45013
|
+
}
|
|
45014
|
+
} catch (err) {
|
|
45015
|
+
return JSON.stringify({
|
|
45016
|
+
ok: false,
|
|
45017
|
+
reason: 'metro-scan-error',
|
|
45018
|
+
message: String((err && err.message) || err),
|
|
45019
|
+
renderersCount: renderersCount,
|
|
45020
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
45021
|
+
});
|
|
45022
|
+
}
|
|
45023
|
+
|
|
45024
|
+
if (!found) {
|
|
45025
|
+
return JSON.stringify({
|
|
45026
|
+
ok: false,
|
|
45027
|
+
reason: moduleSeenButUnsupported ? 'unsupported-rdt-version' : 'no-rdt-module',
|
|
45028
|
+
renderersCount: renderersCount,
|
|
45029
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
45030
|
+
});
|
|
45031
|
+
}
|
|
45032
|
+
|
|
45033
|
+
try {
|
|
45034
|
+
found.connectWithCustomMessagingProtocol({
|
|
45035
|
+
onSubscribe: function () {},
|
|
45036
|
+
onUnsubscribe: function () {},
|
|
45037
|
+
onMessage: function () {},
|
|
45038
|
+
});
|
|
45039
|
+
} catch (err) {
|
|
45040
|
+
return JSON.stringify({
|
|
45041
|
+
ok: false,
|
|
45042
|
+
reason: 'bootstrap-threw',
|
|
45043
|
+
message: String((err && err.message) || err),
|
|
45044
|
+
renderersCount: renderersCount,
|
|
45045
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
45046
|
+
});
|
|
45047
|
+
}
|
|
45048
|
+
|
|
45049
|
+
var afterCount = sizeOf(h.rendererInterfaces);
|
|
45050
|
+
if (afterCount === 0) {
|
|
45051
|
+
return JSON.stringify({
|
|
45052
|
+
ok: false,
|
|
45053
|
+
reason: 'bootstrap-no-effect',
|
|
45054
|
+
renderersCount: renderersCount,
|
|
45055
|
+
rendererInterfacesCount: rendererInterfacesCount,
|
|
45056
|
+
});
|
|
45057
|
+
}
|
|
45058
|
+
|
|
45059
|
+
return JSON.stringify({
|
|
45060
|
+
ok: true,
|
|
45061
|
+
reason: 'bootstrapped',
|
|
45062
|
+
renderersCount: renderersCount,
|
|
45063
|
+
rendererInterfacesCount: afterCount,
|
|
45064
|
+
});
|
|
45065
|
+
})()
|
|
45066
|
+
`;
|
|
44929
45067
|
var HEARTBEAT_SCRIPT = `
|
|
44930
45068
|
(function(){
|
|
44931
45069
|
if (typeof globalThis.__argent_profilerHeartbeat === 'function') {
|
|
@@ -46251,7 +46389,6 @@ Use when you need to scroll a list, dismiss a modal, or navigate between pages.
|
|
|
46251
46389
|
};
|
|
46252
46390
|
|
|
46253
46391
|
// ../tool-server/src/utils/gesture-utils.ts
|
|
46254
|
-
var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
46255
46392
|
function lerp(a, b, t) {
|
|
46256
46393
|
return a + (b - a) * t;
|
|
46257
46394
|
}
|
|
@@ -46299,7 +46436,7 @@ function sendTouchEvent(api, type, x, y, x2, y2) {
|
|
|
46299
46436
|
}
|
|
46300
46437
|
|
|
46301
46438
|
// ../tool-server/src/tools/gesture-custom/index.ts
|
|
46302
|
-
var
|
|
46439
|
+
var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
46303
46440
|
var eventSchema = external_exports.object({
|
|
46304
46441
|
type: external_exports.enum(["Down", "Move", "Up"]).describe("Touch event type"),
|
|
46305
46442
|
x: external_exports.number().describe("Normalized x 0.0\u20131.0 (not pixels; same as tap/swipe)"),
|
|
@@ -46352,7 +46489,7 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
|
|
|
46352
46489
|
const api = services.simulatorServer;
|
|
46353
46490
|
const events = params.interpolate && params.interpolate > 0 ? interpolateEvents(params.events, params.interpolate) : params.events;
|
|
46354
46491
|
for (const event of events) {
|
|
46355
|
-
await
|
|
46492
|
+
await sleep3(event.delayMs ?? 16);
|
|
46356
46493
|
sendCommand(api, {
|
|
46357
46494
|
cmd: "touch",
|
|
46358
46495
|
type: event.type,
|
|
@@ -46366,6 +46503,10 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
|
|
|
46366
46503
|
}
|
|
46367
46504
|
};
|
|
46368
46505
|
|
|
46506
|
+
// ../tool-server/src/utils/timing.ts
|
|
46507
|
+
var sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
46508
|
+
var DEFAULT_INTER_STEP_DELAY_MS = 100;
|
|
46509
|
+
|
|
46369
46510
|
// ../tool-server/src/tools/gesture-pinch/index.ts
|
|
46370
46511
|
var zodSchema18 = external_exports.object({
|
|
46371
46512
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
@@ -46420,7 +46561,7 @@ Use when you need to zoom in or out on a map, image, or zoomable view. Returns {
|
|
|
46420
46561
|
const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
|
|
46421
46562
|
if (i === 0) timestampMs = Date.now();
|
|
46422
46563
|
sendTouchEvent(api, type, x1, y1, x2, y2);
|
|
46423
|
-
if (i < steps) await
|
|
46564
|
+
if (i < steps) await sleep4(16);
|
|
46424
46565
|
}
|
|
46425
46566
|
return { pinched: true, timestampMs };
|
|
46426
46567
|
}
|
|
@@ -46474,7 +46615,7 @@ Use when you need to rotate a map, image picker, or any rotateable UI element. R
|
|
|
46474
46615
|
const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
|
|
46475
46616
|
if (i === 0) timestampMs = Date.now();
|
|
46476
46617
|
sendTouchEvent(api, type, x1, y1, x2, y2);
|
|
46477
|
-
if (i < steps) await
|
|
46618
|
+
if (i < steps) await sleep4(16);
|
|
46478
46619
|
}
|
|
46479
46620
|
return { rotated: true, timestampMs };
|
|
46480
46621
|
}
|
|
@@ -46696,7 +46837,6 @@ Returns { orientation }. Fails if the target device is not booted.`,
|
|
|
46696
46837
|
};
|
|
46697
46838
|
|
|
46698
46839
|
// ../tool-server/src/tools/run-sequence/index.ts
|
|
46699
|
-
var sleep7 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
46700
46840
|
var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
|
|
46701
46841
|
"gesture-tap",
|
|
46702
46842
|
"gesture-swipe",
|
|
@@ -46717,7 +46857,9 @@ var zodSchema23 = external_exports.object({
|
|
|
46717
46857
|
"Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate"
|
|
46718
46858
|
),
|
|
46719
46859
|
args: external_exports.record(external_exports.unknown()).describe("Tool arguments (excluding udid, which is injected automatically)"),
|
|
46720
|
-
delayMs: external_exports.number().optional().describe(
|
|
46860
|
+
delayMs: external_exports.number().optional().describe(
|
|
46861
|
+
`Wait time in ms after this step before the next (default ${DEFAULT_INTER_STEP_DELAY_MS})`
|
|
46862
|
+
)
|
|
46721
46863
|
})
|
|
46722
46864
|
).min(1).describe("Ordered list of interaction steps to execute sequentially")
|
|
46723
46865
|
});
|
|
@@ -46764,6 +46906,7 @@ Example \u2014 type text and submit:
|
|
|
46764
46906
|
|
|
46765
46907
|
Stops on the first error and returns partial results.`,
|
|
46766
46908
|
alwaysLoad: true,
|
|
46909
|
+
longRunning: true,
|
|
46767
46910
|
searchHint: "batch sequence multiple gesture steps sequentially",
|
|
46768
46911
|
zodSchema: zodSchema23,
|
|
46769
46912
|
capability: capability15,
|
|
@@ -46792,8 +46935,8 @@ Stops on the first error and returns partial results.`,
|
|
|
46792
46935
|
});
|
|
46793
46936
|
break;
|
|
46794
46937
|
}
|
|
46795
|
-
const delay = step.delayMs ??
|
|
46796
|
-
if (delay > 0) await
|
|
46938
|
+
const delay = step.delayMs ?? DEFAULT_INTER_STEP_DELAY_MS;
|
|
46939
|
+
if (delay > 0) await sleep4(delay);
|
|
46797
46940
|
}
|
|
46798
46941
|
return {
|
|
46799
46942
|
completed: results.filter((r) => "result" in r).length,
|
|
@@ -48296,226 +48439,6 @@ ${body.slice(0, MAX_BODY_SIZE)}...`;
|
|
|
48296
48439
|
}
|
|
48297
48440
|
};
|
|
48298
48441
|
|
|
48299
|
-
// ../tool-server/src/tools/describe/contract.ts
|
|
48300
|
-
var describeFrameSchema = external_exports.object({
|
|
48301
|
-
x: external_exports.number().finite().min(0).max(1),
|
|
48302
|
-
y: external_exports.number().finite().min(0).max(1),
|
|
48303
|
-
width: external_exports.number().finite().min(0).max(1),
|
|
48304
|
-
height: external_exports.number().finite().min(0).max(1)
|
|
48305
|
-
});
|
|
48306
|
-
var describeNodeSchema = external_exports.lazy(
|
|
48307
|
-
() => external_exports.object({
|
|
48308
|
-
role: external_exports.string().min(1),
|
|
48309
|
-
frame: describeFrameSchema,
|
|
48310
|
-
children: external_exports.array(describeNodeSchema),
|
|
48311
|
-
label: external_exports.string().optional(),
|
|
48312
|
-
identifier: external_exports.string().optional(),
|
|
48313
|
-
value: external_exports.string().optional(),
|
|
48314
|
-
clickable: external_exports.boolean().optional(),
|
|
48315
|
-
longClickable: external_exports.boolean().optional(),
|
|
48316
|
-
scrollable: external_exports.boolean().optional(),
|
|
48317
|
-
checkable: external_exports.boolean().optional(),
|
|
48318
|
-
checked: external_exports.boolean().optional(),
|
|
48319
|
-
disabled: external_exports.boolean().optional(),
|
|
48320
|
-
password: external_exports.boolean().optional(),
|
|
48321
|
-
scrollHidden: external_exports.number().int().nonnegative().optional()
|
|
48322
|
-
}).passthrough()
|
|
48323
|
-
);
|
|
48324
|
-
function parseDescribeResult(input) {
|
|
48325
|
-
return describeNodeSchema.parse(input);
|
|
48326
|
-
}
|
|
48327
|
-
|
|
48328
|
-
// ../tool-server/src/tools/describe/platforms/ios-native-adapter.ts
|
|
48329
|
-
function clamp01(value) {
|
|
48330
|
-
return Math.min(1, Math.max(0, value));
|
|
48331
|
-
}
|
|
48332
|
-
function roundNormalized(value) {
|
|
48333
|
-
return Math.round(value * 1e12) / 1e12;
|
|
48334
|
-
}
|
|
48335
|
-
function clampNormalizedFrame(frame) {
|
|
48336
|
-
const x1 = clamp01(frame.x);
|
|
48337
|
-
const y1 = clamp01(frame.y);
|
|
48338
|
-
const x2 = clamp01(frame.x + frame.width);
|
|
48339
|
-
const y2 = clamp01(frame.y + frame.height);
|
|
48340
|
-
const width = x2 - x1;
|
|
48341
|
-
const height = y2 - y1;
|
|
48342
|
-
if (width <= 0 || height <= 0) {
|
|
48343
|
-
return null;
|
|
48344
|
-
}
|
|
48345
|
-
return {
|
|
48346
|
-
x: roundNormalized(x1),
|
|
48347
|
-
y: roundNormalized(y1),
|
|
48348
|
-
width: roundNormalized(width),
|
|
48349
|
-
height: roundNormalized(height)
|
|
48350
|
-
};
|
|
48351
|
-
}
|
|
48352
|
-
function mapNativeTraitsToDescribeRole(traits) {
|
|
48353
|
-
const set = new Set(traits);
|
|
48354
|
-
if (set.has("header")) return "AXHeading";
|
|
48355
|
-
if (set.has("button") || set.has("toggleButton")) return "AXButton";
|
|
48356
|
-
if (set.has("searchField")) return "AXTextField";
|
|
48357
|
-
if (set.has("link")) return "AXLink";
|
|
48358
|
-
if (set.has("image")) return "AXImage";
|
|
48359
|
-
if (set.has("staticText")) return "AXStaticText";
|
|
48360
|
-
if (set.has("tabBar")) return "AXTabBar";
|
|
48361
|
-
if (set.has("adjustable")) return "AXAdjustable";
|
|
48362
|
-
return "AXGroup";
|
|
48363
|
-
}
|
|
48364
|
-
function adaptNativeDescribeElementToDescribeNode(element) {
|
|
48365
|
-
const frame = clampNormalizedFrame(element.normalizedFrame);
|
|
48366
|
-
if (!frame) return null;
|
|
48367
|
-
return {
|
|
48368
|
-
role: mapNativeTraitsToDescribeRole(element.traits),
|
|
48369
|
-
frame,
|
|
48370
|
-
children: [],
|
|
48371
|
-
label: element.label,
|
|
48372
|
-
identifier: element.identifier,
|
|
48373
|
-
value: element.value
|
|
48374
|
-
};
|
|
48375
|
-
}
|
|
48376
|
-
function adaptNativeDescribeToDescribeResult(result) {
|
|
48377
|
-
const children = result.elements.map(adaptNativeDescribeElementToDescribeNode).filter((node) => node !== null);
|
|
48378
|
-
return parseDescribeResult({
|
|
48379
|
-
role: "AXGroup",
|
|
48380
|
-
frame: {
|
|
48381
|
-
x: 0,
|
|
48382
|
-
y: 0,
|
|
48383
|
-
width: 1,
|
|
48384
|
-
height: 1
|
|
48385
|
-
},
|
|
48386
|
-
children
|
|
48387
|
-
});
|
|
48388
|
-
}
|
|
48389
|
-
|
|
48390
|
-
// ../tool-server/src/tools/describe/platforms/ios-ax-adapter.ts
|
|
48391
|
-
function clamp012(value) {
|
|
48392
|
-
return Math.min(1, Math.max(0, value));
|
|
48393
|
-
}
|
|
48394
|
-
function roundNormalized2(value) {
|
|
48395
|
-
return Math.round(value * 1e12) / 1e12;
|
|
48396
|
-
}
|
|
48397
|
-
function adaptAXElement(el) {
|
|
48398
|
-
if (!el.frame) return null;
|
|
48399
|
-
const x1 = clamp012(el.frame.x);
|
|
48400
|
-
const y1 = clamp012(el.frame.y);
|
|
48401
|
-
const x2 = clamp012(el.frame.x + el.frame.width);
|
|
48402
|
-
const y2 = clamp012(el.frame.y + el.frame.height);
|
|
48403
|
-
const width = x2 - x1;
|
|
48404
|
-
const height = y2 - y1;
|
|
48405
|
-
if (width <= 0 || height <= 0) return null;
|
|
48406
|
-
return {
|
|
48407
|
-
role: mapNativeTraitsToDescribeRole(el.traits ?? []),
|
|
48408
|
-
frame: {
|
|
48409
|
-
x: roundNormalized2(x1),
|
|
48410
|
-
y: roundNormalized2(y1),
|
|
48411
|
-
width: roundNormalized2(width),
|
|
48412
|
-
height: roundNormalized2(height)
|
|
48413
|
-
},
|
|
48414
|
-
children: [],
|
|
48415
|
-
label: el.label,
|
|
48416
|
-
value: el.value
|
|
48417
|
-
};
|
|
48418
|
-
}
|
|
48419
|
-
function adaptAXDescribeToDescribeResult(response) {
|
|
48420
|
-
const children = response.elements.map(adaptAXElement).filter((n) => n !== null);
|
|
48421
|
-
return parseDescribeResult({
|
|
48422
|
-
role: "AXGroup",
|
|
48423
|
-
frame: { x: 0, y: 0, width: 1, height: 1 },
|
|
48424
|
-
children
|
|
48425
|
-
});
|
|
48426
|
-
}
|
|
48427
|
-
|
|
48428
|
-
// ../tool-server/src/utils/native-target-app.ts
|
|
48429
|
-
function chooseFrontmostConnectedApp(apps) {
|
|
48430
|
-
const strongCandidates = apps.filter(
|
|
48431
|
-
(app) => app.applicationState === "active" || app.foregroundActiveSceneCount > 0
|
|
48432
|
-
);
|
|
48433
|
-
if (strongCandidates.length === 1) {
|
|
48434
|
-
return strongCandidates[0];
|
|
48435
|
-
}
|
|
48436
|
-
const weakCandidates = apps.filter(
|
|
48437
|
-
(app) => app.applicationState === "inactive" || app.foregroundInactiveSceneCount > 0
|
|
48438
|
-
);
|
|
48439
|
-
if (strongCandidates.length === 0 && weakCandidates.length === 1) {
|
|
48440
|
-
return weakCandidates[0];
|
|
48441
|
-
}
|
|
48442
|
-
return null;
|
|
48443
|
-
}
|
|
48444
|
-
async function inspectConnectedNativeApps(api) {
|
|
48445
|
-
const bundleIds = api.listConnectedBundleIds();
|
|
48446
|
-
const appStates = await Promise.all(bundleIds.map((bundleId) => api.getAppState(bundleId)));
|
|
48447
|
-
return appStates.sort((a, b) => a.bundleId.localeCompare(b.bundleId));
|
|
48448
|
-
}
|
|
48449
|
-
async function resolveNativeTargetApp(api, bundleId) {
|
|
48450
|
-
if (bundleId) {
|
|
48451
|
-
return { bundleId, source: "explicit" };
|
|
48452
|
-
}
|
|
48453
|
-
const connectedApps = await inspectConnectedNativeApps(api);
|
|
48454
|
-
if (connectedApps.length === 0) {
|
|
48455
|
-
throw new Error(
|
|
48456
|
-
"No native-devtools-connected apps are available for auto-targeting. Launch or restart the app first, provide bundleId explicitly, or use screenshot to inspect visible Home/system UI."
|
|
48457
|
-
);
|
|
48458
|
-
}
|
|
48459
|
-
const frontmost = chooseFrontmostConnectedApp(connectedApps);
|
|
48460
|
-
if (connectedApps.length === 1) {
|
|
48461
|
-
if (frontmost) {
|
|
48462
|
-
return {
|
|
48463
|
-
bundleId: connectedApps[0].bundleId,
|
|
48464
|
-
source: "single_connected_foreground_like"
|
|
48465
|
-
};
|
|
48466
|
-
}
|
|
48467
|
-
const app = connectedApps[0];
|
|
48468
|
-
throw new Error(
|
|
48469
|
-
`A single native-devtools-connected app is available, but it is not foreground-like and may be backgrounded while home/system UI is visible.
|
|
48470
|
-
- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})
|
|
48471
|
-
Provide bundleId explicitly if you still want to target this app.`
|
|
48472
|
-
);
|
|
48473
|
-
}
|
|
48474
|
-
if (frontmost) {
|
|
48475
|
-
return { bundleId: frontmost.bundleId, source: "frontmost_detected" };
|
|
48476
|
-
}
|
|
48477
|
-
const appList = connectedApps.map(
|
|
48478
|
-
(app) => `- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})`
|
|
48479
|
-
).join("\n");
|
|
48480
|
-
throw new Error(
|
|
48481
|
-
`Multiple native-devtools-connected apps are available and none can be identified as uniquely frontmost.
|
|
48482
|
-
${appList}
|
|
48483
|
-
Provide bundleId explicitly.`
|
|
48484
|
-
);
|
|
48485
|
-
}
|
|
48486
|
-
|
|
48487
|
-
// ../tool-server/src/tools/describe/platforms/ios.ts
|
|
48488
|
-
var iosRequires = ["xcrun"];
|
|
48489
|
-
async function describeIos(registry, device, params) {
|
|
48490
|
-
const axRef = axServiceRef(device);
|
|
48491
|
-
const axApi = await registry.resolveService(axRef.urn, axRef.options);
|
|
48492
|
-
const response = await axApi.describe();
|
|
48493
|
-
const tree = adaptAXDescribeToDescribeResult(response);
|
|
48494
|
-
if (tree.children.length > 0) {
|
|
48495
|
-
return { tree, source: "ax-service" };
|
|
48496
|
-
}
|
|
48497
|
-
try {
|
|
48498
|
-
const ndRef = nativeDevtoolsRef(device);
|
|
48499
|
-
const nativeApi = await registry.resolveService(ndRef.urn, ndRef.options);
|
|
48500
|
-
const target = await resolveNativeTargetApp(nativeApi, params.bundleId);
|
|
48501
|
-
if (await nativeApi.requiresAppRestart(target.bundleId)) {
|
|
48502
|
-
return { tree, source: "ax-service", should_restart: true };
|
|
48503
|
-
}
|
|
48504
|
-
const rawResult = await nativeApi.queryViewHierarchy(
|
|
48505
|
-
target.bundleId,
|
|
48506
|
-
"ViewHierarchy.describeScreen"
|
|
48507
|
-
);
|
|
48508
|
-
if (rawResult.error) {
|
|
48509
|
-
return { tree, source: "ax-service" };
|
|
48510
|
-
}
|
|
48511
|
-
const parsed = parseNativeDescribeScreenResult(rawResult);
|
|
48512
|
-
const nativeTree = adaptNativeDescribeToDescribeResult(parsed);
|
|
48513
|
-
return { tree: nativeTree, source: "native-devtools" };
|
|
48514
|
-
} catch {
|
|
48515
|
-
return { tree, source: "ax-service" };
|
|
48516
|
-
}
|
|
48517
|
-
}
|
|
48518
|
-
|
|
48519
48442
|
// ../tool-server/src/utils/android-screen.ts
|
|
48520
48443
|
async function getAndroidScreenSize(serial) {
|
|
48521
48444
|
const out = await adbShell(serial, "wm size", { timeoutMs: 5e3 });
|
|
@@ -48533,7 +48456,7 @@ async function getAndroidScreenSize(serial) {
|
|
|
48533
48456
|
return { width, height };
|
|
48534
48457
|
}
|
|
48535
48458
|
|
|
48536
|
-
// ../tool-server/src/
|
|
48459
|
+
// ../tool-server/src/tools/describe/platforms/android/uiautomator-parser.ts
|
|
48537
48460
|
function parseUiAutomatorXml(xml) {
|
|
48538
48461
|
const body = xml.replace(/^\s*<\?xml[^?]*\?>\s*/, "");
|
|
48539
48462
|
const tagRe = /<(\/?)([A-Za-z_][\w.-]*)((?:"[^"]*"|'[^']*'|[^"'/<>])*?)\s*(\/?)>/gs;
|
|
@@ -48915,7 +48838,7 @@ function parseUiAutomatorDump(rawOutput, screenW, screenH, options = {}) {
|
|
|
48915
48838
|
};
|
|
48916
48839
|
}
|
|
48917
48840
|
|
|
48918
|
-
// ../tool-server/src/tools/describe/platforms/android.ts
|
|
48841
|
+
// ../tool-server/src/tools/describe/platforms/android/index.ts
|
|
48919
48842
|
var androidRequires = ["adb"];
|
|
48920
48843
|
async function describeAndroid(udid, _bundleId) {
|
|
48921
48844
|
const randomSuffix = `${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
|
|
@@ -48939,6 +48862,226 @@ async function describeAndroid(udid, _bundleId) {
|
|
|
48939
48862
|
return { tree, source: "uiautomator" };
|
|
48940
48863
|
}
|
|
48941
48864
|
|
|
48865
|
+
// ../tool-server/src/utils/native-target-app.ts
|
|
48866
|
+
function chooseFrontmostConnectedApp(apps) {
|
|
48867
|
+
const strongCandidates = apps.filter(
|
|
48868
|
+
(app) => app.applicationState === "active" || app.foregroundActiveSceneCount > 0
|
|
48869
|
+
);
|
|
48870
|
+
if (strongCandidates.length === 1) {
|
|
48871
|
+
return strongCandidates[0];
|
|
48872
|
+
}
|
|
48873
|
+
const weakCandidates = apps.filter(
|
|
48874
|
+
(app) => app.applicationState === "inactive" || app.foregroundInactiveSceneCount > 0
|
|
48875
|
+
);
|
|
48876
|
+
if (strongCandidates.length === 0 && weakCandidates.length === 1) {
|
|
48877
|
+
return weakCandidates[0];
|
|
48878
|
+
}
|
|
48879
|
+
return null;
|
|
48880
|
+
}
|
|
48881
|
+
async function inspectConnectedNativeApps(api) {
|
|
48882
|
+
const bundleIds = api.listConnectedBundleIds();
|
|
48883
|
+
const appStates = await Promise.all(bundleIds.map((bundleId) => api.getAppState(bundleId)));
|
|
48884
|
+
return appStates.sort((a, b) => a.bundleId.localeCompare(b.bundleId));
|
|
48885
|
+
}
|
|
48886
|
+
async function resolveNativeTargetApp(api, bundleId) {
|
|
48887
|
+
if (bundleId) {
|
|
48888
|
+
return { bundleId, source: "explicit" };
|
|
48889
|
+
}
|
|
48890
|
+
const connectedApps = await inspectConnectedNativeApps(api);
|
|
48891
|
+
if (connectedApps.length === 0) {
|
|
48892
|
+
throw new Error(
|
|
48893
|
+
"No native-devtools-connected apps are available for auto-targeting. Launch or restart the app first, provide bundleId explicitly, or use screenshot to inspect visible Home/system UI."
|
|
48894
|
+
);
|
|
48895
|
+
}
|
|
48896
|
+
const frontmost = chooseFrontmostConnectedApp(connectedApps);
|
|
48897
|
+
if (connectedApps.length === 1) {
|
|
48898
|
+
if (frontmost) {
|
|
48899
|
+
return {
|
|
48900
|
+
bundleId: connectedApps[0].bundleId,
|
|
48901
|
+
source: "single_connected_foreground_like"
|
|
48902
|
+
};
|
|
48903
|
+
}
|
|
48904
|
+
const app = connectedApps[0];
|
|
48905
|
+
throw new Error(
|
|
48906
|
+
`A single native-devtools-connected app is available, but it is not foreground-like and may be backgrounded while home/system UI is visible.
|
|
48907
|
+
- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})
|
|
48908
|
+
Provide bundleId explicitly if you still want to target this app.`
|
|
48909
|
+
);
|
|
48910
|
+
}
|
|
48911
|
+
if (frontmost) {
|
|
48912
|
+
return { bundleId: frontmost.bundleId, source: "frontmost_detected" };
|
|
48913
|
+
}
|
|
48914
|
+
const appList = connectedApps.map(
|
|
48915
|
+
(app) => `- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})`
|
|
48916
|
+
).join("\n");
|
|
48917
|
+
throw new Error(
|
|
48918
|
+
`Multiple native-devtools-connected apps are available and none can be identified as uniquely frontmost.
|
|
48919
|
+
${appList}
|
|
48920
|
+
Provide bundleId explicitly.`
|
|
48921
|
+
);
|
|
48922
|
+
}
|
|
48923
|
+
|
|
48924
|
+
// ../tool-server/src/tools/describe/contract.ts
|
|
48925
|
+
var describeFrameSchema = external_exports.object({
|
|
48926
|
+
x: external_exports.number().finite().min(0).max(1),
|
|
48927
|
+
y: external_exports.number().finite().min(0).max(1),
|
|
48928
|
+
width: external_exports.number().finite().min(0).max(1),
|
|
48929
|
+
height: external_exports.number().finite().min(0).max(1)
|
|
48930
|
+
});
|
|
48931
|
+
var describeNodeSchema = external_exports.lazy(
|
|
48932
|
+
() => external_exports.object({
|
|
48933
|
+
role: external_exports.string().min(1),
|
|
48934
|
+
frame: describeFrameSchema,
|
|
48935
|
+
children: external_exports.array(describeNodeSchema),
|
|
48936
|
+
label: external_exports.string().optional(),
|
|
48937
|
+
identifier: external_exports.string().optional(),
|
|
48938
|
+
value: external_exports.string().optional(),
|
|
48939
|
+
clickable: external_exports.boolean().optional(),
|
|
48940
|
+
longClickable: external_exports.boolean().optional(),
|
|
48941
|
+
scrollable: external_exports.boolean().optional(),
|
|
48942
|
+
checkable: external_exports.boolean().optional(),
|
|
48943
|
+
checked: external_exports.boolean().optional(),
|
|
48944
|
+
disabled: external_exports.boolean().optional(),
|
|
48945
|
+
password: external_exports.boolean().optional(),
|
|
48946
|
+
scrollHidden: external_exports.number().int().nonnegative().optional()
|
|
48947
|
+
}).passthrough()
|
|
48948
|
+
);
|
|
48949
|
+
function parseDescribeResult(input) {
|
|
48950
|
+
return describeNodeSchema.parse(input);
|
|
48951
|
+
}
|
|
48952
|
+
|
|
48953
|
+
// ../tool-server/src/tools/describe/platforms/ios/ios-native-adapter.ts
|
|
48954
|
+
function clamp01(value) {
|
|
48955
|
+
return Math.min(1, Math.max(0, value));
|
|
48956
|
+
}
|
|
48957
|
+
function roundNormalized(value) {
|
|
48958
|
+
return Math.round(value * 1e12) / 1e12;
|
|
48959
|
+
}
|
|
48960
|
+
function clampNormalizedFrame(frame) {
|
|
48961
|
+
const x1 = clamp01(frame.x);
|
|
48962
|
+
const y1 = clamp01(frame.y);
|
|
48963
|
+
const x2 = clamp01(frame.x + frame.width);
|
|
48964
|
+
const y2 = clamp01(frame.y + frame.height);
|
|
48965
|
+
const width = x2 - x1;
|
|
48966
|
+
const height = y2 - y1;
|
|
48967
|
+
if (width <= 0 || height <= 0) {
|
|
48968
|
+
return null;
|
|
48969
|
+
}
|
|
48970
|
+
return {
|
|
48971
|
+
x: roundNormalized(x1),
|
|
48972
|
+
y: roundNormalized(y1),
|
|
48973
|
+
width: roundNormalized(width),
|
|
48974
|
+
height: roundNormalized(height)
|
|
48975
|
+
};
|
|
48976
|
+
}
|
|
48977
|
+
function mapNativeTraitsToDescribeRole(traits) {
|
|
48978
|
+
const set = new Set(traits);
|
|
48979
|
+
if (set.has("header")) return "AXHeading";
|
|
48980
|
+
if (set.has("button") || set.has("toggleButton")) return "AXButton";
|
|
48981
|
+
if (set.has("searchField")) return "AXTextField";
|
|
48982
|
+
if (set.has("link")) return "AXLink";
|
|
48983
|
+
if (set.has("image")) return "AXImage";
|
|
48984
|
+
if (set.has("staticText")) return "AXStaticText";
|
|
48985
|
+
if (set.has("tabBar")) return "AXTabBar";
|
|
48986
|
+
if (set.has("adjustable")) return "AXAdjustable";
|
|
48987
|
+
return "AXGroup";
|
|
48988
|
+
}
|
|
48989
|
+
function adaptNativeDescribeElementToDescribeNode(element) {
|
|
48990
|
+
const frame = clampNormalizedFrame(element.normalizedFrame);
|
|
48991
|
+
if (!frame) return null;
|
|
48992
|
+
return {
|
|
48993
|
+
role: mapNativeTraitsToDescribeRole(element.traits),
|
|
48994
|
+
frame,
|
|
48995
|
+
children: [],
|
|
48996
|
+
label: element.label,
|
|
48997
|
+
identifier: element.identifier,
|
|
48998
|
+
value: element.value
|
|
48999
|
+
};
|
|
49000
|
+
}
|
|
49001
|
+
function adaptNativeDescribeToDescribeResult(result) {
|
|
49002
|
+
const children = result.elements.map(adaptNativeDescribeElementToDescribeNode).filter((node) => node !== null);
|
|
49003
|
+
return parseDescribeResult({
|
|
49004
|
+
role: "AXGroup",
|
|
49005
|
+
frame: {
|
|
49006
|
+
x: 0,
|
|
49007
|
+
y: 0,
|
|
49008
|
+
width: 1,
|
|
49009
|
+
height: 1
|
|
49010
|
+
},
|
|
49011
|
+
children
|
|
49012
|
+
});
|
|
49013
|
+
}
|
|
49014
|
+
|
|
49015
|
+
// ../tool-server/src/tools/describe/platforms/ios/ios-ax-adapter.ts
|
|
49016
|
+
function clamp012(value) {
|
|
49017
|
+
return Math.min(1, Math.max(0, value));
|
|
49018
|
+
}
|
|
49019
|
+
function roundNormalized2(value) {
|
|
49020
|
+
return Math.round(value * 1e12) / 1e12;
|
|
49021
|
+
}
|
|
49022
|
+
function adaptAXElement(el) {
|
|
49023
|
+
if (!el.frame) return null;
|
|
49024
|
+
const x1 = clamp012(el.frame.x);
|
|
49025
|
+
const y1 = clamp012(el.frame.y);
|
|
49026
|
+
const x2 = clamp012(el.frame.x + el.frame.width);
|
|
49027
|
+
const y2 = clamp012(el.frame.y + el.frame.height);
|
|
49028
|
+
const width = x2 - x1;
|
|
49029
|
+
const height = y2 - y1;
|
|
49030
|
+
if (width <= 0 || height <= 0) return null;
|
|
49031
|
+
return {
|
|
49032
|
+
role: mapNativeTraitsToDescribeRole(el.traits ?? []),
|
|
49033
|
+
frame: {
|
|
49034
|
+
x: roundNormalized2(x1),
|
|
49035
|
+
y: roundNormalized2(y1),
|
|
49036
|
+
width: roundNormalized2(width),
|
|
49037
|
+
height: roundNormalized2(height)
|
|
49038
|
+
},
|
|
49039
|
+
children: [],
|
|
49040
|
+
label: el.label,
|
|
49041
|
+
value: el.value
|
|
49042
|
+
};
|
|
49043
|
+
}
|
|
49044
|
+
function adaptAXDescribeToDescribeResult(response) {
|
|
49045
|
+
const children = response.elements.map(adaptAXElement).filter((n) => n !== null);
|
|
49046
|
+
return parseDescribeResult({
|
|
49047
|
+
role: "AXGroup",
|
|
49048
|
+
frame: { x: 0, y: 0, width: 1, height: 1 },
|
|
49049
|
+
children
|
|
49050
|
+
});
|
|
49051
|
+
}
|
|
49052
|
+
|
|
49053
|
+
// ../tool-server/src/tools/describe/platforms/ios/index.ts
|
|
49054
|
+
var iosRequires = ["xcrun"];
|
|
49055
|
+
async function describeIos(registry, device, params) {
|
|
49056
|
+
const axRef = axServiceRef(device);
|
|
49057
|
+
const axApi = await registry.resolveService(axRef.urn, axRef.options);
|
|
49058
|
+
const response = await axApi.describe();
|
|
49059
|
+
const tree = adaptAXDescribeToDescribeResult(response);
|
|
49060
|
+
if (tree.children.length > 0) {
|
|
49061
|
+
return { tree, source: "ax-service" };
|
|
49062
|
+
}
|
|
49063
|
+
try {
|
|
49064
|
+
const ndRef = nativeDevtoolsRef(device);
|
|
49065
|
+
const nativeApi = await registry.resolveService(ndRef.urn, ndRef.options);
|
|
49066
|
+
const target = await resolveNativeTargetApp(nativeApi, params.bundleId);
|
|
49067
|
+
if (await nativeApi.requiresAppRestart(target.bundleId)) {
|
|
49068
|
+
return { tree, source: "ax-service", should_restart: true };
|
|
49069
|
+
}
|
|
49070
|
+
const rawResult = await nativeApi.queryViewHierarchy(
|
|
49071
|
+
target.bundleId,
|
|
49072
|
+
"ViewHierarchy.describeScreen"
|
|
49073
|
+
);
|
|
49074
|
+
if (rawResult.error) {
|
|
49075
|
+
return { tree, source: "ax-service" };
|
|
49076
|
+
}
|
|
49077
|
+
const parsed = parseNativeDescribeScreenResult(rawResult);
|
|
49078
|
+
const nativeTree = adaptNativeDescribeToDescribeResult(parsed);
|
|
49079
|
+
return { tree: nativeTree, source: "native-devtools" };
|
|
49080
|
+
} catch {
|
|
49081
|
+
return { tree, source: "ax-service" };
|
|
49082
|
+
}
|
|
49083
|
+
}
|
|
49084
|
+
|
|
48942
49085
|
// ../tool-server/src/tools/describe/index.ts
|
|
48943
49086
|
var zodSchema33 = external_exports.object({
|
|
48944
49087
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
@@ -49016,6 +49159,25 @@ function classifyStaleness({
|
|
|
49016
49159
|
};
|
|
49017
49160
|
}
|
|
49018
49161
|
|
|
49162
|
+
// ../tool-server/src/utils/react-profiler/devtools-bootstrap.ts
|
|
49163
|
+
function bootstrapFailureMessage(bootstrap) {
|
|
49164
|
+
switch (bootstrap.reason) {
|
|
49165
|
+
case "no-hook":
|
|
49166
|
+
case "no-rdt-module":
|
|
49167
|
+
return "React DevTools is not available in this app. This usually means the app is a production build. Ask the user to run a development build of the app, then retry.";
|
|
49168
|
+
case "no-renderers":
|
|
49169
|
+
return "React has not rendered yet, so there is nothing to profile. Ask the user to wait until the app shows React content (or navigate to a screen with React content), then retry.";
|
|
49170
|
+
case "no-metro-modules":
|
|
49171
|
+
return "Could not attach the React DevTools backend: the JS runtime does not expose a Metro module registry. This runtime is not a standard Metro-bundled React Native app and the React profiler cannot proceed. Inform the user that React profiling is only supported on standard Metro / React Native bundles.";
|
|
49172
|
+
case "unsupported-rdt-version":
|
|
49173
|
+
return "This app is running React Native older than 0.74, which the React profiler does not support. Ask the user to upgrade React Native to 0.74 or newer to use this tool.";
|
|
49174
|
+
default: {
|
|
49175
|
+
const detail = bootstrap.message ? ` (runtime error: ${bootstrap.message})` : "";
|
|
49176
|
+
return `Could not attach the React DevTools backend${detail}. Ask the user to fully reload the JS bundle and retry. If the error persists, the runtime may not be supported by the React profiler.`;
|
|
49177
|
+
}
|
|
49178
|
+
}
|
|
49179
|
+
}
|
|
49180
|
+
|
|
49019
49181
|
// ../tool-server/src/tools/profiler/react/react-profiler-start.ts
|
|
49020
49182
|
var zodSchema34 = external_exports.object({
|
|
49021
49183
|
port: external_exports.coerce.number().default(8081).describe("Metro server port"),
|
|
@@ -49086,20 +49248,40 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
49086
49248
|
}
|
|
49087
49249
|
const cdp = api.cdp;
|
|
49088
49250
|
await cdp.evaluate(REACT_NATIVE_PROFILER_SETUP_SCRIPT);
|
|
49089
|
-
|
|
49251
|
+
let stateJson = await cdp.evaluate(READ_STATE_SCRIPT);
|
|
49090
49252
|
if (!stateJson) {
|
|
49091
49253
|
throw new Error("Failed to read React profiler state from runtime (no value returned).");
|
|
49092
49254
|
}
|
|
49093
|
-
|
|
49255
|
+
let state2 = JSON.parse(stateJson);
|
|
49094
49256
|
if (!state2.hookExists) {
|
|
49095
49257
|
throw new Error(
|
|
49096
|
-
"
|
|
49258
|
+
"React DevTools is not available in this app. This usually means the app is a production build. Ask the user to run a development build of the app, then retry."
|
|
49097
49259
|
);
|
|
49098
49260
|
}
|
|
49099
49261
|
if (!("rendererInterfaceFound" in state2) || !state2.rendererInterfaceFound) {
|
|
49100
|
-
|
|
49101
|
-
|
|
49102
|
-
|
|
49262
|
+
const bootstrapJson = await cdp.evaluate(BOOTSTRAP_DEVTOOLS_BACKEND_SCRIPT);
|
|
49263
|
+
if (!bootstrapJson) {
|
|
49264
|
+
throw new Error(
|
|
49265
|
+
"Failed to attach React DevTools backend (no value returned from runtime)."
|
|
49266
|
+
);
|
|
49267
|
+
}
|
|
49268
|
+
const bootstrap = JSON.parse(bootstrapJson);
|
|
49269
|
+
if (!bootstrap.ok) {
|
|
49270
|
+
throw new Error(bootstrapFailureMessage(bootstrap));
|
|
49271
|
+
}
|
|
49272
|
+
await cdp.evaluate(REACT_NATIVE_PROFILER_SETUP_SCRIPT);
|
|
49273
|
+
stateJson = await cdp.evaluate(READ_STATE_SCRIPT);
|
|
49274
|
+
if (!stateJson) {
|
|
49275
|
+
throw new Error(
|
|
49276
|
+
"Failed to re-read React profiler state after attach (no value returned)."
|
|
49277
|
+
);
|
|
49278
|
+
}
|
|
49279
|
+
state2 = JSON.parse(stateJson);
|
|
49280
|
+
if (!state2.hookExists || !("rendererInterfaceFound" in state2) || !state2.rendererInterfaceFound) {
|
|
49281
|
+
throw new Error(
|
|
49282
|
+
"Attached the React DevTools backend but no React renderer registered itself afterwards. Ask the user to fully reload the JS bundle and retry."
|
|
49283
|
+
);
|
|
49284
|
+
}
|
|
49103
49285
|
}
|
|
49104
49286
|
if (state2.isRunning) {
|
|
49105
49287
|
const owner = state2.owner;
|
|
@@ -49115,7 +49297,7 @@ Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot
|
|
|
49115
49297
|
owner,
|
|
49116
49298
|
age_seconds: staleness.ageSeconds,
|
|
49117
49299
|
stale: staleness.stale,
|
|
49118
|
-
how_to_reclaim:
|
|
49300
|
+
how_to_reclaim: "Another profiling session is already active \u2014 see the `owner` field. Ask the user before taking over and explain that the prior session's data will be discarded; to take over, call react-profiler-start again with { force: true }. If `stale` is true, the prior owner is likely gone and you may take over without prompting the user."
|
|
49119
49301
|
};
|
|
49120
49302
|
}
|
|
49121
49303
|
await cdp.evaluate(STOP_FOR_TAKEOVER_SCRIPT).catch(ignore);
|
|
@@ -54518,14 +54700,20 @@ function toYamlStep(step) {
|
|
|
54518
54700
|
if (step.kind === "echo") {
|
|
54519
54701
|
return { echo: step.message };
|
|
54520
54702
|
}
|
|
54521
|
-
const
|
|
54522
|
-
|
|
54703
|
+
const yaml = {
|
|
54704
|
+
tool: step.name
|
|
54705
|
+
};
|
|
54706
|
+
if (Object.keys(step.args).length > 0) yaml.args = step.args;
|
|
54707
|
+
if (step.delayMs !== void 0) yaml.delayMs = step.delayMs;
|
|
54708
|
+
return yaml;
|
|
54523
54709
|
}
|
|
54524
54710
|
function fromYamlStep(raw) {
|
|
54525
54711
|
if ("echo" in raw) {
|
|
54526
54712
|
return { kind: "echo", message: raw.echo };
|
|
54527
54713
|
}
|
|
54528
|
-
|
|
54714
|
+
const step = { kind: "tool", name: raw.tool, args: raw.args ?? {} };
|
|
54715
|
+
if (raw.delayMs !== void 0) step.delayMs = raw.delayMs;
|
|
54716
|
+
return step;
|
|
54529
54717
|
}
|
|
54530
54718
|
function serializeFlow(flow) {
|
|
54531
54719
|
const doc = {
|
|
@@ -54618,7 +54806,8 @@ var zodSchema53 = external_exports.object({
|
|
|
54618
54806
|
command: external_exports.string().describe('MCP tool name (e.g. "tap", "screenshot", "launch-app")'),
|
|
54619
54807
|
args: external_exports.string().optional().describe(
|
|
54620
54808
|
`Tool arguments as a JSON string, e.g. '{"udid": "ABC", "x": 0.5, "y": 0.3}'. Omit for tools with no arguments.`
|
|
54621
|
-
)
|
|
54809
|
+
),
|
|
54810
|
+
delayMs: external_exports.number().int().min(0).optional().describe("Milliseconds to sleep before executing this step during replay.")
|
|
54622
54811
|
});
|
|
54623
54812
|
function createFlowAddStepTool(registry) {
|
|
54624
54813
|
return {
|
|
@@ -54635,7 +54824,8 @@ If a step was recorded by mistake, edit the .yaml file directly to remove it.`,
|
|
|
54635
54824
|
const flowFile = await appendStep(filePath, {
|
|
54636
54825
|
kind: "tool",
|
|
54637
54826
|
name: params.command,
|
|
54638
|
-
args
|
|
54827
|
+
args,
|
|
54828
|
+
delayMs: params.delayMs
|
|
54639
54829
|
});
|
|
54640
54830
|
return {
|
|
54641
54831
|
message: `Step added to "${flowName}" flow`,
|
|
@@ -54719,13 +54909,15 @@ function createRunFlowTool(registry) {
|
|
|
54719
54909
|
id: "flow-execute",
|
|
54720
54910
|
description: `Run a saved flow from the .argent/flows/ directory.
|
|
54721
54911
|
Each step is executed in order: tool calls are dispatched through the registry,
|
|
54722
|
-
echo steps print a message.
|
|
54912
|
+
echo steps print a message. A tool step may carry \`delayMs: <ms>\` to sleep
|
|
54913
|
+
that long before the step runs. Returns the result of every step, including images.
|
|
54723
54914
|
Use when you want to replay a recorded flow or run a scripted sequence of simulator actions.
|
|
54724
54915
|
Fails if the flow file does not exist or a step tool raises an error (execution stops at that step).
|
|
54725
54916
|
|
|
54726
54917
|
If the flow has an execution prerequisite and prerequisiteAcknowledged is not
|
|
54727
54918
|
set to true, the tool returns a notice with the prerequisite instead of running.
|
|
54728
54919
|
Use flow-read-prerequisite to inspect the prerequisite beforehand.`,
|
|
54920
|
+
longRunning: true,
|
|
54729
54921
|
zodSchema: zodSchema56,
|
|
54730
54922
|
services: () => ({}),
|
|
54731
54923
|
async execute(_services, params) {
|
|
@@ -54747,6 +54939,7 @@ Use flow-read-prerequisite to inspect the prerequisite beforehand.`,
|
|
|
54747
54939
|
steps.push({ kind: "echo", message: step.message });
|
|
54748
54940
|
continue;
|
|
54749
54941
|
}
|
|
54942
|
+
if (step.delayMs) await sleep4(step.delayMs);
|
|
54750
54943
|
const toolDef = registry.getTool(step.name);
|
|
54751
54944
|
try {
|
|
54752
54945
|
const result = await registry.invokeTool(step.name, step.args);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -99,7 +99,7 @@ flow-execute { name: "open-settings", project_root: "/Users/dev/MyApp", prereq
|
|
|
99
99
|
Flow files use YAML. The top-level is an object with `executionPrerequisite` (describes required state) and `steps` (array of actions):
|
|
100
100
|
|
|
101
101
|
- `- echo: <message>` — a label
|
|
102
|
-
- `- tool: <name>` with optional `args:` — a tool call
|
|
102
|
+
- `- tool: <name>` with optional `args:` — a tool call. Add `delayMs: <ms>` to sleep that long before the step runs (use sparingly — only when the app needs a fixed wait between actions).
|
|
103
103
|
|
|
104
104
|
Example `.yaml` file:
|
|
105
105
|
|