@swmansion/argent 0.20.1-next.6 → 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 +369 -76
- 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();
|
|
@@ -146082,7 +146374,7 @@ var import_pngjs3 = __toESM(require_png());
|
|
|
146082
146374
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
146083
146375
|
var import_child_process8 = require("child_process");
|
|
146084
146376
|
var import_util8 = require("util");
|
|
146085
|
-
var
|
|
146377
|
+
var execFileAsync22 = (0, import_util8.promisify)(import_child_process8.execFile);
|
|
146086
146378
|
var OCR_TIMEOUT_MS = 1e4;
|
|
146087
146379
|
var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
146088
146380
|
var TESSERACT_BINARY = "tesseract";
|
|
@@ -146127,7 +146419,7 @@ async function extractOcrTextBlocks(imagePath) {
|
|
|
146127
146419
|
}
|
|
146128
146420
|
}
|
|
146129
146421
|
async function recognizeTsv(imagePath) {
|
|
146130
|
-
const { stdout } = await
|
|
146422
|
+
const { stdout } = await execFileAsync22(
|
|
146131
146423
|
TESSERACT_BINARY,
|
|
146132
146424
|
[
|
|
146133
146425
|
imagePath,
|
|
@@ -148324,15 +148616,15 @@ async function runSnapshot(env, opts) {
|
|
|
148324
148616
|
}
|
|
148325
148617
|
|
|
148326
148618
|
// ../tool-server/src/utils/status-bar.ts
|
|
148327
|
-
var
|
|
148328
|
-
var
|
|
148619
|
+
var import_node_child_process28 = require("node:child_process");
|
|
148620
|
+
var import_node_util21 = require("node:util");
|
|
148329
148621
|
init_adb();
|
|
148330
|
-
var
|
|
148622
|
+
var execFileAsync23 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
|
|
148331
148623
|
var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
|
|
148332
148624
|
async function pinStatusBar(device) {
|
|
148333
148625
|
try {
|
|
148334
148626
|
if (device.platform === "ios") {
|
|
148335
|
-
await
|
|
148627
|
+
await execFileAsync23(
|
|
148336
148628
|
"xcrun",
|
|
148337
148629
|
await simctlArgsForUdid(device.id, [
|
|
148338
148630
|
"status_bar",
|
|
@@ -148375,7 +148667,7 @@ async function pinStatusBar(device) {
|
|
|
148375
148667
|
async function restoreStatusBar(device) {
|
|
148376
148668
|
try {
|
|
148377
148669
|
if (device.platform === "ios") {
|
|
148378
|
-
await
|
|
148670
|
+
await execFileAsync23(
|
|
148379
148671
|
"xcrun",
|
|
148380
148672
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
|
|
148381
148673
|
);
|
|
@@ -149660,7 +149952,7 @@ init_zod();
|
|
|
149660
149952
|
// ../tool-server/src/utils/workspace-reader.ts
|
|
149661
149953
|
var import_promises12 = require("node:fs/promises");
|
|
149662
149954
|
var import_node_path21 = require("node:path");
|
|
149663
|
-
var
|
|
149955
|
+
var import_node_child_process29 = require("node:child_process");
|
|
149664
149956
|
var import_dotenv2 = __toESM(require_main());
|
|
149665
149957
|
async function exists(path40) {
|
|
149666
149958
|
try {
|
|
@@ -149704,7 +149996,7 @@ async function listDir(path40) {
|
|
|
149704
149996
|
var COMMAND_TIMEOUT_MS = 3e3;
|
|
149705
149997
|
function runVersionCommand(cmd, args, cwd) {
|
|
149706
149998
|
return new Promise((resolve11) => {
|
|
149707
|
-
const child = (0,
|
|
149999
|
+
const child = (0, import_node_child_process29.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
|
|
149708
150000
|
if (err) {
|
|
149709
150001
|
resolve11(null);
|
|
149710
150002
|
return;
|
|
@@ -149993,7 +150285,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
149993
150285
|
};
|
|
149994
150286
|
|
|
149995
150287
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
149996
|
-
var
|
|
150288
|
+
var import_node_child_process30 = require("node:child_process");
|
|
149997
150289
|
var fs51 = __toESM(require("node:fs"));
|
|
149998
150290
|
var path36 = __toESM(require("node:path"));
|
|
149999
150291
|
init_zod();
|
|
@@ -150128,7 +150420,7 @@ var updateArgentTool = {
|
|
|
150128
150420
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
150129
150421
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
150130
150422
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
150131
|
-
const child = (0,
|
|
150423
|
+
const child = (0, import_node_child_process30.spawn)(cmd, args, {
|
|
150132
150424
|
detached: true,
|
|
150133
150425
|
stdio: "ignore",
|
|
150134
150426
|
env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
|
|
@@ -150201,7 +150493,7 @@ var zodSchema70 = external_exports.object({
|
|
|
150201
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."
|
|
150202
150494
|
)
|
|
150203
150495
|
}).strict();
|
|
150204
|
-
var
|
|
150496
|
+
var capability29 = {
|
|
150205
150497
|
apple: { simulator: true, device: true },
|
|
150206
150498
|
android: { emulator: true, device: true, unknown: true }
|
|
150207
150499
|
};
|
|
@@ -150226,7 +150518,7 @@ Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
|
|
|
150226
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.`,
|
|
150227
150519
|
searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
|
|
150228
150520
|
zodSchema: zodSchema70,
|
|
150229
|
-
capability:
|
|
150521
|
+
capability: capability29,
|
|
150230
150522
|
fileInputs: fileInputs6,
|
|
150231
150523
|
services: (params) => {
|
|
150232
150524
|
if (params.captureBaseline || params.captureCurrent) {
|
|
@@ -150617,7 +150909,7 @@ var tabAction = {
|
|
|
150617
150909
|
failure: "close"
|
|
150618
150910
|
}
|
|
150619
150911
|
};
|
|
150620
|
-
var
|
|
150912
|
+
var capability30 = {
|
|
150621
150913
|
chromium: { app: true }
|
|
150622
150914
|
};
|
|
150623
150915
|
var chromiumTabsTool = {
|
|
@@ -150636,7 +150928,7 @@ Use when an app exposes multiple windows or tabs and you need to inspect or driv
|
|
|
150636
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.`,
|
|
150637
150929
|
searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
|
|
150638
150930
|
zodSchema: zodSchema73,
|
|
150639
|
-
capability:
|
|
150931
|
+
capability: capability30,
|
|
150640
150932
|
services: (params) => {
|
|
150641
150933
|
const device = resolveDevice(params.udid);
|
|
150642
150934
|
if (device.platform === "chromium") {
|
|
@@ -150759,7 +151051,7 @@ var cookieAction = {
|
|
|
150759
151051
|
delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
|
|
150760
151052
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
150761
151053
|
};
|
|
150762
|
-
var
|
|
151054
|
+
var capability31 = {
|
|
150763
151055
|
chromium: { app: true }
|
|
150764
151056
|
};
|
|
150765
151057
|
var chromiumCookiesTool = {
|
|
@@ -150778,7 +151070,7 @@ Use when seeding an authenticated session before a flow (set the session cookie,
|
|
|
150778
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.`,
|
|
150779
151071
|
searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
|
|
150780
151072
|
zodSchema: zodSchema74,
|
|
150781
|
-
capability:
|
|
151073
|
+
capability: capability31,
|
|
150782
151074
|
services: (params) => {
|
|
150783
151075
|
const device = resolveDevice(params.udid);
|
|
150784
151076
|
if (device.platform === "chromium") {
|
|
@@ -150857,7 +151149,7 @@ var storageAction = {
|
|
|
150857
151149
|
remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
|
|
150858
151150
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
150859
151151
|
};
|
|
150860
|
-
var
|
|
151152
|
+
var capability32 = {
|
|
150861
151153
|
chromium: { app: true }
|
|
150862
151154
|
};
|
|
150863
151155
|
var chromiumStorageTool = {
|
|
@@ -150877,7 +151169,7 @@ Use when seeding feature flags / auth tokens before a flow or asserting persiste
|
|
|
150877
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.`,
|
|
150878
151170
|
searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
|
|
150879
151171
|
zodSchema: zodSchema75,
|
|
150880
|
-
capability:
|
|
151172
|
+
capability: capability32,
|
|
150881
151173
|
services: (params) => {
|
|
150882
151174
|
const device = resolveDevice(params.udid);
|
|
150883
151175
|
if (device.platform === "chromium") {
|
|
@@ -150966,6 +151258,7 @@ function createRegistry() {
|
|
|
150966
151258
|
registry2.registerTool(buttonTool);
|
|
150967
151259
|
registry2.registerTool(createKeyboardTool(registry2));
|
|
150968
151260
|
registry2.registerTool(rotateTool);
|
|
151261
|
+
registry2.registerTool(shakeTool);
|
|
150969
151262
|
registry2.registerTool(createTvRemoteTool(registry2));
|
|
150970
151263
|
registry2.registerTool(createRunSequenceTool(registry2));
|
|
150971
151264
|
registry2.registerTool(debuggerConnectTool);
|
|
@@ -151045,12 +151338,12 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
151045
151338
|
|
|
151046
151339
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
151047
151340
|
var fs53 = __toESM(require("node:fs"));
|
|
151048
|
-
var
|
|
151049
|
-
var
|
|
151050
|
-
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);
|
|
151051
151344
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
151052
151345
|
async function getBootedUdidsInSet(deviceSet) {
|
|
151053
|
-
const { stdout } = await
|
|
151346
|
+
const { stdout } = await execFileAsync24("xcrun", [
|
|
151054
151347
|
...simctlPrefix(deviceSet),
|
|
151055
151348
|
"list",
|
|
151056
151349
|
"devices",
|
|
@@ -151123,7 +151416,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
151123
151416
|
}
|
|
151124
151417
|
|
|
151125
151418
|
// ../tool-server/src/utils/preview-window.ts
|
|
151126
|
-
var
|
|
151419
|
+
var import_node_child_process32 = require("node:child_process");
|
|
151127
151420
|
var fs54 = __toESM(require("node:fs"));
|
|
151128
151421
|
var os14 = __toESM(require("node:os"));
|
|
151129
151422
|
var path38 = __toESM(require("node:path"));
|
|
@@ -151155,10 +151448,10 @@ function ensureLensAppBundle(electronBin) {
|
|
|
151155
151448
|
fs54.copyFileSync(path38.join(realContents, "Info.plist"), plist);
|
|
151156
151449
|
const setPlist = (entry, value) => {
|
|
151157
151450
|
try {
|
|
151158
|
-
(0,
|
|
151451
|
+
(0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
151159
151452
|
} catch {
|
|
151160
151453
|
try {
|
|
151161
|
-
(0,
|
|
151454
|
+
(0, import_node_child_process32.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
|
|
151162
151455
|
} catch {
|
|
151163
151456
|
}
|
|
151164
151457
|
}
|
|
@@ -151217,7 +151510,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
151217
151510
|
const wrapperBin = ensureLensAppBundle(electronBin);
|
|
151218
151511
|
const launchBin = wrapperBin ?? electronBin;
|
|
151219
151512
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
151220
|
-
const next = (0,
|
|
151513
|
+
const next = (0, import_node_child_process32.spawn)(launchBin, launchArgs, {
|
|
151221
151514
|
// Strip ELECTRON_RUN_AS_NODE so the child boots as a GUI Electron app, not
|
|
151222
151515
|
// a bare Node runtime (see electronGuiChildEnv). An Electron-based MCP
|
|
151223
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
|
|