@swmansion/argent 0.7.0-next.4 → 0.7.0
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/bin/ax-service
CHANGED
|
Binary file
|
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/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;
|
|
@@ -41948,7 +41948,7 @@ var import_node_https = __toESM(require("node:https"));
|
|
|
41948
41948
|
var import_semver = __toESM(require_semver2());
|
|
41949
41949
|
|
|
41950
41950
|
// ../tool-server/package.json
|
|
41951
|
-
var version = "0.7.0
|
|
41951
|
+
var version = "0.7.0";
|
|
41952
41952
|
|
|
41953
41953
|
// ../tool-server/src/utils/update-checker.ts
|
|
41954
41954
|
var PACKAGE_NAME = "@swmansion/argent";
|
|
@@ -42492,11 +42492,15 @@ var ADB_KILL_SIGNAL = "SIGKILL";
|
|
|
42492
42492
|
function describeAdbFailure(args, err) {
|
|
42493
42493
|
const e = err;
|
|
42494
42494
|
const argv = args.join(" ");
|
|
42495
|
-
const
|
|
42496
|
-
|
|
42497
|
-
const
|
|
42498
|
-
|
|
42499
|
-
|
|
42495
|
+
const ioDetail = (e.stderr ?? "").trim() || (e.stdout ?? "").trim();
|
|
42496
|
+
if (ioDetail) return new Error(`adb ${argv} failed: ${ioDetail}`);
|
|
42497
|
+
const meta = [];
|
|
42498
|
+
if (e.killed) meta.push("killed=true");
|
|
42499
|
+
if (e.signal) meta.push(`signal=${e.signal}`);
|
|
42500
|
+
if (e.code) meta.push(`code=${e.code}`);
|
|
42501
|
+
const baseMsg = (e.message ?? String(err)).trim();
|
|
42502
|
+
const suffix = meta.length ? ` (${meta.join(" ")})` : "";
|
|
42503
|
+
return new Error(`adb ${argv} failed: ${baseMsg}${suffix}`);
|
|
42500
42504
|
}
|
|
42501
42505
|
async function runAdb(args, options = {}) {
|
|
42502
42506
|
const adbPath = await resolveAdbOrThrow();
|
|
@@ -48296,226 +48300,6 @@ ${body.slice(0, MAX_BODY_SIZE)}...`;
|
|
|
48296
48300
|
}
|
|
48297
48301
|
};
|
|
48298
48302
|
|
|
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
48303
|
// ../tool-server/src/utils/android-screen.ts
|
|
48520
48304
|
async function getAndroidScreenSize(serial) {
|
|
48521
48305
|
const out = await adbShell(serial, "wm size", { timeoutMs: 5e3 });
|
|
@@ -48533,7 +48317,7 @@ async function getAndroidScreenSize(serial) {
|
|
|
48533
48317
|
return { width, height };
|
|
48534
48318
|
}
|
|
48535
48319
|
|
|
48536
|
-
// ../tool-server/src/
|
|
48320
|
+
// ../tool-server/src/tools/describe/platforms/android/uiautomator-parser.ts
|
|
48537
48321
|
function parseUiAutomatorXml(xml) {
|
|
48538
48322
|
const body = xml.replace(/^\s*<\?xml[^?]*\?>\s*/, "");
|
|
48539
48323
|
const tagRe = /<(\/?)([A-Za-z_][\w.-]*)((?:"[^"]*"|'[^']*'|[^"'/<>])*?)\s*(\/?)>/gs;
|
|
@@ -48915,7 +48699,7 @@ function parseUiAutomatorDump(rawOutput, screenW, screenH, options = {}) {
|
|
|
48915
48699
|
};
|
|
48916
48700
|
}
|
|
48917
48701
|
|
|
48918
|
-
// ../tool-server/src/tools/describe/platforms/android.ts
|
|
48702
|
+
// ../tool-server/src/tools/describe/platforms/android/index.ts
|
|
48919
48703
|
var androidRequires = ["adb"];
|
|
48920
48704
|
async function describeAndroid(udid, _bundleId) {
|
|
48921
48705
|
const randomSuffix = `${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
|
|
@@ -48939,6 +48723,226 @@ async function describeAndroid(udid, _bundleId) {
|
|
|
48939
48723
|
return { tree, source: "uiautomator" };
|
|
48940
48724
|
}
|
|
48941
48725
|
|
|
48726
|
+
// ../tool-server/src/utils/native-target-app.ts
|
|
48727
|
+
function chooseFrontmostConnectedApp(apps) {
|
|
48728
|
+
const strongCandidates = apps.filter(
|
|
48729
|
+
(app) => app.applicationState === "active" || app.foregroundActiveSceneCount > 0
|
|
48730
|
+
);
|
|
48731
|
+
if (strongCandidates.length === 1) {
|
|
48732
|
+
return strongCandidates[0];
|
|
48733
|
+
}
|
|
48734
|
+
const weakCandidates = apps.filter(
|
|
48735
|
+
(app) => app.applicationState === "inactive" || app.foregroundInactiveSceneCount > 0
|
|
48736
|
+
);
|
|
48737
|
+
if (strongCandidates.length === 0 && weakCandidates.length === 1) {
|
|
48738
|
+
return weakCandidates[0];
|
|
48739
|
+
}
|
|
48740
|
+
return null;
|
|
48741
|
+
}
|
|
48742
|
+
async function inspectConnectedNativeApps(api) {
|
|
48743
|
+
const bundleIds = api.listConnectedBundleIds();
|
|
48744
|
+
const appStates = await Promise.all(bundleIds.map((bundleId) => api.getAppState(bundleId)));
|
|
48745
|
+
return appStates.sort((a, b) => a.bundleId.localeCompare(b.bundleId));
|
|
48746
|
+
}
|
|
48747
|
+
async function resolveNativeTargetApp(api, bundleId) {
|
|
48748
|
+
if (bundleId) {
|
|
48749
|
+
return { bundleId, source: "explicit" };
|
|
48750
|
+
}
|
|
48751
|
+
const connectedApps = await inspectConnectedNativeApps(api);
|
|
48752
|
+
if (connectedApps.length === 0) {
|
|
48753
|
+
throw new Error(
|
|
48754
|
+
"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."
|
|
48755
|
+
);
|
|
48756
|
+
}
|
|
48757
|
+
const frontmost = chooseFrontmostConnectedApp(connectedApps);
|
|
48758
|
+
if (connectedApps.length === 1) {
|
|
48759
|
+
if (frontmost) {
|
|
48760
|
+
return {
|
|
48761
|
+
bundleId: connectedApps[0].bundleId,
|
|
48762
|
+
source: "single_connected_foreground_like"
|
|
48763
|
+
};
|
|
48764
|
+
}
|
|
48765
|
+
const app = connectedApps[0];
|
|
48766
|
+
throw new Error(
|
|
48767
|
+
`A single native-devtools-connected app is available, but it is not foreground-like and may be backgrounded while home/system UI is visible.
|
|
48768
|
+
- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})
|
|
48769
|
+
Provide bundleId explicitly if you still want to target this app.`
|
|
48770
|
+
);
|
|
48771
|
+
}
|
|
48772
|
+
if (frontmost) {
|
|
48773
|
+
return { bundleId: frontmost.bundleId, source: "frontmost_detected" };
|
|
48774
|
+
}
|
|
48775
|
+
const appList = connectedApps.map(
|
|
48776
|
+
(app) => `- ${app.bundleId} (applicationState=${app.applicationState}, foregroundActiveScenes=${app.foregroundActiveSceneCount}, foregroundInactiveScenes=${app.foregroundInactiveSceneCount})`
|
|
48777
|
+
).join("\n");
|
|
48778
|
+
throw new Error(
|
|
48779
|
+
`Multiple native-devtools-connected apps are available and none can be identified as uniquely frontmost.
|
|
48780
|
+
${appList}
|
|
48781
|
+
Provide bundleId explicitly.`
|
|
48782
|
+
);
|
|
48783
|
+
}
|
|
48784
|
+
|
|
48785
|
+
// ../tool-server/src/tools/describe/contract.ts
|
|
48786
|
+
var describeFrameSchema = external_exports.object({
|
|
48787
|
+
x: external_exports.number().finite().min(0).max(1),
|
|
48788
|
+
y: external_exports.number().finite().min(0).max(1),
|
|
48789
|
+
width: external_exports.number().finite().min(0).max(1),
|
|
48790
|
+
height: external_exports.number().finite().min(0).max(1)
|
|
48791
|
+
});
|
|
48792
|
+
var describeNodeSchema = external_exports.lazy(
|
|
48793
|
+
() => external_exports.object({
|
|
48794
|
+
role: external_exports.string().min(1),
|
|
48795
|
+
frame: describeFrameSchema,
|
|
48796
|
+
children: external_exports.array(describeNodeSchema),
|
|
48797
|
+
label: external_exports.string().optional(),
|
|
48798
|
+
identifier: external_exports.string().optional(),
|
|
48799
|
+
value: external_exports.string().optional(),
|
|
48800
|
+
clickable: external_exports.boolean().optional(),
|
|
48801
|
+
longClickable: external_exports.boolean().optional(),
|
|
48802
|
+
scrollable: external_exports.boolean().optional(),
|
|
48803
|
+
checkable: external_exports.boolean().optional(),
|
|
48804
|
+
checked: external_exports.boolean().optional(),
|
|
48805
|
+
disabled: external_exports.boolean().optional(),
|
|
48806
|
+
password: external_exports.boolean().optional(),
|
|
48807
|
+
scrollHidden: external_exports.number().int().nonnegative().optional()
|
|
48808
|
+
}).passthrough()
|
|
48809
|
+
);
|
|
48810
|
+
function parseDescribeResult(input) {
|
|
48811
|
+
return describeNodeSchema.parse(input);
|
|
48812
|
+
}
|
|
48813
|
+
|
|
48814
|
+
// ../tool-server/src/tools/describe/platforms/ios/ios-native-adapter.ts
|
|
48815
|
+
function clamp01(value) {
|
|
48816
|
+
return Math.min(1, Math.max(0, value));
|
|
48817
|
+
}
|
|
48818
|
+
function roundNormalized(value) {
|
|
48819
|
+
return Math.round(value * 1e12) / 1e12;
|
|
48820
|
+
}
|
|
48821
|
+
function clampNormalizedFrame(frame) {
|
|
48822
|
+
const x1 = clamp01(frame.x);
|
|
48823
|
+
const y1 = clamp01(frame.y);
|
|
48824
|
+
const x2 = clamp01(frame.x + frame.width);
|
|
48825
|
+
const y2 = clamp01(frame.y + frame.height);
|
|
48826
|
+
const width = x2 - x1;
|
|
48827
|
+
const height = y2 - y1;
|
|
48828
|
+
if (width <= 0 || height <= 0) {
|
|
48829
|
+
return null;
|
|
48830
|
+
}
|
|
48831
|
+
return {
|
|
48832
|
+
x: roundNormalized(x1),
|
|
48833
|
+
y: roundNormalized(y1),
|
|
48834
|
+
width: roundNormalized(width),
|
|
48835
|
+
height: roundNormalized(height)
|
|
48836
|
+
};
|
|
48837
|
+
}
|
|
48838
|
+
function mapNativeTraitsToDescribeRole(traits) {
|
|
48839
|
+
const set = new Set(traits);
|
|
48840
|
+
if (set.has("header")) return "AXHeading";
|
|
48841
|
+
if (set.has("button") || set.has("toggleButton")) return "AXButton";
|
|
48842
|
+
if (set.has("searchField")) return "AXTextField";
|
|
48843
|
+
if (set.has("link")) return "AXLink";
|
|
48844
|
+
if (set.has("image")) return "AXImage";
|
|
48845
|
+
if (set.has("staticText")) return "AXStaticText";
|
|
48846
|
+
if (set.has("tabBar")) return "AXTabBar";
|
|
48847
|
+
if (set.has("adjustable")) return "AXAdjustable";
|
|
48848
|
+
return "AXGroup";
|
|
48849
|
+
}
|
|
48850
|
+
function adaptNativeDescribeElementToDescribeNode(element) {
|
|
48851
|
+
const frame = clampNormalizedFrame(element.normalizedFrame);
|
|
48852
|
+
if (!frame) return null;
|
|
48853
|
+
return {
|
|
48854
|
+
role: mapNativeTraitsToDescribeRole(element.traits),
|
|
48855
|
+
frame,
|
|
48856
|
+
children: [],
|
|
48857
|
+
label: element.label,
|
|
48858
|
+
identifier: element.identifier,
|
|
48859
|
+
value: element.value
|
|
48860
|
+
};
|
|
48861
|
+
}
|
|
48862
|
+
function adaptNativeDescribeToDescribeResult(result) {
|
|
48863
|
+
const children = result.elements.map(adaptNativeDescribeElementToDescribeNode).filter((node) => node !== null);
|
|
48864
|
+
return parseDescribeResult({
|
|
48865
|
+
role: "AXGroup",
|
|
48866
|
+
frame: {
|
|
48867
|
+
x: 0,
|
|
48868
|
+
y: 0,
|
|
48869
|
+
width: 1,
|
|
48870
|
+
height: 1
|
|
48871
|
+
},
|
|
48872
|
+
children
|
|
48873
|
+
});
|
|
48874
|
+
}
|
|
48875
|
+
|
|
48876
|
+
// ../tool-server/src/tools/describe/platforms/ios/ios-ax-adapter.ts
|
|
48877
|
+
function clamp012(value) {
|
|
48878
|
+
return Math.min(1, Math.max(0, value));
|
|
48879
|
+
}
|
|
48880
|
+
function roundNormalized2(value) {
|
|
48881
|
+
return Math.round(value * 1e12) / 1e12;
|
|
48882
|
+
}
|
|
48883
|
+
function adaptAXElement(el) {
|
|
48884
|
+
if (!el.frame) return null;
|
|
48885
|
+
const x1 = clamp012(el.frame.x);
|
|
48886
|
+
const y1 = clamp012(el.frame.y);
|
|
48887
|
+
const x2 = clamp012(el.frame.x + el.frame.width);
|
|
48888
|
+
const y2 = clamp012(el.frame.y + el.frame.height);
|
|
48889
|
+
const width = x2 - x1;
|
|
48890
|
+
const height = y2 - y1;
|
|
48891
|
+
if (width <= 0 || height <= 0) return null;
|
|
48892
|
+
return {
|
|
48893
|
+
role: mapNativeTraitsToDescribeRole(el.traits ?? []),
|
|
48894
|
+
frame: {
|
|
48895
|
+
x: roundNormalized2(x1),
|
|
48896
|
+
y: roundNormalized2(y1),
|
|
48897
|
+
width: roundNormalized2(width),
|
|
48898
|
+
height: roundNormalized2(height)
|
|
48899
|
+
},
|
|
48900
|
+
children: [],
|
|
48901
|
+
label: el.label,
|
|
48902
|
+
value: el.value
|
|
48903
|
+
};
|
|
48904
|
+
}
|
|
48905
|
+
function adaptAXDescribeToDescribeResult(response) {
|
|
48906
|
+
const children = response.elements.map(adaptAXElement).filter((n) => n !== null);
|
|
48907
|
+
return parseDescribeResult({
|
|
48908
|
+
role: "AXGroup",
|
|
48909
|
+
frame: { x: 0, y: 0, width: 1, height: 1 },
|
|
48910
|
+
children
|
|
48911
|
+
});
|
|
48912
|
+
}
|
|
48913
|
+
|
|
48914
|
+
// ../tool-server/src/tools/describe/platforms/ios/index.ts
|
|
48915
|
+
var iosRequires = ["xcrun"];
|
|
48916
|
+
async function describeIos(registry, device, params) {
|
|
48917
|
+
const axRef = axServiceRef(device);
|
|
48918
|
+
const axApi = await registry.resolveService(axRef.urn, axRef.options);
|
|
48919
|
+
const response = await axApi.describe();
|
|
48920
|
+
const tree = adaptAXDescribeToDescribeResult(response);
|
|
48921
|
+
if (tree.children.length > 0) {
|
|
48922
|
+
return { tree, source: "ax-service" };
|
|
48923
|
+
}
|
|
48924
|
+
try {
|
|
48925
|
+
const ndRef = nativeDevtoolsRef(device);
|
|
48926
|
+
const nativeApi = await registry.resolveService(ndRef.urn, ndRef.options);
|
|
48927
|
+
const target = await resolveNativeTargetApp(nativeApi, params.bundleId);
|
|
48928
|
+
if (await nativeApi.requiresAppRestart(target.bundleId)) {
|
|
48929
|
+
return { tree, source: "ax-service", should_restart: true };
|
|
48930
|
+
}
|
|
48931
|
+
const rawResult = await nativeApi.queryViewHierarchy(
|
|
48932
|
+
target.bundleId,
|
|
48933
|
+
"ViewHierarchy.describeScreen"
|
|
48934
|
+
);
|
|
48935
|
+
if (rawResult.error) {
|
|
48936
|
+
return { tree, source: "ax-service" };
|
|
48937
|
+
}
|
|
48938
|
+
const parsed = parseNativeDescribeScreenResult(rawResult);
|
|
48939
|
+
const nativeTree = adaptNativeDescribeToDescribeResult(parsed);
|
|
48940
|
+
return { tree: nativeTree, source: "native-devtools" };
|
|
48941
|
+
} catch {
|
|
48942
|
+
return { tree, source: "ax-service" };
|
|
48943
|
+
}
|
|
48944
|
+
}
|
|
48945
|
+
|
|
48942
48946
|
// ../tool-server/src/tools/describe/index.ts
|
|
48943
48947
|
var zodSchema33 = external_exports.object({
|
|
48944
48948
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
Binary file
|
|
Binary file
|
|
Binary file
|