@swmansion/argent 0.20.1-next.5 → 0.20.1-next.7
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 +2 -0
- package/dist/installer.mjs +2 -0
- package/dist/mcp-server.mjs +2 -0
- package/dist/tool-server.cjs +436 -102
- package/package.json +1 -1
- package/skills/argent-device-interact/SKILL.md +1 -0
package/dist/cli-cmds.mjs
CHANGED
|
@@ -1285,6 +1285,8 @@ var FAILURE_CODES = {
|
|
|
1285
1285
|
IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
|
|
1286
1286
|
IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
|
|
1287
1287
|
IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
|
|
1288
|
+
IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
|
|
1289
|
+
ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
|
|
1288
1290
|
SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
|
|
1289
1291
|
NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
|
|
1290
1292
|
NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
|
package/dist/installer.mjs
CHANGED
|
@@ -16434,6 +16434,8 @@ var FAILURE_CODES = {
|
|
|
16434
16434
|
IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
|
|
16435
16435
|
IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
|
|
16436
16436
|
IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
|
|
16437
|
+
IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
|
|
16438
|
+
ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
|
|
16437
16439
|
SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
|
|
16438
16440
|
NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
|
|
16439
16441
|
NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -16491,6 +16491,8 @@ var FAILURE_CODES = {
|
|
|
16491
16491
|
IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
|
|
16492
16492
|
IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
|
|
16493
16493
|
IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
|
|
16494
|
+
IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
|
|
16495
|
+
ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
|
|
16494
16496
|
SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
|
|
16495
16497
|
NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
|
|
16496
16498
|
NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
|
package/dist/tool-server.cjs
CHANGED
|
@@ -608,6 +608,8 @@ var init_failure_codes = __esm({
|
|
|
608
608
|
IOS_REINSTALL_INSTALL_FAILED: "IOS_REINSTALL_INSTALL_FAILED",
|
|
609
609
|
IOS_RESTART_LAUNCH_FAILED: "IOS_RESTART_LAUNCH_FAILED",
|
|
610
610
|
IOS_SETTINGS_PERMISSION_FAILED: "IOS_SETTINGS_PERMISSION_FAILED",
|
|
611
|
+
IOS_SHAKE_FAILED: "IOS_SHAKE_FAILED",
|
|
612
|
+
ANDROID_SHAKE_FAILED: "ANDROID_SHAKE_FAILED",
|
|
611
613
|
SETTINGS_PERMISSION_UNSUPPORTED: "SETTINGS_PERMISSION_UNSUPPORTED",
|
|
612
614
|
NATIVE_DEVTOOLS_DESCRIBE_ERROR: "NATIVE_DEVTOOLS_DESCRIBE_ERROR",
|
|
613
615
|
NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR: "NATIVE_DEVTOOLS_VIEW_AT_POINT_ERROR",
|
|
@@ -98632,6 +98634,23 @@ async function simctlListDevices() {
|
|
|
98632
98634
|
);
|
|
98633
98635
|
}
|
|
98634
98636
|
}
|
|
98637
|
+
var remoteRuntimeKindCache = /* @__PURE__ */ new Map();
|
|
98638
|
+
async function isRemoteTvOsSimulator(udid) {
|
|
98639
|
+
const id = stripRemotePrefix(udid);
|
|
98640
|
+
const cached3 = remoteRuntimeKindCache.get(id);
|
|
98641
|
+
if (cached3) return cached3 === "tv";
|
|
98642
|
+
try {
|
|
98643
|
+
const { devices } = await simctlListDevices();
|
|
98644
|
+
for (const [runtime, entries] of Object.entries(devices)) {
|
|
98645
|
+
if (!entries.some((d) => d.udid === id)) continue;
|
|
98646
|
+
const kind = runtime.includes("tvOS") ? "tv" : "mobile";
|
|
98647
|
+
remoteRuntimeKindCache.set(id, kind);
|
|
98648
|
+
return kind === "tv";
|
|
98649
|
+
}
|
|
98650
|
+
} catch {
|
|
98651
|
+
}
|
|
98652
|
+
return false;
|
|
98653
|
+
}
|
|
98635
98654
|
async function simctlBoot(udid) {
|
|
98636
98655
|
await run(["simctl", "boot", stripRemotePrefix(udid)]);
|
|
98637
98656
|
}
|
|
@@ -99364,23 +99383,23 @@ var InvalidToolInputError = class extends Error {
|
|
|
99364
99383
|
});
|
|
99365
99384
|
}
|
|
99366
99385
|
};
|
|
99367
|
-
function platformMatrix(platform,
|
|
99386
|
+
function platformMatrix(platform, capability33) {
|
|
99368
99387
|
switch (platform) {
|
|
99369
99388
|
case "ios":
|
|
99370
|
-
return
|
|
99389
|
+
return capability33.apple;
|
|
99371
99390
|
case "ios-remote":
|
|
99372
|
-
return
|
|
99391
|
+
return capability33.appleRemote;
|
|
99373
99392
|
case "android":
|
|
99374
|
-
return
|
|
99393
|
+
return capability33.android;
|
|
99375
99394
|
case "chromium":
|
|
99376
|
-
return
|
|
99395
|
+
return capability33.chromium;
|
|
99377
99396
|
case "vega":
|
|
99378
|
-
return
|
|
99397
|
+
return capability33.vega;
|
|
99379
99398
|
}
|
|
99380
99399
|
}
|
|
99381
|
-
function assertSupported(toolId,
|
|
99382
|
-
if (!
|
|
99383
|
-
const matrix = platformMatrix(device.platform,
|
|
99400
|
+
function assertSupported(toolId, capability33, device) {
|
|
99401
|
+
if (!capability33) return;
|
|
99402
|
+
const matrix = platformMatrix(device.platform, capability33);
|
|
99384
99403
|
if (!matrix) {
|
|
99385
99404
|
throw new UnsupportedOperationError(toolId, device, `no ${device.platform} support declared`);
|
|
99386
99405
|
}
|
|
@@ -99388,7 +99407,7 @@ function assertSupported(toolId, capability32, device) {
|
|
|
99388
99407
|
if (!supported) {
|
|
99389
99408
|
throw new UnsupportedOperationError(toolId, device, `kind '${device.kind}' not supported`);
|
|
99390
99409
|
}
|
|
99391
|
-
if (
|
|
99410
|
+
if (capability33.supports && !capability33.supports(device)) {
|
|
99392
99411
|
throw new UnsupportedOperationError(toolId, device, "supports() refiner rejected device");
|
|
99393
99412
|
}
|
|
99394
99413
|
}
|
|
@@ -123264,6 +123283,274 @@ Returns { orientation }. Fails if the target device is not booted.`,
|
|
|
123264
123283
|
}
|
|
123265
123284
|
};
|
|
123266
123285
|
|
|
123286
|
+
// ../tool-server/src/tools/shake/schema.ts
|
|
123287
|
+
init_zod();
|
|
123288
|
+
var MAX_SHAKE_COUNT = 10;
|
|
123289
|
+
var shakeZodSchema = external_exports.object({
|
|
123290
|
+
udid: external_exports.string().min(1).describe(
|
|
123291
|
+
"Target device id from `list-devices` (iOS simulator UDID or Android emulator serial)."
|
|
123292
|
+
),
|
|
123293
|
+
count: external_exports.number().int().min(1).max(MAX_SHAKE_COUNT).optional().describe(
|
|
123294
|
+
`How many shake gestures to deliver back-to-back (default 1, max ${MAX_SHAKE_COUNT}). Raise it for apps whose shake detector needs sustained motion before it fires.`
|
|
123295
|
+
)
|
|
123296
|
+
});
|
|
123297
|
+
|
|
123298
|
+
// ../tool-server/src/tools/shake/platforms/ios.ts
|
|
123299
|
+
var import_node_child_process26 = require("node:child_process");
|
|
123300
|
+
var import_node_util20 = require("node:util");
|
|
123301
|
+
init_src();
|
|
123302
|
+
var execFileAsync20 = (0, import_node_util20.promisify)(import_node_child_process26.execFile);
|
|
123303
|
+
var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
|
|
123304
|
+
var SHAKE_INTERVAL_MS = 400;
|
|
123305
|
+
var sleep10 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
123306
|
+
var NOTIFYUTIL_ARGV = ["notifyutil", "-p", SHAKE_NOTIFICATION];
|
|
123307
|
+
function rejectTv(toolId, device) {
|
|
123308
|
+
throw new UnsupportedOperationError(
|
|
123309
|
+
toolId,
|
|
123310
|
+
device,
|
|
123311
|
+
"tvOS has no shake gesture \u2014 a TV is focus-driven, use tv-remote"
|
|
123312
|
+
);
|
|
123313
|
+
}
|
|
123314
|
+
function shakeFailure(udid, detail, cause) {
|
|
123315
|
+
const shutdownHint = /current state:\s*shutdown|unable to lookup/i.test(detail) ? " The simulator must be booted first \u2014 use boot-device." : "";
|
|
123316
|
+
return new FailureError(
|
|
123317
|
+
`Failed to shake ${udid}: ${detail.trim()}${shutdownHint}`,
|
|
123318
|
+
{
|
|
123319
|
+
error_code: FAILURE_CODES.IOS_SHAKE_FAILED,
|
|
123320
|
+
failure_stage: "ios_shake_notifyutil",
|
|
123321
|
+
failure_area: "tool_server",
|
|
123322
|
+
error_kind: "subprocess",
|
|
123323
|
+
// Only a thrown subprocess error carries the syscall/exit metadata. The
|
|
123324
|
+
// remote backend reports a non-zero child in its JSON payload instead of
|
|
123325
|
+
// throwing, so there is no error object to mine there.
|
|
123326
|
+
...cause ? subprocessFailureMetadata(cause, "xcrun_simctl") : {}
|
|
123327
|
+
},
|
|
123328
|
+
cause ? { cause } : void 0
|
|
123329
|
+
);
|
|
123330
|
+
}
|
|
123331
|
+
var iosImpl4 = {
|
|
123332
|
+
requires: ["xcrun"],
|
|
123333
|
+
async handler(_services, params, device) {
|
|
123334
|
+
const { udid } = params;
|
|
123335
|
+
const count2 = params.count ?? 1;
|
|
123336
|
+
if (await isTvOsSimulator(udid)) rejectTv("shake", device);
|
|
123337
|
+
const args = await simctlArgsForUdid(udid, ["spawn", udid, ...NOTIFYUTIL_ARGV]);
|
|
123338
|
+
for (let i = 0; i < count2; i++) {
|
|
123339
|
+
if (i > 0) await sleep10(SHAKE_INTERVAL_MS);
|
|
123340
|
+
try {
|
|
123341
|
+
await execFileAsync20("xcrun", args, { timeout: 15e3 });
|
|
123342
|
+
} catch (err) {
|
|
123343
|
+
const error52 = err instanceof Error ? err : new Error(String(err));
|
|
123344
|
+
throw shakeFailure(udid, error52.message, error52);
|
|
123345
|
+
}
|
|
123346
|
+
}
|
|
123347
|
+
return { shaken: true, count: count2 };
|
|
123348
|
+
}
|
|
123349
|
+
};
|
|
123350
|
+
var iosRemoteImpl6 = {
|
|
123351
|
+
requires: ["sim-remote"],
|
|
123352
|
+
async handler(_services, params, device) {
|
|
123353
|
+
const { udid } = params;
|
|
123354
|
+
const count2 = params.count ?? 1;
|
|
123355
|
+
if (await isRemoteTvOsSimulator(udid)) rejectTv("shake", device);
|
|
123356
|
+
for (let i = 0; i < count2; i++) {
|
|
123357
|
+
if (i > 0) await sleep10(SHAKE_INTERVAL_MS);
|
|
123358
|
+
let result;
|
|
123359
|
+
try {
|
|
123360
|
+
result = await simctlSpawn(udid, { args: NOTIFYUTIL_ARGV });
|
|
123361
|
+
} catch (err) {
|
|
123362
|
+
const error52 = err instanceof Error ? err : new Error(String(err));
|
|
123363
|
+
throw shakeFailure(udid, error52.message, error52);
|
|
123364
|
+
}
|
|
123365
|
+
if (result.exitCode !== 0) {
|
|
123366
|
+
throw shakeFailure(
|
|
123367
|
+
udid,
|
|
123368
|
+
`notifyutil exited ${result.exitCode ?? "unknown"}${result.stderr ? `: ${result.stderr}` : ""}`
|
|
123369
|
+
);
|
|
123370
|
+
}
|
|
123371
|
+
}
|
|
123372
|
+
return { shaken: true, count: count2 };
|
|
123373
|
+
}
|
|
123374
|
+
};
|
|
123375
|
+
|
|
123376
|
+
// ../tool-server/src/tools/shake/platforms/android.ts
|
|
123377
|
+
init_src();
|
|
123378
|
+
init_adb();
|
|
123379
|
+
var SHAKE_AMPLITUDE = 30;
|
|
123380
|
+
var SWINGS_PER_SHAKE = 8;
|
|
123381
|
+
var SWING_INTERVAL_MS = 50;
|
|
123382
|
+
var DEFAULT_REST = { x: 0, y: 9.81, z: 0 };
|
|
123383
|
+
var MIN_REST_MAGNITUDE = 5;
|
|
123384
|
+
var MAX_REST_MAGNITUDE = 15;
|
|
123385
|
+
var DECIMAL = String.raw`[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?`;
|
|
123386
|
+
var ACCELERATION_RE = new RegExp(
|
|
123387
|
+
String.raw`acceleration\s*=\s*(${DECIMAL}):(${DECIMAL}):(${DECIMAL})`
|
|
123388
|
+
);
|
|
123389
|
+
function parseAcceleration(stdout) {
|
|
123390
|
+
const match = ACCELERATION_RE.exec(stdout);
|
|
123391
|
+
if (!match) return null;
|
|
123392
|
+
const [x, y, z2] = [match[1], match[2], match[3]].map(Number);
|
|
123393
|
+
if (![x, y, z2].every((n) => Number.isFinite(n))) return null;
|
|
123394
|
+
return { x, y, z: z2 };
|
|
123395
|
+
}
|
|
123396
|
+
function restingVectorFrom(stdout) {
|
|
123397
|
+
const read = parseAcceleration(stdout);
|
|
123398
|
+
if (!read) return DEFAULT_REST;
|
|
123399
|
+
const magnitude = Math.hypot(read.x, read.y, read.z);
|
|
123400
|
+
if (magnitude < MIN_REST_MAGNITUDE || magnitude > MAX_REST_MAGNITUDE) return DEFAULT_REST;
|
|
123401
|
+
return read;
|
|
123402
|
+
}
|
|
123403
|
+
var fmt = (v) => `${v.x.toFixed(4)}:${v.y.toFixed(4)}:${v.z.toFixed(4)}`;
|
|
123404
|
+
var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
123405
|
+
async function emuConsole(serial, args) {
|
|
123406
|
+
const { stdout } = await runAdb(["-s", serial, "emu", ...args], { timeoutMs: 1e4 });
|
|
123407
|
+
const lines = stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
123408
|
+
const verdict = lines[lines.length - 1];
|
|
123409
|
+
if (verdict?.startsWith("KO:")) {
|
|
123410
|
+
throw new Error(`emulator console rejected \`${args.join(" ")}\` \u2014 ${verdict}`);
|
|
123411
|
+
}
|
|
123412
|
+
return stdout;
|
|
123413
|
+
}
|
|
123414
|
+
var inFlightByDevice = /* @__PURE__ */ new Map();
|
|
123415
|
+
function withDeviceLock(serial, fn) {
|
|
123416
|
+
const previous = inFlightByDevice.get(serial) ?? Promise.resolve();
|
|
123417
|
+
const run2 = previous.then(fn, fn);
|
|
123418
|
+
const settled = run2.catch(() => {
|
|
123419
|
+
});
|
|
123420
|
+
inFlightByDevice.set(serial, settled);
|
|
123421
|
+
void settled.then(() => {
|
|
123422
|
+
if (inFlightByDevice.get(serial) === settled) inFlightByDevice.delete(serial);
|
|
123423
|
+
});
|
|
123424
|
+
return run2;
|
|
123425
|
+
}
|
|
123426
|
+
var androidImpl6 = {
|
|
123427
|
+
requires: ["adb"],
|
|
123428
|
+
async handler(_services, params, device) {
|
|
123429
|
+
const serial = params.udid;
|
|
123430
|
+
const count2 = params.count ?? 1;
|
|
123431
|
+
if (await isAndroidTv(serial)) {
|
|
123432
|
+
throw new UnsupportedOperationError(
|
|
123433
|
+
"shake",
|
|
123434
|
+
device,
|
|
123435
|
+
"Android TV has no shake gesture \u2014 a TV is focus-driven, use tv-remote"
|
|
123436
|
+
);
|
|
123437
|
+
}
|
|
123438
|
+
if (consolePortFromAdbSerial(serial) === null) {
|
|
123439
|
+
throw new FailureError(
|
|
123440
|
+
`Cannot shake ${serial}: sensor injection needs an Android emulator.`,
|
|
123441
|
+
{
|
|
123442
|
+
error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
|
|
123443
|
+
failure_stage: "android_shake_not_emulator",
|
|
123444
|
+
failure_area: "tool_server",
|
|
123445
|
+
error_kind: "validation"
|
|
123446
|
+
}
|
|
123447
|
+
);
|
|
123448
|
+
}
|
|
123449
|
+
const setAcceleration = async (v) => {
|
|
123450
|
+
await emuConsole(serial, ["sensor", "set", "acceleration", fmt(v)]);
|
|
123451
|
+
};
|
|
123452
|
+
return withDeviceLock(serial, async () => {
|
|
123453
|
+
let rest;
|
|
123454
|
+
try {
|
|
123455
|
+
rest = restingVectorFrom(await emuConsole(serial, ["sensor", "get", "acceleration"]));
|
|
123456
|
+
} catch (err) {
|
|
123457
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
123458
|
+
throw new FailureError(
|
|
123459
|
+
`Failed to read the accelerometer on ${serial}: ${detail.trim()}`,
|
|
123460
|
+
{
|
|
123461
|
+
error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
|
|
123462
|
+
failure_stage: "android_shake_sensor_get",
|
|
123463
|
+
failure_area: "tool_server",
|
|
123464
|
+
error_kind: "subprocess"
|
|
123465
|
+
},
|
|
123466
|
+
{ cause: err instanceof Error ? err : new Error(String(err)) }
|
|
123467
|
+
);
|
|
123468
|
+
}
|
|
123469
|
+
try {
|
|
123470
|
+
for (let gesture = 0; gesture < count2; gesture++) {
|
|
123471
|
+
for (let swing = 0; swing < SWINGS_PER_SHAKE; swing++) {
|
|
123472
|
+
const direction = swing % 2 === 0 ? 1 : -1;
|
|
123473
|
+
await setAcceleration({
|
|
123474
|
+
x: rest.x + direction * SHAKE_AMPLITUDE,
|
|
123475
|
+
y: rest.y,
|
|
123476
|
+
z: rest.z
|
|
123477
|
+
});
|
|
123478
|
+
await sleep11(SWING_INTERVAL_MS);
|
|
123479
|
+
}
|
|
123480
|
+
}
|
|
123481
|
+
} catch (err) {
|
|
123482
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
123483
|
+
throw new FailureError(
|
|
123484
|
+
`Failed to shake ${serial}: ${detail.trim()}`,
|
|
123485
|
+
{
|
|
123486
|
+
error_code: FAILURE_CODES.ANDROID_SHAKE_FAILED,
|
|
123487
|
+
failure_stage: "android_shake_sensor_set",
|
|
123488
|
+
failure_area: "tool_server",
|
|
123489
|
+
error_kind: "subprocess"
|
|
123490
|
+
},
|
|
123491
|
+
{ cause: err instanceof Error ? err : new Error(String(err)) }
|
|
123492
|
+
);
|
|
123493
|
+
} finally {
|
|
123494
|
+
await setAcceleration(rest).catch(() => {
|
|
123495
|
+
});
|
|
123496
|
+
}
|
|
123497
|
+
return { shaken: true, count: count2 };
|
|
123498
|
+
});
|
|
123499
|
+
}
|
|
123500
|
+
};
|
|
123501
|
+
|
|
123502
|
+
// ../tool-server/src/tools/shake/index.ts
|
|
123503
|
+
var capability18 = {
|
|
123504
|
+
// Simulator only. A physical iPhone's motion comes from real hardware; there
|
|
123505
|
+
// is no host-side hook to fake it, so `device` stays false and a paired phone
|
|
123506
|
+
// gets a clean 400 instead of a silent no-op.
|
|
123507
|
+
apple: { simulator: true },
|
|
123508
|
+
// A remote simulator is still a simulator: `sim-remote spawn` runs the same
|
|
123509
|
+
// in-simulator `notifyutil` argv the local path does.
|
|
123510
|
+
appleRemote: { simulator: true },
|
|
123511
|
+
// Android emulators only, for the same reason as iOS: a physical phone's
|
|
123512
|
+
// accelerometer can't be driven from the host. `unknown` is allowed through
|
|
123513
|
+
// because a serial that didn't resolve may still be an emulator; the handler
|
|
123514
|
+
// re-checks and rejects a non-emulator serial explicitly.
|
|
123515
|
+
android: { emulator: true, unknown: true }
|
|
123516
|
+
// No `vega`: a Fire TV is rejected here, by the absent block.
|
|
123517
|
+
//
|
|
123518
|
+
// TV targets that are NOT separate platforms cannot be excluded here. An
|
|
123519
|
+
// Apple TV simulator is `ios`/`simulator` and an Android TV emulator is
|
|
123520
|
+
// `android`/`emulator` — identical to a phone by id shape and device kind, so
|
|
123521
|
+
// the matrix admits them and each platform handler probes the runtime and
|
|
123522
|
+
// rejects a TV. `supports` can't do it: it is synchronous, while the runtime
|
|
123523
|
+
// kind is an async `simctl list` / `adb` probe.
|
|
123524
|
+
};
|
|
123525
|
+
var shakeTool = {
|
|
123526
|
+
id: "shake",
|
|
123527
|
+
interaction: {
|
|
123528
|
+
startedMsg: ({ params }) => params.count && params.count > 1 ? `Shaking device ${params.count}x` : "Shaking device",
|
|
123529
|
+
completedMsg: ({ params }) => params.count && params.count > 1 ? `Shook device ${params.count}x` : "Shook device",
|
|
123530
|
+
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to shake device: ${failureSignal2.error_code}`
|
|
123531
|
+
},
|
|
123532
|
+
description: `Shake the device (iOS simulator or Android emulator).
|
|
123533
|
+
Use to trigger anything bound to the shake gesture: iOS's "Undo Typing" / "Redo Typing" prompt in a text field, React Native's developer menu in a debug build, or an app's own shake-to-report handler.
|
|
123534
|
+
iOS delivers one discrete shake per gesture (the same motion event a physical device raises). Android has no OS-level shake event \u2014 the accelerometer is driven through a burst of hard direction changes so app-side detectors fire, and the resting orientation is restored afterwards.
|
|
123535
|
+
Set \`count\` above 1 when a detector needs sustained motion before it triggers.
|
|
123536
|
+
Returns { shaken: true, count }.
|
|
123537
|
+
Works on local and remote (sim-remote) iOS simulators.
|
|
123538
|
+
Only phone/tablet simulators and emulators are supported.`,
|
|
123539
|
+
searchHint: "shake motion accelerometer undo typing dev menu gesture",
|
|
123540
|
+
zodSchema: shakeZodSchema,
|
|
123541
|
+
capability: capability18,
|
|
123542
|
+
// Talks to `simctl` / `adb` directly, so no simulator-server is resolved —
|
|
123543
|
+
// avoids spawning one (and its ready-wait) for a tool that never uses it.
|
|
123544
|
+
services: () => ({}),
|
|
123545
|
+
execute: dispatchByPlatform({
|
|
123546
|
+
toolId: "shake",
|
|
123547
|
+
capability: capability18,
|
|
123548
|
+
ios: iosImpl4,
|
|
123549
|
+
iosRemote: iosRemoteImpl6,
|
|
123550
|
+
android: androidImpl6
|
|
123551
|
+
})
|
|
123552
|
+
};
|
|
123553
|
+
|
|
123267
123554
|
// ../tool-server/src/tools/tv-remote/index.ts
|
|
123268
123555
|
init_zod();
|
|
123269
123556
|
|
|
@@ -123360,7 +123647,7 @@ var zodSchema26 = external_exports.object({
|
|
|
123360
123647
|
'Repeat the whole `button` value this many times (default 1). Compact for long same-button runs, e.g. { button: "down", repeat: 12 }.'
|
|
123361
123648
|
)
|
|
123362
123649
|
});
|
|
123363
|
-
var
|
|
123650
|
+
var capability19 = {
|
|
123364
123651
|
apple: { simulator: true, device: true },
|
|
123365
123652
|
android: { emulator: true, device: true, unknown: true },
|
|
123366
123653
|
vega: { vvd: true }
|
|
@@ -123387,11 +123674,11 @@ Returns { pressed, count }.`,
|
|
|
123387
123674
|
longRunning: true,
|
|
123388
123675
|
searchHint: "tv remote dpad d-pad navigate focus up down left right select ok back home menu play pause rewind fast forward sequence path apple tv tvos android tv leanback vega fire tv",
|
|
123389
123676
|
zodSchema: zodSchema26,
|
|
123390
|
-
capability:
|
|
123677
|
+
capability: capability19,
|
|
123391
123678
|
services: () => ({}),
|
|
123392
123679
|
execute: dispatchByPlatform({
|
|
123393
123680
|
toolId: "tv-remote",
|
|
123394
|
-
capability:
|
|
123681
|
+
capability: capability19,
|
|
123395
123682
|
ios: makeIosImpl4(registry2),
|
|
123396
123683
|
android: makeAndroidImpl2(registry2),
|
|
123397
123684
|
vega: vegaImpl5
|
|
@@ -129565,7 +129852,7 @@ var conditionCompleted = {
|
|
|
129565
129852
|
hidden: "UI element became hidden",
|
|
129566
129853
|
text: "UI element matched expected text"
|
|
129567
129854
|
};
|
|
129568
|
-
var
|
|
129855
|
+
var capability20 = {
|
|
129569
129856
|
apple: { simulator: true, device: true },
|
|
129570
129857
|
android: { emulator: true, device: true, unknown: true },
|
|
129571
129858
|
chromium: { app: true },
|
|
@@ -129657,7 +129944,7 @@ or before tapping an element that appears asynchronously.`,
|
|
|
129657
129944
|
searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
|
|
129658
129945
|
longRunning: true,
|
|
129659
129946
|
zodSchema: zodSchema27,
|
|
129660
|
-
capability:
|
|
129947
|
+
capability: capability20,
|
|
129661
129948
|
services: (params) => {
|
|
129662
129949
|
const device = resolveDevice(params.udid);
|
|
129663
129950
|
if (device.platform === "chromium") {
|
|
@@ -129668,7 +129955,7 @@ or before tapping an element that appears asynchronously.`,
|
|
|
129668
129955
|
async execute(services, params, ctx) {
|
|
129669
129956
|
const signal = ctx?.signal;
|
|
129670
129957
|
const device = resolveDevice(params.udid);
|
|
129671
|
-
assertSupported(AWAIT_UI_ELEMENT_TOOL_ID,
|
|
129958
|
+
assertSupported(AWAIT_UI_ELEMENT_TOOL_ID, capability20, device);
|
|
129672
129959
|
if (device.platform === "ios") await ensureDeps(iosRequires);
|
|
129673
129960
|
else if (device.platform === "android") await ensureDeps(androidRequires);
|
|
129674
129961
|
else if (device.platform === "vega") await ensureDeps(vegaRequires);
|
|
@@ -129726,6 +130013,10 @@ var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
129726
130013
|
"button",
|
|
129727
130014
|
"keyboard",
|
|
129728
130015
|
"rotate",
|
|
130016
|
+
// Sequencing matters for shake: the interesting cases are races (shake while
|
|
130017
|
+
// a sheet is dismissing, shake right after typing), which need the steps
|
|
130018
|
+
// dispatched back-to-back rather than across separate round-trips.
|
|
130019
|
+
"shake",
|
|
129729
130020
|
// `tv-remote` drives the D-pad on a TV target (Apple TV / Android TV / Vega);
|
|
129730
130021
|
// `keyboard` types into the focused field there.
|
|
129731
130022
|
"tv-remote",
|
|
@@ -129738,7 +130029,7 @@ var zodSchema28 = external_exports.object({
|
|
|
129738
130029
|
steps: external_exports.array(
|
|
129739
130030
|
external_exports.object({
|
|
129740
130031
|
tool: external_exports.string().describe(
|
|
129741
|
-
"Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
|
|
130032
|
+
"Tool name \u2014 one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate, shake, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
|
|
129742
130033
|
),
|
|
129743
130034
|
args: external_exports.record(external_exports.string(), external_exports.unknown()).describe("Tool arguments (excluding udid, which is injected automatically)"),
|
|
129744
130035
|
delayMs: external_exports.number().optional().describe(
|
|
@@ -129747,7 +130038,7 @@ var zodSchema28 = external_exports.object({
|
|
|
129747
130038
|
})
|
|
129748
130039
|
).min(1).describe("Ordered list of interaction steps to execute sequentially")
|
|
129749
130040
|
});
|
|
129750
|
-
var
|
|
130041
|
+
var capability21 = {
|
|
129751
130042
|
apple: { simulator: true, device: true },
|
|
129752
130043
|
appleRemote: { simulator: true },
|
|
129753
130044
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -129789,6 +130080,7 @@ Allowed tools and their args (udid is auto-injected, do NOT include it in args):
|
|
|
129789
130080
|
keyboard: { text?: string, key?: string, delayMs?: number } (key pressed after text; TV: text only) [ios/android/chromium/vega/tv]
|
|
129790
130081
|
text supports {{secret:<NAME>}} placeholders, resolved server-side from ARGENT_SECRET_<NAME> env vars or an argent secrets file \u2014 credentials never enter agent context
|
|
129791
130082
|
rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android]
|
|
130083
|
+
shake: { count?: number } [ios sim/android emu]
|
|
129792
130084
|
tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega]
|
|
129793
130085
|
buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute \u2014 work on Android TV and Vega; rejected on the Apple TV simulator)
|
|
129794
130086
|
await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]
|
|
@@ -129824,7 +130116,7 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
|
|
|
129824
130116
|
longRunning: true,
|
|
129825
130117
|
searchHint: "batch sequence multiple gesture steps sequentially",
|
|
129826
130118
|
zodSchema: zodSchema28,
|
|
129827
|
-
capability:
|
|
130119
|
+
capability: capability21,
|
|
129828
130120
|
// No eagerly-declared service: each step resolves its own services through
|
|
129829
130121
|
// `invokeSubTool` below (simulator-server for iOS/Android, CDP for
|
|
129830
130122
|
// Chromium), so run-sequence itself needs none. An eager resolver can't be
|
|
@@ -132102,7 +132394,7 @@ function formatDescribeTree(root, opts) {
|
|
|
132102
132394
|
}
|
|
132103
132395
|
|
|
132104
132396
|
// ../tool-server/src/tools/describe/platforms/tv.ts
|
|
132105
|
-
var
|
|
132397
|
+
var sleep12 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
132106
132398
|
var EMPTY_RETRY_ATTEMPTS = 3;
|
|
132107
132399
|
var EMPTY_RETRY_DELAY_MS = 600;
|
|
132108
132400
|
var EMPTY_HINT = "No focusable elements after retrying and recycling the read path. The app is most likely still launching (splash / loading screen) or mid-transition \u2014 this is normal right after launch-app / restart-app. Wait ~2-3s and call describe again; a React Native app only exposes focus once its JS bundle has loaded. If it stays empty, take a screenshot to confirm what's actually on screen.";
|
|
@@ -132143,7 +132435,7 @@ async function describeTv(registry2, device) {
|
|
|
132143
132435
|
let res = await api.describe();
|
|
132144
132436
|
if (device.platform !== "android") {
|
|
132145
132437
|
for (let attempt = 1; attempt < EMPTY_RETRY_ATTEMPTS && isEmpty(res); attempt++) {
|
|
132146
|
-
await
|
|
132438
|
+
await sleep12(EMPTY_RETRY_DELAY_MS);
|
|
132147
132439
|
res = await api.describe();
|
|
132148
132440
|
}
|
|
132149
132441
|
}
|
|
@@ -132193,7 +132485,7 @@ var zodSchema38 = external_exports.object({
|
|
|
132193
132485
|
"Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on Android / Chromium."
|
|
132194
132486
|
)
|
|
132195
132487
|
});
|
|
132196
|
-
var
|
|
132488
|
+
var capability22 = {
|
|
132197
132489
|
apple: { simulator: true, device: true },
|
|
132198
132490
|
appleRemote: { simulator: true },
|
|
132199
132491
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -132203,7 +132495,7 @@ var capability21 = {
|
|
|
132203
132495
|
function makeDescribeExecute(registry2) {
|
|
132204
132496
|
return dispatchByPlatform({
|
|
132205
132497
|
toolId: "describe",
|
|
132206
|
-
capability:
|
|
132498
|
+
capability: capability22,
|
|
132207
132499
|
ios: {
|
|
132208
132500
|
requires: iosRequires,
|
|
132209
132501
|
handler: async (_services, params, device) => (
|
|
@@ -132278,7 +132570,7 @@ back/menu/home), then call describe again to confirm where focus landed.`,
|
|
|
132278
132570
|
alwaysLoad: true,
|
|
132279
132571
|
searchHint: "accessibility element tree ui hierarchy tap coordinates ios android chromium vega dom tv tvos apple tv android tv fire tv focus focusable remote dpad",
|
|
132280
132572
|
zodSchema: zodSchema38,
|
|
132281
|
-
capability:
|
|
132573
|
+
capability: capability22,
|
|
132282
132574
|
services: (params) => {
|
|
132283
132575
|
const device = resolveDevice(params.udid);
|
|
132284
132576
|
if (device.platform === "chromium") {
|
|
@@ -132307,7 +132599,7 @@ var zodSchema39 = external_exports.object({
|
|
|
132307
132599
|
`The screen must hold the same content for at least this long to count as settled (default ${DEFAULT_MIN_STABLE_MS}).`
|
|
132308
132600
|
)
|
|
132309
132601
|
});
|
|
132310
|
-
var
|
|
132602
|
+
var capability23 = {
|
|
132311
132603
|
apple: { simulator: true, device: true },
|
|
132312
132604
|
android: { emulator: true, device: true, unknown: true },
|
|
132313
132605
|
chromium: { app: true }
|
|
@@ -132351,7 +132643,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
|
|
|
132351
132643
|
searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
|
|
132352
132644
|
longRunning: true,
|
|
132353
132645
|
zodSchema: zodSchema39,
|
|
132354
|
-
capability:
|
|
132646
|
+
capability: capability23,
|
|
132355
132647
|
services: (params) => {
|
|
132356
132648
|
const device = resolveDevice(params.udid);
|
|
132357
132649
|
if (device.platform === "chromium") {
|
|
@@ -132361,7 +132653,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
|
|
|
132361
132653
|
},
|
|
132362
132654
|
async execute(services, params, ctx) {
|
|
132363
132655
|
const device = resolveDevice(params.udid);
|
|
132364
|
-
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID,
|
|
132656
|
+
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability23, device);
|
|
132365
132657
|
if (device.platform === "ios") await ensureDeps(iosRequires);
|
|
132366
132658
|
else if (device.platform === "android") await ensureDeps(androidRequires);
|
|
132367
132659
|
const isTvOs = device.platform === "ios" && await isTvOsSimulator(device.id);
|
|
@@ -135688,8 +135980,8 @@ var import_util6 = require("util");
|
|
|
135688
135980
|
var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
|
|
135689
135981
|
var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
|
|
135690
135982
|
async function execFileAsyncWithTimeout(file2, args, options = {}) {
|
|
135691
|
-
const
|
|
135692
|
-
const { stdout, stderr } = await
|
|
135983
|
+
const execFileAsync25 = (0, import_util6.promisify)(import_child_process2.execFile);
|
|
135984
|
+
const { stdout, stderr } = await execFileAsync25(file2, args, {
|
|
135693
135985
|
encoding: "utf-8",
|
|
135694
135986
|
...options,
|
|
135695
135987
|
// The timeout and maxBuffer are this wrapper's whole purpose (the
|
|
@@ -139049,7 +139341,7 @@ var zodSchema48 = external_exports.object({
|
|
|
139049
139341
|
"iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable \u2014 Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes \u2014 e.g. exported globally for the normal capture path \u2014 also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android."
|
|
139050
139342
|
)
|
|
139051
139343
|
});
|
|
139052
|
-
var
|
|
139344
|
+
var capability24 = {
|
|
139053
139345
|
apple: { simulator: true, device: true },
|
|
139054
139346
|
android: { emulator: true, device: true, unknown: true }
|
|
139055
139347
|
};
|
|
@@ -139060,7 +139352,7 @@ var nativeProfilerStartTool = {
|
|
|
139060
139352
|
completedMsg: () => "Started native profiler",
|
|
139061
139353
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start native profiler: ${failureSignal2.error_code}`
|
|
139062
139354
|
},
|
|
139063
|
-
capability:
|
|
139355
|
+
capability: capability24,
|
|
139064
139356
|
description: `Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal).
|
|
139065
139357
|
Auto-detects the running app process unless app_process is explicitly provided.
|
|
139066
139358
|
After starting, let the user interact with the app, then call native-profiler-stop.
|
|
@@ -139074,7 +139366,7 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
|
|
|
139074
139366
|
async execute(services, params) {
|
|
139075
139367
|
const api = services.session;
|
|
139076
139368
|
const device = resolveDevice(params.device_id);
|
|
139077
|
-
assertSupported("native-profiler-start",
|
|
139369
|
+
assertSupported("native-profiler-start", capability24, device);
|
|
139078
139370
|
if (api.platform === "ios") {
|
|
139079
139371
|
await ensureDeps(["xcrun"]);
|
|
139080
139372
|
return startNativeProfilerIos(api, params);
|
|
@@ -139091,7 +139383,7 @@ var zodSchema49 = external_exports.object({
|
|
|
139091
139383
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
139092
139384
|
)
|
|
139093
139385
|
});
|
|
139094
|
-
var
|
|
139386
|
+
var capability25 = {
|
|
139095
139387
|
apple: { simulator: true, device: true },
|
|
139096
139388
|
android: { emulator: true, device: true, unknown: true }
|
|
139097
139389
|
};
|
|
@@ -139112,7 +139404,7 @@ var nativeProfilerStopTool = {
|
|
|
139112
139404
|
completedMsg: ({ result }) => `Saved native profile ${result.traceFile.filename}`,
|
|
139113
139405
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
|
|
139114
139406
|
},
|
|
139115
|
-
capability:
|
|
139407
|
+
capability: capability25,
|
|
139116
139408
|
// Packaging plus the export passes routinely exceed the 30s fetch timeout.
|
|
139117
139409
|
longRunning: true,
|
|
139118
139410
|
description: `Stop native profiling and export trace data.
|
|
@@ -139129,7 +139421,7 @@ Fails if no active native-profiler-start session exists for the given device_id.
|
|
|
139129
139421
|
async execute(services, params, ctx) {
|
|
139130
139422
|
const api = services.session;
|
|
139131
139423
|
const device = resolveDevice(params.device_id);
|
|
139132
|
-
assertSupported("native-profiler-stop",
|
|
139424
|
+
assertSupported("native-profiler-stop", capability25, device);
|
|
139133
139425
|
if (api.platform === "ios") {
|
|
139134
139426
|
await ensureDeps(["xcrun"]);
|
|
139135
139427
|
const ios = await stopNativeProfilerIos(api);
|
|
@@ -139161,7 +139453,7 @@ var zodSchema50 = external_exports.object({
|
|
|
139161
139453
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
139162
139454
|
)
|
|
139163
139455
|
});
|
|
139164
|
-
var
|
|
139456
|
+
var capability26 = {
|
|
139165
139457
|
apple: { simulator: true, device: true },
|
|
139166
139458
|
android: { emulator: true, device: true, unknown: true }
|
|
139167
139459
|
};
|
|
@@ -139172,7 +139464,7 @@ var nativeProfilerAnalyzeTool = {
|
|
|
139172
139464
|
completedMsg: () => "Analyzed native profile",
|
|
139173
139465
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to analyze native profile: ${failureSignal2.error_code}`
|
|
139174
139466
|
},
|
|
139175
|
-
capability:
|
|
139467
|
+
capability: capability26,
|
|
139176
139468
|
description: `Analyze exported native trace data and return an LLM-optimized markdown report.
|
|
139177
139469
|
iOS: parses CPU time profile, UI hangs, and memory leaks from the exported XML files.
|
|
139178
139470
|
Android: queries the Perfetto .pftrace via the in-process Perfetto trace-processor engine for CPU hotspots, UI hangs with jank reason + main-thread state breakdown, GC annotation, and an RSS-growth weak signal.
|
|
@@ -139189,7 +139481,7 @@ Fails if native-profiler-stop has not been called first to export trace data.`,
|
|
|
139189
139481
|
async execute(services, params, ctx) {
|
|
139190
139482
|
const api = services.session;
|
|
139191
139483
|
const device = resolveDevice(params.device_id);
|
|
139192
|
-
assertSupported("native-profiler-analyze",
|
|
139484
|
+
assertSupported("native-profiler-analyze", capability26, device);
|
|
139193
139485
|
let result;
|
|
139194
139486
|
if (api.platform === "ios") {
|
|
139195
139487
|
await ensureDeps(["xcrun"]);
|
|
@@ -139673,7 +139965,7 @@ var WATERMARK_PNG_HEIGHT = 277;
|
|
|
139673
139965
|
var WATERMARK_PNG_BASE64 = "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";
|
|
139674
139966
|
|
|
139675
139967
|
// ../tool-server/src/tools/screen-recording/watermark.ts
|
|
139676
|
-
var
|
|
139968
|
+
var execFileAsync21 = (0, import_util7.promisify)(import_child_process6.execFile);
|
|
139677
139969
|
var OUTPUT_FPS = 30;
|
|
139678
139970
|
var FFMPEG_FALLBACK_PATHS = [
|
|
139679
139971
|
"/opt/homebrew/bin/ffmpeg",
|
|
@@ -139690,7 +139982,7 @@ var MASK_DARK_MAX_LUMA = 90;
|
|
|
139690
139982
|
var MASK_LIGHT_MIN_LUMA = 165;
|
|
139691
139983
|
async function resolveBinary(name, fallbacks) {
|
|
139692
139984
|
try {
|
|
139693
|
-
await
|
|
139985
|
+
await execFileAsync21("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
|
|
139694
139986
|
return name;
|
|
139695
139987
|
} catch {
|
|
139696
139988
|
}
|
|
@@ -140168,7 +140460,7 @@ var zodSchema51 = external_exports.object({
|
|
|
140168
140460
|
"Default true. Draw simulator-server's touch visualizer into the recording: a pulse marks each tap, a comet trail follows swipes and drags, and paired markers show two-finger pinch/rotate, so the video makes clear where every interaction landed. Set false to record the raw screen with no overlay."
|
|
140169
140461
|
)
|
|
140170
140462
|
});
|
|
140171
|
-
var
|
|
140463
|
+
var capability27 = {
|
|
140172
140464
|
apple: { simulator: true },
|
|
140173
140465
|
android: { emulator: true, device: true, unknown: true }
|
|
140174
140466
|
};
|
|
@@ -140180,7 +140472,7 @@ function createScreenRecordingStartTool(registry2) {
|
|
|
140180
140472
|
completedMsg: () => "Started screen recording",
|
|
140181
140473
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start screen recording: ${failureSignal2.error_code}`
|
|
140182
140474
|
},
|
|
140183
|
-
capability:
|
|
140475
|
+
capability: capability27,
|
|
140184
140476
|
description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
|
|
140185
140477
|
By default stretches where the screen does not change are trimmed out (see trimStatic), so a long session with only brief activity comes back as a short clip instead of minutes of dead air.
|
|
140186
140478
|
By default every tap, swipe, drag, pinch and rotate is drawn into the video as an on-screen touch marker (see showTouches), so the recording shows where each interaction landed.
|
|
@@ -140200,7 +140492,7 @@ Fails if a recording is already running on the device, the device is not booted,
|
|
|
140200
140492
|
async execute(services, params) {
|
|
140201
140493
|
const api = services.session;
|
|
140202
140494
|
const device = resolveDevice(params.udid);
|
|
140203
|
-
assertSupported("screen-recording-start",
|
|
140495
|
+
assertSupported("screen-recording-start", capability27, device);
|
|
140204
140496
|
if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
|
|
140205
140497
|
throw new FailureError(
|
|
140206
140498
|
`Screen recording is not supported on tvOS simulators (device ${params.udid}).`,
|
|
@@ -140275,7 +140567,7 @@ var zodSchema52 = external_exports.object({
|
|
|
140275
140567
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial).")
|
|
140276
140568
|
});
|
|
140277
140569
|
var RECORDINGS_DIR = ".argent/recordings";
|
|
140278
|
-
var
|
|
140570
|
+
var capability28 = {
|
|
140279
140571
|
apple: { simulator: true },
|
|
140280
140572
|
android: { emulator: true, device: true, unknown: true }
|
|
140281
140573
|
};
|
|
@@ -140286,7 +140578,7 @@ var screenRecordingStopTool = {
|
|
|
140286
140578
|
completedMsg: ({ result }) => `Saved screen recording ${result.video.filename}`,
|
|
140287
140579
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop screen recording: ${failureSignal2.error_code}`
|
|
140288
140580
|
},
|
|
140289
|
-
capability:
|
|
140581
|
+
capability: capability28,
|
|
140290
140582
|
description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
|
|
140291
140583
|
Also retrieves the video when the recording already ended on its own (time limit reached, capture process died) \u2014 call it even after the cap fired.
|
|
140292
140584
|
Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
|
|
@@ -140300,7 +140592,7 @@ Fails if no recording (running or finished-but-unretrieved) exists for the given
|
|
|
140300
140592
|
async execute(services, params, ctx) {
|
|
140301
140593
|
const api = services.session;
|
|
140302
140594
|
const device = resolveDevice(params.udid);
|
|
140303
|
-
assertSupported("screen-recording-stop",
|
|
140595
|
+
assertSupported("screen-recording-stop", capability28, device);
|
|
140304
140596
|
const stopped = await stopCapture(api);
|
|
140305
140597
|
const artifacts = requireArtifacts(ctx);
|
|
140306
140598
|
const video = await artifacts.register(stopped.outputFile, {
|
|
@@ -142347,7 +142639,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
|
|
|
142347
142639
|
|
|
142348
142640
|
// ../tool-server/src/tools/simulator/stop-metro.ts
|
|
142349
142641
|
init_zod();
|
|
142350
|
-
var
|
|
142642
|
+
var import_node_child_process27 = require("node:child_process");
|
|
142351
142643
|
function parseNetstatListeningPids(netstatOutput, port) {
|
|
142352
142644
|
const pids = /* @__PURE__ */ new Set();
|
|
142353
142645
|
for (const line of netstatOutput.split(/\r?\n/)) {
|
|
@@ -142363,7 +142655,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
|
|
|
142363
142655
|
}
|
|
142364
142656
|
function listeningPids(port) {
|
|
142365
142657
|
if (process.platform === "win32") {
|
|
142366
|
-
const output2 = (0,
|
|
142658
|
+
const output2 = (0, import_node_child_process27.execFileSync)("netstat", ["-ano"], {
|
|
142367
142659
|
encoding: "utf-8",
|
|
142368
142660
|
timeout: 5e3,
|
|
142369
142661
|
// `netstat -ano` dumps every socket on the host; a busy box easily
|
|
@@ -142373,7 +142665,7 @@ function listeningPids(port) {
|
|
|
142373
142665
|
});
|
|
142374
142666
|
return parseNetstatListeningPids(output2, port);
|
|
142375
142667
|
}
|
|
142376
|
-
const output = (0,
|
|
142668
|
+
const output = (0, import_node_child_process27.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
|
|
142377
142669
|
encoding: "utf-8",
|
|
142378
142670
|
timeout: 5e3
|
|
142379
142671
|
}).trim();
|
|
@@ -142717,6 +143009,12 @@ function selectorTree(sel) {
|
|
|
142717
143009
|
walk(sel);
|
|
142718
143010
|
return out;
|
|
142719
143011
|
}
|
|
143012
|
+
function blockSteps(step) {
|
|
143013
|
+
return isBlockStep(step) ? step.steps : void 0;
|
|
143014
|
+
}
|
|
143015
|
+
function isBlockStep(step) {
|
|
143016
|
+
return isBlockDirectiveKey(step.kind);
|
|
143017
|
+
}
|
|
142720
143018
|
function isE2eFlow(flow) {
|
|
142721
143019
|
const first = flow.steps.find((s) => s.kind !== "echo");
|
|
142722
143020
|
return first?.kind === "launch";
|
|
@@ -143381,6 +143679,10 @@ var STEP_DIRECTIVE_KEYS = [
|
|
|
143381
143679
|
"rotate",
|
|
143382
143680
|
"snapshot"
|
|
143383
143681
|
];
|
|
143682
|
+
var BLOCK_DIRECTIVE_KEYS = ["when"];
|
|
143683
|
+
function isBlockDirectiveKey(key2) {
|
|
143684
|
+
return BLOCK_DIRECTIVE_KEYS.includes(key2);
|
|
143685
|
+
}
|
|
143384
143686
|
function parseTapTimes(raw, entry) {
|
|
143385
143687
|
if (raw === void 0) return void 0;
|
|
143386
143688
|
if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 1 || raw > 10) {
|
|
@@ -143573,14 +143875,26 @@ function parseWhenCondition(raw) {
|
|
|
143573
143875
|
}
|
|
143574
143876
|
return { kind: "ui", ...cond };
|
|
143575
143877
|
}
|
|
143576
|
-
var
|
|
143577
|
-
function
|
|
143578
|
-
if (depth >=
|
|
143878
|
+
var MAX_BLOCK_DEPTH = 20;
|
|
143879
|
+
function assertBlockDepth(raw, depth) {
|
|
143880
|
+
if (depth >= MAX_BLOCK_DEPTH) {
|
|
143881
|
+
const directives = BLOCK_DIRECTIVE_KEYS.map((key2) => `\`${key2}:\``).join("/");
|
|
143579
143882
|
badEntry(
|
|
143580
143883
|
raw,
|
|
143581
|
-
|
|
143884
|
+
`${directives} blocks nest deeper than ${MAX_BLOCK_DEPTH} levels \u2014 check for a cyclic YAML alias (\`steps: &s \u2026 steps: *s\`)`
|
|
143582
143885
|
);
|
|
143583
143886
|
}
|
|
143887
|
+
}
|
|
143888
|
+
function parseBlockSteps(raw, depth, emptyDetail) {
|
|
143889
|
+
assertBlockDepth(raw, depth);
|
|
143890
|
+
if (!Array.isArray(raw.steps) || raw.steps.length === 0) badEntry(raw, emptyDetail);
|
|
143891
|
+
return raw.steps.map((s) => {
|
|
143892
|
+
if (s !== null && typeof s === "object") return fromYamlStep(s, depth + 1);
|
|
143893
|
+
return badEntry(s, "step must be an object");
|
|
143894
|
+
});
|
|
143895
|
+
}
|
|
143896
|
+
function parseWhenStep(raw, depth) {
|
|
143897
|
+
assertBlockDepth(raw, depth);
|
|
143584
143898
|
if ("else" in raw) {
|
|
143585
143899
|
badEntry(
|
|
143586
143900
|
raw,
|
|
@@ -143591,13 +143905,7 @@ function parseWhenStep(raw, depth) {
|
|
|
143591
143905
|
badEntry(raw, "a when step takes exactly { when: <condition>, steps: [...] }");
|
|
143592
143906
|
}
|
|
143593
143907
|
const condition = parseWhenCondition(raw.when);
|
|
143594
|
-
|
|
143595
|
-
badEntry(raw, "when needs a non-empty steps list to guard");
|
|
143596
|
-
}
|
|
143597
|
-
const steps = raw.steps.map((s) => {
|
|
143598
|
-
if (s !== null && typeof s === "object") return fromYamlStep(s, depth + 1);
|
|
143599
|
-
return badEntry(s, "step must be an object");
|
|
143600
|
-
});
|
|
143908
|
+
const steps = parseBlockSteps(raw, depth, "when needs a non-empty steps list to guard");
|
|
143601
143909
|
return { kind: "when", condition, steps };
|
|
143602
143910
|
}
|
|
143603
143911
|
function runTargetName(target) {
|
|
@@ -143636,7 +143944,7 @@ function completeRunExtension(value) {
|
|
|
143636
143944
|
const candidate = `${value}.yaml`;
|
|
143637
143945
|
return FLOW_FILE_NAME_PATTERN.test(path31.posix.basename(candidate)) ? candidate : value;
|
|
143638
143946
|
}
|
|
143639
|
-
function fromYamlStep(raw,
|
|
143947
|
+
function fromYamlStep(raw, blockDepth = 0) {
|
|
143640
143948
|
const entry = raw;
|
|
143641
143949
|
if ("optional" in raw) {
|
|
143642
143950
|
badEntry(
|
|
@@ -143659,7 +143967,7 @@ function fromYamlStep(raw, whenDepth = 0) {
|
|
|
143659
143967
|
);
|
|
143660
143968
|
}
|
|
143661
143969
|
const kind = kinds[0];
|
|
143662
|
-
if (kind
|
|
143970
|
+
if (!isBlockDirectiveKey(kind)) {
|
|
143663
143971
|
const siblings = kind === "tool" ? ["tool", "args", "delayMs"] : [kind];
|
|
143664
143972
|
const extras = Object.keys(entry).filter((k) => !siblings.includes(k));
|
|
143665
143973
|
if (extras.length > 0) {
|
|
@@ -143672,7 +143980,7 @@ function fromYamlStep(raw, whenDepth = 0) {
|
|
|
143672
143980
|
if ("echo" in raw) return { kind: "echo", message: String(raw.echo) };
|
|
143673
143981
|
if ("launch" in raw) return { kind: "launch", app: parseLaunch(raw.launch) };
|
|
143674
143982
|
if ("run" in raw) return { kind: "run", flow: parseRunTarget(raw, raw.run) };
|
|
143675
|
-
if ("when" in raw) return parseWhenStep(entry,
|
|
143983
|
+
if ("when" in raw) return parseWhenStep(entry, blockDepth);
|
|
143676
143984
|
if ("tap" in raw) return parseTap(raw.tap, raw);
|
|
143677
143985
|
if ("long-press" in raw) {
|
|
143678
143986
|
return parseLongPress(raw["long-press"], raw);
|
|
@@ -144388,11 +144696,13 @@ function stepRequiresDevice(registry2, step) {
|
|
|
144388
144696
|
}
|
|
144389
144697
|
}
|
|
144390
144698
|
function flowRequiresDevice(registry2, steps) {
|
|
144391
|
-
return steps.some(
|
|
144699
|
+
return steps.some(
|
|
144700
|
+
(step) => stepRequiresDevice(registry2, step) || flowRequiresDevice(registry2, blockSteps(step) ?? [])
|
|
144701
|
+
);
|
|
144392
144702
|
}
|
|
144393
144703
|
function flowScopesDevice(registry2, steps) {
|
|
144394
144704
|
return steps.some(
|
|
144395
|
-
(step) => step.kind === "tool" && declaresAny(registry2, step.name, DEVICE_BIND_LIST_KEYS)
|
|
144705
|
+
(step) => step.kind === "tool" && declaresAny(registry2, step.name, DEVICE_BIND_LIST_KEYS) || flowScopesDevice(registry2, blockSteps(step) ?? [])
|
|
144396
144706
|
);
|
|
144397
144707
|
}
|
|
144398
144708
|
function toolRequiresDevice(registry2, toolName) {
|
|
@@ -146064,7 +146374,7 @@ var import_pngjs3 = __toESM(require_png());
|
|
|
146064
146374
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
146065
146375
|
var import_child_process8 = require("child_process");
|
|
146066
146376
|
var import_util8 = require("util");
|
|
146067
|
-
var
|
|
146377
|
+
var execFileAsync22 = (0, import_util8.promisify)(import_child_process8.execFile);
|
|
146068
146378
|
var OCR_TIMEOUT_MS = 1e4;
|
|
146069
146379
|
var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
146070
146380
|
var TESSERACT_BINARY = "tesseract";
|
|
@@ -146109,7 +146419,7 @@ async function extractOcrTextBlocks(imagePath) {
|
|
|
146109
146419
|
}
|
|
146110
146420
|
}
|
|
146111
146421
|
async function recognizeTsv(imagePath) {
|
|
146112
|
-
const { stdout } = await
|
|
146422
|
+
const { stdout } = await execFileAsync22(
|
|
146113
146423
|
TESSERACT_BINARY,
|
|
146114
146424
|
[
|
|
146115
146425
|
imagePath,
|
|
@@ -148306,15 +148616,15 @@ async function runSnapshot(env, opts) {
|
|
|
148306
148616
|
}
|
|
148307
148617
|
|
|
148308
148618
|
// ../tool-server/src/utils/status-bar.ts
|
|
148309
|
-
var
|
|
148310
|
-
var
|
|
148619
|
+
var import_node_child_process28 = require("node:child_process");
|
|
148620
|
+
var import_node_util21 = require("node:util");
|
|
148311
148621
|
init_adb();
|
|
148312
|
-
var
|
|
148622
|
+
var execFileAsync23 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
|
|
148313
148623
|
var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
|
|
148314
148624
|
async function pinStatusBar(device) {
|
|
148315
148625
|
try {
|
|
148316
148626
|
if (device.platform === "ios") {
|
|
148317
|
-
await
|
|
148627
|
+
await execFileAsync23(
|
|
148318
148628
|
"xcrun",
|
|
148319
148629
|
await simctlArgsForUdid(device.id, [
|
|
148320
148630
|
"status_bar",
|
|
@@ -148357,7 +148667,7 @@ async function pinStatusBar(device) {
|
|
|
148357
148667
|
async function restoreStatusBar(device) {
|
|
148358
148668
|
try {
|
|
148359
148669
|
if (device.platform === "ios") {
|
|
148360
|
-
await
|
|
148670
|
+
await execFileAsync23(
|
|
148361
148671
|
"xcrun",
|
|
148362
148672
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
|
|
148363
148673
|
);
|
|
@@ -148662,7 +148972,8 @@ function displayFlowName(params) {
|
|
|
148662
148972
|
function* walkSteps(steps) {
|
|
148663
148973
|
for (const step of steps) {
|
|
148664
148974
|
yield step;
|
|
148665
|
-
|
|
148975
|
+
const inner = blockSteps(step);
|
|
148976
|
+
if (inner) yield* walkSteps(inner);
|
|
148666
148977
|
}
|
|
148667
148978
|
}
|
|
148668
148979
|
function assertUploadSelfContained(flow) {
|
|
@@ -149063,8 +149374,18 @@ function stepTarget(step) {
|
|
|
149063
149374
|
return step.cropOn ? `"${step.name}" cropOn ${selectorLabel2(step.cropOn)}` : `"${step.name}"`;
|
|
149064
149375
|
case "run":
|
|
149065
149376
|
return step.flow;
|
|
149066
|
-
|
|
149377
|
+
case "echo":
|
|
149378
|
+
case "tool":
|
|
149379
|
+
return void 0;
|
|
149380
|
+
case "launch":
|
|
149067
149381
|
return void 0;
|
|
149382
|
+
case "wait":
|
|
149383
|
+
return void 0;
|
|
149384
|
+
default: {
|
|
149385
|
+
const unclassified = step;
|
|
149386
|
+
void unclassified;
|
|
149387
|
+
return void 0;
|
|
149388
|
+
}
|
|
149068
149389
|
}
|
|
149069
149390
|
}
|
|
149070
149391
|
function scopeFlow(scope) {
|
|
@@ -149106,7 +149427,8 @@ async function execSteps(state3, steps, scope) {
|
|
|
149106
149427
|
// line rather than vanishing — matching reportBlockSkipped.
|
|
149107
149428
|
...step.kind === "echo" ? { message: step.message } : {}
|
|
149108
149429
|
});
|
|
149109
|
-
|
|
149430
|
+
const inner = blockSteps(step);
|
|
149431
|
+
if (inner) reportBlockSkipped(state3, inner, childScope(scope));
|
|
149110
149432
|
continue;
|
|
149111
149433
|
}
|
|
149112
149434
|
if (!state3.device && stepRequiresDevice(state3.registry, step)) {
|
|
@@ -149120,7 +149442,8 @@ async function execSteps(state3, steps, scope) {
|
|
|
149120
149442
|
...depthOf(scope),
|
|
149121
149443
|
reason: `step needs a device but the flow was resolved as device-free \u2014 pass an explicit device`
|
|
149122
149444
|
});
|
|
149123
|
-
|
|
149445
|
+
const inner = blockSteps(step);
|
|
149446
|
+
if (inner) reportBlockSkipped(state3, inner, childScope(scope));
|
|
149124
149447
|
continue;
|
|
149125
149448
|
}
|
|
149126
149449
|
if (state3.signal?.aborted) {
|
|
@@ -149135,17 +149458,16 @@ async function execSteps(state3, steps, scope) {
|
|
|
149135
149458
|
...depthOf(scope),
|
|
149136
149459
|
...step.kind === "echo" ? { message: step.message } : {}
|
|
149137
149460
|
});
|
|
149138
|
-
|
|
149139
|
-
|
|
149140
|
-
}
|
|
149461
|
+
const inner = blockSteps(step);
|
|
149462
|
+
if (inner) reportBlockSkipped(state3, inner, childScope(scope), "run aborted");
|
|
149141
149463
|
continue;
|
|
149142
149464
|
}
|
|
149143
149465
|
if (step.kind === "run") {
|
|
149144
149466
|
await execRunStep(state3, step, scope);
|
|
149145
149467
|
continue;
|
|
149146
149468
|
}
|
|
149147
|
-
if (step
|
|
149148
|
-
await
|
|
149469
|
+
if (isBlockStep(step)) {
|
|
149470
|
+
await execBlockStep(state3, step, scope);
|
|
149149
149471
|
continue;
|
|
149150
149472
|
}
|
|
149151
149473
|
const report = await execLeafStep(state3, step, index, scope);
|
|
@@ -149169,7 +149491,18 @@ function reportBlockSkipped(state3, steps, scope, reason) {
|
|
|
149169
149491
|
...depthOf(scope),
|
|
149170
149492
|
...step.kind === "echo" ? { message: step.message } : {}
|
|
149171
149493
|
});
|
|
149172
|
-
|
|
149494
|
+
const inner = blockSteps(step);
|
|
149495
|
+
if (inner) reportBlockSkipped(state3, inner, childScope(scope), reason);
|
|
149496
|
+
}
|
|
149497
|
+
}
|
|
149498
|
+
async function execBlockStep(state3, step, scope) {
|
|
149499
|
+
switch (step.kind) {
|
|
149500
|
+
case "when":
|
|
149501
|
+
return execWhenStep(state3, step, scope);
|
|
149502
|
+
default: {
|
|
149503
|
+
const unhandled = step.kind;
|
|
149504
|
+
void unhandled;
|
|
149505
|
+
}
|
|
149173
149506
|
}
|
|
149174
149507
|
}
|
|
149175
149508
|
async function execWhenStep(state3, step, scope) {
|
|
@@ -149619,7 +149952,7 @@ init_zod();
|
|
|
149619
149952
|
// ../tool-server/src/utils/workspace-reader.ts
|
|
149620
149953
|
var import_promises12 = require("node:fs/promises");
|
|
149621
149954
|
var import_node_path21 = require("node:path");
|
|
149622
|
-
var
|
|
149955
|
+
var import_node_child_process29 = require("node:child_process");
|
|
149623
149956
|
var import_dotenv2 = __toESM(require_main());
|
|
149624
149957
|
async function exists(path40) {
|
|
149625
149958
|
try {
|
|
@@ -149663,7 +149996,7 @@ async function listDir(path40) {
|
|
|
149663
149996
|
var COMMAND_TIMEOUT_MS = 3e3;
|
|
149664
149997
|
function runVersionCommand(cmd, args, cwd) {
|
|
149665
149998
|
return new Promise((resolve11) => {
|
|
149666
|
-
const child = (0,
|
|
149999
|
+
const child = (0, import_node_child_process29.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
|
|
149667
150000
|
if (err) {
|
|
149668
150001
|
resolve11(null);
|
|
149669
150002
|
return;
|
|
@@ -149952,7 +150285,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
149952
150285
|
};
|
|
149953
150286
|
|
|
149954
150287
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
149955
|
-
var
|
|
150288
|
+
var import_node_child_process30 = require("node:child_process");
|
|
149956
150289
|
var fs51 = __toESM(require("node:fs"));
|
|
149957
150290
|
var path36 = __toESM(require("node:path"));
|
|
149958
150291
|
init_zod();
|
|
@@ -150087,7 +150420,7 @@ var updateArgentTool = {
|
|
|
150087
150420
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
150088
150421
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
150089
150422
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
150090
|
-
const child = (0,
|
|
150423
|
+
const child = (0, import_node_child_process30.spawn)(cmd, args, {
|
|
150091
150424
|
detached: true,
|
|
150092
150425
|
stdio: "ignore",
|
|
150093
150426
|
env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
|
|
@@ -150160,7 +150493,7 @@ var zodSchema70 = external_exports.object({
|
|
|
150160
150493
|
"Directory where diff artifacts should be written. Optional \u2014 defaults to a temp directory; the diff images are returned in the result either way."
|
|
150161
150494
|
)
|
|
150162
150495
|
}).strict();
|
|
150163
|
-
var
|
|
150496
|
+
var capability29 = {
|
|
150164
150497
|
apple: { simulator: true, device: true },
|
|
150165
150498
|
android: { emulator: true, device: true, unknown: true }
|
|
150166
150499
|
};
|
|
@@ -150185,7 +150518,7 @@ Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
|
|
|
150185
150518
|
Fails if the input sources are invalid, PNG files cannot be read, outputDir cannot be written, or the simulator-server / emulator backend is not reachable.`,
|
|
150186
150519
|
searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
|
|
150187
150520
|
zodSchema: zodSchema70,
|
|
150188
|
-
capability:
|
|
150521
|
+
capability: capability29,
|
|
150189
150522
|
fileInputs: fileInputs6,
|
|
150190
150523
|
services: (params) => {
|
|
150191
150524
|
if (params.captureBaseline || params.captureCurrent) {
|
|
@@ -150576,7 +150909,7 @@ var tabAction = {
|
|
|
150576
150909
|
failure: "close"
|
|
150577
150910
|
}
|
|
150578
150911
|
};
|
|
150579
|
-
var
|
|
150912
|
+
var capability30 = {
|
|
150580
150913
|
chromium: { app: true }
|
|
150581
150914
|
};
|
|
150582
150915
|
var chromiumTabsTool = {
|
|
@@ -150595,7 +150928,7 @@ Use when an app exposes multiple windows or tabs and you need to inspect or driv
|
|
|
150595
150928
|
Returns { tabs: [{ tabId, targetId, title, url, active, label? }] }. Fails if the device is not a Chromium (CDP) device, or the requested tabId/label no longer matches a live tab. Chromium-only.`,
|
|
150596
150929
|
searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
|
|
150597
150930
|
zodSchema: zodSchema73,
|
|
150598
|
-
capability:
|
|
150931
|
+
capability: capability30,
|
|
150599
150932
|
services: (params) => {
|
|
150600
150933
|
const device = resolveDevice(params.udid);
|
|
150601
150934
|
if (device.platform === "chromium") {
|
|
@@ -150718,7 +151051,7 @@ var cookieAction = {
|
|
|
150718
151051
|
delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
|
|
150719
151052
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
150720
151053
|
};
|
|
150721
|
-
var
|
|
151054
|
+
var capability31 = {
|
|
150722
151055
|
chromium: { app: true }
|
|
150723
151056
|
};
|
|
150724
151057
|
var chromiumCookiesTool = {
|
|
@@ -150737,7 +151070,7 @@ Use when seeding an authenticated session before a flow (set the session cookie,
|
|
|
150737
151070
|
Returns { cookies, count } for get, or a small status object ({ set } / { deleted } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing name/value. Chromium-only.`,
|
|
150738
151071
|
searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
|
|
150739
151072
|
zodSchema: zodSchema74,
|
|
150740
|
-
capability:
|
|
151073
|
+
capability: capability31,
|
|
150741
151074
|
services: (params) => {
|
|
150742
151075
|
const device = resolveDevice(params.udid);
|
|
150743
151076
|
if (device.platform === "chromium") {
|
|
@@ -150816,7 +151149,7 @@ var storageAction = {
|
|
|
150816
151149
|
remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
|
|
150817
151150
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
150818
151151
|
};
|
|
150819
|
-
var
|
|
151152
|
+
var capability32 = {
|
|
150820
151153
|
chromium: { app: true }
|
|
150821
151154
|
};
|
|
150822
151155
|
var chromiumStorageTool = {
|
|
@@ -150836,7 +151169,7 @@ Use when seeding feature flags / auth tokens before a flow or asserting persiste
|
|
|
150836
151169
|
Returns { value } for a single key, { entries, count } for all, or a status object ({ set } / { removed } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing key/value. Chromium-only.`,
|
|
150837
151170
|
searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
|
|
150838
151171
|
zodSchema: zodSchema75,
|
|
150839
|
-
capability:
|
|
151172
|
+
capability: capability32,
|
|
150840
151173
|
services: (params) => {
|
|
150841
151174
|
const device = resolveDevice(params.udid);
|
|
150842
151175
|
if (device.platform === "chromium") {
|
|
@@ -150925,6 +151258,7 @@ function createRegistry() {
|
|
|
150925
151258
|
registry2.registerTool(buttonTool);
|
|
150926
151259
|
registry2.registerTool(createKeyboardTool(registry2));
|
|
150927
151260
|
registry2.registerTool(rotateTool);
|
|
151261
|
+
registry2.registerTool(shakeTool);
|
|
150928
151262
|
registry2.registerTool(createTvRemoteTool(registry2));
|
|
150929
151263
|
registry2.registerTool(createRunSequenceTool(registry2));
|
|
150930
151264
|
registry2.registerTool(debuggerConnectTool);
|
|
@@ -151004,12 +151338,12 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
151004
151338
|
|
|
151005
151339
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
151006
151340
|
var fs53 = __toESM(require("node:fs"));
|
|
151007
|
-
var
|
|
151008
|
-
var
|
|
151009
|
-
var
|
|
151341
|
+
var import_node_child_process31 = require("node:child_process");
|
|
151342
|
+
var import_node_util22 = require("node:util");
|
|
151343
|
+
var execFileAsync24 = (0, import_node_util22.promisify)(import_node_child_process31.execFile);
|
|
151010
151344
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
151011
151345
|
async function getBootedUdidsInSet(deviceSet) {
|
|
151012
|
-
const { stdout } = await
|
|
151346
|
+
const { stdout } = await execFileAsync24("xcrun", [
|
|
151013
151347
|
...simctlPrefix(deviceSet),
|
|
151014
151348
|
"list",
|
|
151015
151349
|
"devices",
|
|
@@ -151082,7 +151416,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
151082
151416
|
}
|
|
151083
151417
|
|
|
151084
151418
|
// ../tool-server/src/utils/preview-window.ts
|
|
151085
|
-
var
|
|
151419
|
+
var import_node_child_process32 = require("node:child_process");
|
|
151086
151420
|
var fs54 = __toESM(require("node:fs"));
|
|
151087
151421
|
var os14 = __toESM(require("node:os"));
|
|
151088
151422
|
var path38 = __toESM(require("node:path"));
|
|
@@ -151114,10 +151448,10 @@ function ensureLensAppBundle(electronBin) {
|
|
|
151114
151448
|
fs54.copyFileSync(path38.join(realContents, "Info.plist"), plist);
|
|
151115
151449
|
const setPlist = (entry, value) => {
|
|
151116
151450
|
try {
|
|
151117
|
-
(0,
|
|
151451
|
+
(0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
151118
151452
|
} catch {
|
|
151119
151453
|
try {
|
|
151120
|
-
(0,
|
|
151454
|
+
(0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
|
|
151121
151455
|
} catch {
|
|
151122
151456
|
}
|
|
151123
151457
|
}
|
|
@@ -151176,7 +151510,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
151176
151510
|
const wrapperBin = ensureLensAppBundle(electronBin);
|
|
151177
151511
|
const launchBin = wrapperBin ?? electronBin;
|
|
151178
151512
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
151179
|
-
const next = (0,
|
|
151513
|
+
const next = (0, import_node_child_process32.spawn)(launchBin, launchArgs, {
|
|
151180
151514
|
// Strip ELECTRON_RUN_AS_NODE so the child boots as a GUI Electron app, not
|
|
151181
151515
|
// a bare Node runtime (see electronGuiChildEnv). An Electron-based MCP
|
|
151182
151516
|
// host puts it in our env, and inheriting it makes main.cjs crash at
|
package/package.json
CHANGED
|
@@ -74,6 +74,7 @@ Common schemes: `messages://`, `settings://`, `maps://?q=<query>`, `tel://<numbe
|
|
|
74
74
|
| Hardware key | `button` | Home, back, power, volume, appSwitch, actionButton |
|
|
75
75
|
| Type text | `keyboard` | Every platform. Supports Enter, Escape, arrows (not on TV) |
|
|
76
76
|
| Rotate device | `rotate` | Orientation changes |
|
|
77
|
+
| Shake device | `shake` | Shake handlers (sim/emu only), Undo-typing prompt, RN dev menu |
|
|
77
78
|
| Wait for UI | `await-ui-element` | Block until an element is visible/hidden/exists/contains text |
|
|
78
79
|
| Wait for idle | `await-screen-idle` | Block until a non-empty screen tree stops changing |
|
|
79
80
|
|