@swmansion/argent 0.28.1-next.1 → 0.28.1-next.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/argent-android-devtools-0.2.0.apk +0 -0
- package/bin/darwin/ax-service +0 -0
- package/bin/darwin/tvos-ax-service +0 -0
- package/bin/darwin/tvos-hid-daemon +0 -0
- package/bin/tcp/ax-service +0 -0
- package/dist/cli-cmds.mjs +1 -1
- package/dist/client.d.ts +9 -0
- package/dist/installer.mjs +1 -1
- package/dist/tool-args.generated.d.ts +10 -0
- package/dist/tool-server.cjs +593 -369
- package/dylibs/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/libKeyboardPatch.dylib +0 -0
- package/dylibs/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tcp/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tcp/libKeyboardPatch.dylib +0 -0
- package/dylibs/tcp/libNativeDevtoolsIos.dylib +0 -0
- package/dylibs/tvos/libArgentInjectionBootstrap.dylib +0 -0
- package/dylibs/tvos/libKeyboardPatch.dylib +0 -0
- package/dylibs/tvos/libNativeDevtoolsIos.dylib +0 -0
- package/package.json +1 -1
- package/skills/argent-metro-debugger/SKILL.md +7 -7
package/dist/tool-server.cjs
CHANGED
|
@@ -13223,8 +13223,8 @@ function finalize(ctx, schema) {
|
|
|
13223
13223
|
const root = ctx.seen.get(schema);
|
|
13224
13224
|
if (!root)
|
|
13225
13225
|
throw new Error("Unprocessed schema. This is a bug in Zod.");
|
|
13226
|
-
const flattenRef = (
|
|
13227
|
-
const seen = ctx.seen.get(
|
|
13226
|
+
const flattenRef = (zodSchema81) => {
|
|
13227
|
+
const seen = ctx.seen.get(zodSchema81);
|
|
13228
13228
|
if (seen.ref === null)
|
|
13229
13229
|
return;
|
|
13230
13230
|
const schema2 = seen.def ?? seen.schema;
|
|
@@ -13242,7 +13242,7 @@ function finalize(ctx, schema) {
|
|
|
13242
13242
|
Object.assign(schema2, refSchema);
|
|
13243
13243
|
}
|
|
13244
13244
|
Object.assign(schema2, _cached);
|
|
13245
|
-
const isParentRef =
|
|
13245
|
+
const isParentRef = zodSchema81._zod.parent === ref;
|
|
13246
13246
|
if (isParentRef) {
|
|
13247
13247
|
for (const key2 in schema2) {
|
|
13248
13248
|
if (key2 === "$ref" || key2 === "allOf")
|
|
@@ -13262,7 +13262,7 @@ function finalize(ctx, schema) {
|
|
|
13262
13262
|
}
|
|
13263
13263
|
}
|
|
13264
13264
|
}
|
|
13265
|
-
const parent =
|
|
13265
|
+
const parent = zodSchema81._zod.parent;
|
|
13266
13266
|
if (parent && parent !== ref) {
|
|
13267
13267
|
flattenRef(parent);
|
|
13268
13268
|
const parentSeen = ctx.seen.get(parent);
|
|
@@ -13280,7 +13280,7 @@ function finalize(ctx, schema) {
|
|
|
13280
13280
|
}
|
|
13281
13281
|
}
|
|
13282
13282
|
ctx.override({
|
|
13283
|
-
zodSchema:
|
|
13283
|
+
zodSchema: zodSchema81,
|
|
13284
13284
|
jsonSchema: schema2,
|
|
13285
13285
|
path: seen.path ?? []
|
|
13286
13286
|
});
|
|
@@ -16081,10 +16081,10 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16081
16081
|
}
|
|
16082
16082
|
ctx.processing.add(refPath);
|
|
16083
16083
|
const resolved = resolveRef(refPath, ctx);
|
|
16084
|
-
const
|
|
16085
|
-
ctx.refs.set(refPath,
|
|
16084
|
+
const zodSchema82 = convertSchema(resolved, ctx);
|
|
16085
|
+
ctx.refs.set(refPath, zodSchema82);
|
|
16086
16086
|
ctx.processing.delete(refPath);
|
|
16087
|
-
return
|
|
16087
|
+
return zodSchema82;
|
|
16088
16088
|
}
|
|
16089
16089
|
if (schema.enum !== void 0) {
|
|
16090
16090
|
const enumValues = schema.enum;
|
|
@@ -16126,7 +16126,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16126
16126
|
if (!type) {
|
|
16127
16127
|
return z.any();
|
|
16128
16128
|
}
|
|
16129
|
-
let
|
|
16129
|
+
let zodSchema81;
|
|
16130
16130
|
switch (type) {
|
|
16131
16131
|
case "string": {
|
|
16132
16132
|
let stringSchema = z.string();
|
|
@@ -16189,7 +16189,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16189
16189
|
if (schema.pattern) {
|
|
16190
16190
|
stringSchema = stringSchema.regex(new RegExp(schema.pattern));
|
|
16191
16191
|
}
|
|
16192
|
-
|
|
16192
|
+
zodSchema81 = stringSchema;
|
|
16193
16193
|
break;
|
|
16194
16194
|
}
|
|
16195
16195
|
case "number":
|
|
@@ -16214,15 +16214,15 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16214
16214
|
if (typeof schema.multipleOf === "number") {
|
|
16215
16215
|
numberSchema = numberSchema.multipleOf(schema.multipleOf);
|
|
16216
16216
|
}
|
|
16217
|
-
|
|
16217
|
+
zodSchema81 = numberSchema;
|
|
16218
16218
|
break;
|
|
16219
16219
|
}
|
|
16220
16220
|
case "boolean": {
|
|
16221
|
-
|
|
16221
|
+
zodSchema81 = z.boolean();
|
|
16222
16222
|
break;
|
|
16223
16223
|
}
|
|
16224
16224
|
case "null": {
|
|
16225
|
-
|
|
16225
|
+
zodSchema81 = z.null();
|
|
16226
16226
|
break;
|
|
16227
16227
|
}
|
|
16228
16228
|
case "object": {
|
|
@@ -16237,12 +16237,12 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16237
16237
|
const keySchema = convertSchema(schema.propertyNames, ctx);
|
|
16238
16238
|
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) : z.any();
|
|
16239
16239
|
if (Object.keys(shape).length === 0) {
|
|
16240
|
-
|
|
16240
|
+
zodSchema81 = z.record(keySchema, valueSchema);
|
|
16241
16241
|
break;
|
|
16242
16242
|
}
|
|
16243
16243
|
const objectSchema2 = z.object(shape).passthrough();
|
|
16244
16244
|
const recordSchema = z.looseRecord(keySchema, valueSchema);
|
|
16245
|
-
|
|
16245
|
+
zodSchema81 = z.intersection(objectSchema2, recordSchema);
|
|
16246
16246
|
break;
|
|
16247
16247
|
}
|
|
16248
16248
|
if (schema.patternProperties) {
|
|
@@ -16260,25 +16260,25 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16260
16260
|
}
|
|
16261
16261
|
schemasToIntersect.push(...looseRecords);
|
|
16262
16262
|
if (schemasToIntersect.length === 0) {
|
|
16263
|
-
|
|
16263
|
+
zodSchema81 = z.object({}).passthrough();
|
|
16264
16264
|
} else if (schemasToIntersect.length === 1) {
|
|
16265
|
-
|
|
16265
|
+
zodSchema81 = schemasToIntersect[0];
|
|
16266
16266
|
} else {
|
|
16267
16267
|
let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);
|
|
16268
16268
|
for (let i = 2; i < schemasToIntersect.length; i++) {
|
|
16269
16269
|
result = z.intersection(result, schemasToIntersect[i]);
|
|
16270
16270
|
}
|
|
16271
|
-
|
|
16271
|
+
zodSchema81 = result;
|
|
16272
16272
|
}
|
|
16273
16273
|
break;
|
|
16274
16274
|
}
|
|
16275
16275
|
const objectSchema = z.object(shape);
|
|
16276
16276
|
if (schema.additionalProperties === false) {
|
|
16277
|
-
|
|
16277
|
+
zodSchema81 = objectSchema.strict();
|
|
16278
16278
|
} else if (typeof schema.additionalProperties === "object") {
|
|
16279
|
-
|
|
16279
|
+
zodSchema81 = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));
|
|
16280
16280
|
} else {
|
|
16281
|
-
|
|
16281
|
+
zodSchema81 = objectSchema.passthrough();
|
|
16282
16282
|
}
|
|
16283
16283
|
break;
|
|
16284
16284
|
}
|
|
@@ -16289,29 +16289,29 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16289
16289
|
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
|
16290
16290
|
const rest = items && typeof items === "object" && !Array.isArray(items) ? convertSchema(items, ctx) : void 0;
|
|
16291
16291
|
if (rest) {
|
|
16292
|
-
|
|
16292
|
+
zodSchema81 = z.tuple(tupleItems).rest(rest);
|
|
16293
16293
|
} else {
|
|
16294
|
-
|
|
16294
|
+
zodSchema81 = z.tuple(tupleItems);
|
|
16295
16295
|
}
|
|
16296
16296
|
if (typeof schema.minItems === "number") {
|
|
16297
|
-
|
|
16297
|
+
zodSchema81 = zodSchema81.check(z.minLength(schema.minItems));
|
|
16298
16298
|
}
|
|
16299
16299
|
if (typeof schema.maxItems === "number") {
|
|
16300
|
-
|
|
16300
|
+
zodSchema81 = zodSchema81.check(z.maxLength(schema.maxItems));
|
|
16301
16301
|
}
|
|
16302
16302
|
} else if (Array.isArray(items)) {
|
|
16303
16303
|
const tupleItems = items.map((item) => convertSchema(item, ctx));
|
|
16304
16304
|
const rest = schema.additionalItems && typeof schema.additionalItems === "object" ? convertSchema(schema.additionalItems, ctx) : void 0;
|
|
16305
16305
|
if (rest) {
|
|
16306
|
-
|
|
16306
|
+
zodSchema81 = z.tuple(tupleItems).rest(rest);
|
|
16307
16307
|
} else {
|
|
16308
|
-
|
|
16308
|
+
zodSchema81 = z.tuple(tupleItems);
|
|
16309
16309
|
}
|
|
16310
16310
|
if (typeof schema.minItems === "number") {
|
|
16311
|
-
|
|
16311
|
+
zodSchema81 = zodSchema81.check(z.minLength(schema.minItems));
|
|
16312
16312
|
}
|
|
16313
16313
|
if (typeof schema.maxItems === "number") {
|
|
16314
|
-
|
|
16314
|
+
zodSchema81 = zodSchema81.check(z.maxLength(schema.maxItems));
|
|
16315
16315
|
}
|
|
16316
16316
|
} else if (items !== void 0) {
|
|
16317
16317
|
const element = convertSchema(items, ctx);
|
|
@@ -16322,16 +16322,16 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16322
16322
|
if (typeof schema.maxItems === "number") {
|
|
16323
16323
|
arraySchema = arraySchema.max(schema.maxItems);
|
|
16324
16324
|
}
|
|
16325
|
-
|
|
16325
|
+
zodSchema81 = arraySchema;
|
|
16326
16326
|
} else {
|
|
16327
|
-
|
|
16327
|
+
zodSchema81 = z.array(z.any());
|
|
16328
16328
|
}
|
|
16329
16329
|
break;
|
|
16330
16330
|
}
|
|
16331
16331
|
default:
|
|
16332
16332
|
throw new Error(`Unsupported type: ${type}`);
|
|
16333
16333
|
}
|
|
16334
|
-
return
|
|
16334
|
+
return zodSchema81;
|
|
16335
16335
|
}
|
|
16336
16336
|
function convertSchema(schema, ctx) {
|
|
16337
16337
|
if (typeof schema === "boolean") {
|
|
@@ -73655,16 +73655,16 @@ function lookupExternalDeviceNow(id) {
|
|
|
73655
73655
|
}
|
|
73656
73656
|
return device;
|
|
73657
73657
|
}
|
|
73658
|
-
async function assertExternalCapability(namespace, device,
|
|
73659
|
-
assertExternalCapabilitySync(namespace, device,
|
|
73658
|
+
async function assertExternalCapability(namespace, device, capability38) {
|
|
73659
|
+
assertExternalCapabilitySync(namespace, device, capability38);
|
|
73660
73660
|
}
|
|
73661
|
-
function assertExternalCapabilitySync(namespace, device,
|
|
73661
|
+
function assertExternalCapabilitySync(namespace, device, capability38) {
|
|
73662
73662
|
const id = typeof device === "string" ? device : device.id;
|
|
73663
73663
|
const externalDevice = isExternalId(id) ? lookupExternalDeviceNow(id) : externalClaimForNativeId(id);
|
|
73664
73664
|
if (!externalDevice) return;
|
|
73665
|
-
if (externalDevice.capabilities.has(
|
|
73665
|
+
if (externalDevice.capabilities.has(capability38)) return;
|
|
73666
73666
|
throw new FailureError(
|
|
73667
|
-
`${namespace} is not available on '${externalDevice.name}': ${externalDevice.provider.name} did not grant the '${
|
|
73667
|
+
`${namespace} is not available on '${externalDevice.name}': ${externalDevice.provider.name} did not grant the '${capability38}' capability for this device.`,
|
|
73668
73668
|
{
|
|
73669
73669
|
error_code: FAILURE_CODES.EXTERNAL_DEVICE_CAPABILITY_DENIED,
|
|
73670
73670
|
error_kind: "unsupported",
|
|
@@ -94920,7 +94920,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
94920
94920
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
94921
94921
|
function readCliVersion() {
|
|
94922
94922
|
if (true) {
|
|
94923
|
-
return "0.28.1-next.
|
|
94923
|
+
return "0.28.1-next.11";
|
|
94924
94924
|
}
|
|
94925
94925
|
return "0.0.0";
|
|
94926
94926
|
}
|
|
@@ -96694,8 +96694,8 @@ async function simctlArgsForUdid(udid, args, options) {
|
|
|
96694
96694
|
return [...simctlPrefix(await deviceSetForUdid(udid)), ...nativeArgs(udid, args)];
|
|
96695
96695
|
}
|
|
96696
96696
|
function assertSimctlEntitlement(udid, options) {
|
|
96697
|
-
const
|
|
96698
|
-
assertExternalCapabilitySync(
|
|
96697
|
+
const capability38 = options?.granted ?? "simctl";
|
|
96698
|
+
assertExternalCapabilitySync(capability38, udid, capability38);
|
|
96699
96699
|
}
|
|
96700
96700
|
async function simctlTargetForUdid(udid, options) {
|
|
96701
96701
|
assertSimctlEntitlement(udid, options);
|
|
@@ -97760,6 +97760,9 @@ var axServiceBlueprint = {
|
|
|
97760
97760
|
treeVersion: result.treeVersion
|
|
97761
97761
|
};
|
|
97762
97762
|
},
|
|
97763
|
+
async foregroundApp() {
|
|
97764
|
+
return await query("foreground_app");
|
|
97765
|
+
},
|
|
97763
97766
|
async livePanel() {
|
|
97764
97767
|
const result = await query("live_panel", LIVE_PANEL_TIMEOUT_MS);
|
|
97765
97768
|
if (result.error) {
|
|
@@ -97869,23 +97872,23 @@ var InvalidToolInputError = class extends Error {
|
|
|
97869
97872
|
});
|
|
97870
97873
|
}
|
|
97871
97874
|
};
|
|
97872
|
-
function platformMatrix(platform,
|
|
97875
|
+
function platformMatrix(platform, capability38) {
|
|
97873
97876
|
switch (platform) {
|
|
97874
97877
|
case "ios":
|
|
97875
|
-
return
|
|
97878
|
+
return capability38.apple;
|
|
97876
97879
|
case "ios-remote":
|
|
97877
|
-
return
|
|
97880
|
+
return capability38.appleRemote;
|
|
97878
97881
|
case "android":
|
|
97879
|
-
return
|
|
97882
|
+
return capability38.android;
|
|
97880
97883
|
case "chromium":
|
|
97881
|
-
return
|
|
97884
|
+
return capability38.chromium;
|
|
97882
97885
|
case "vega":
|
|
97883
|
-
return
|
|
97886
|
+
return capability38.vega;
|
|
97884
97887
|
}
|
|
97885
97888
|
}
|
|
97886
|
-
function assertSupported(toolId,
|
|
97887
|
-
if (!
|
|
97888
|
-
const matrix = platformMatrix(device.platform,
|
|
97889
|
+
function assertSupported(toolId, capability38, device) {
|
|
97890
|
+
if (!capability38) return;
|
|
97891
|
+
const matrix = platformMatrix(device.platform, capability38);
|
|
97889
97892
|
if (!matrix) {
|
|
97890
97893
|
throw new UnsupportedOperationError(toolId, device, `no ${device.platform} support declared`);
|
|
97891
97894
|
}
|
|
@@ -97893,7 +97896,7 @@ function assertSupported(toolId, capability36, device) {
|
|
|
97893
97896
|
if (!supported) {
|
|
97894
97897
|
throw new UnsupportedOperationError(toolId, device, `kind '${device.kind}' not supported`);
|
|
97895
97898
|
}
|
|
97896
|
-
if (
|
|
97899
|
+
if (capability38.supports && !capability38.supports(device)) {
|
|
97897
97900
|
throw new UnsupportedOperationError(toolId, device, "supports() refiner rejected device");
|
|
97898
97901
|
}
|
|
97899
97902
|
}
|
|
@@ -116728,13 +116731,13 @@ function scheduleGroupSigkill(pid, graceMs, opts) {
|
|
|
116728
116731
|
}, graceMs).unref();
|
|
116729
116732
|
}
|
|
116730
116733
|
async function pollPidsUntilGone(pids, opts) {
|
|
116731
|
-
const
|
|
116734
|
+
const isAlive2 = opts.isAlive ?? pidIsAlive;
|
|
116732
116735
|
const sleep14 = opts.sleep ?? ((ms) => new Promise((resolve14) => setTimeout(resolve14, ms)));
|
|
116733
116736
|
const maxPolls = Math.max(1, Math.ceil(opts.timeoutMs / opts.pollIntervalMs));
|
|
116734
|
-
let remaining = pids.filter((pid) =>
|
|
116737
|
+
let remaining = pids.filter((pid) => isAlive2(pid));
|
|
116735
116738
|
for (let poll = 0; poll < maxPolls && remaining.length > 0; poll += 1) {
|
|
116736
116739
|
await sleep14(opts.pollIntervalMs);
|
|
116737
|
-
remaining = remaining.filter((pid) =>
|
|
116740
|
+
remaining = remaining.filter((pid) => isAlive2(pid));
|
|
116738
116741
|
}
|
|
116739
116742
|
return remaining;
|
|
116740
116743
|
}
|
|
@@ -117834,9 +117837,11 @@ var fs29 = __toESM(require("node:fs"));
|
|
|
117834
117837
|
var path26 = __toESM(require("node:path"));
|
|
117835
117838
|
var os12 = __toESM(require("node:os"));
|
|
117836
117839
|
var MAX_ENTRIES = 5e4;
|
|
117840
|
+
var STALE_LOG_MS = 24 * 60 * 60 * 1e3;
|
|
117837
117841
|
var CLUSTER_KEY_LENGTH = 80;
|
|
117838
117842
|
var SOURCE_EXT = /\.(tsx?|jsx?|mjs|cjs)$/;
|
|
117839
117843
|
var LINE_RE = /^\[L:(\d+)\] (\S+) (\S+)\s+(\S+) \| (.*)$/;
|
|
117844
|
+
var liveLogFiles = /* @__PURE__ */ new Set();
|
|
117840
117845
|
var LogFileWriter = class {
|
|
117841
117846
|
filePath;
|
|
117842
117847
|
fd = null;
|
|
@@ -117850,7 +117855,9 @@ var LogFileWriter = class {
|
|
|
117850
117855
|
const timestamp = Date.now();
|
|
117851
117856
|
const dir = path26.join(os12.homedir(), ".argent", "tmp");
|
|
117852
117857
|
fs29.mkdirSync(dir, { recursive: true });
|
|
117853
|
-
|
|
117858
|
+
pruneStaleLogs(dir);
|
|
117859
|
+
this.filePath = path26.join(dir, `argent-logs-${port}-${timestamp}-p${process.pid}.log`);
|
|
117860
|
+
liveLogFiles.add(this.filePath);
|
|
117854
117861
|
this.open();
|
|
117855
117862
|
}
|
|
117856
117863
|
open() {
|
|
@@ -117943,9 +117950,11 @@ var LogFileWriter = class {
|
|
|
117943
117950
|
}
|
|
117944
117951
|
return { entries: filtered, total };
|
|
117945
117952
|
}
|
|
117946
|
-
close
|
|
117953
|
+
/** `keepFile` leaves the log to the sweep, 24h after the close. */
|
|
117954
|
+
close({ keepFile = false } = {}) {
|
|
117947
117955
|
if (this.closed) return;
|
|
117948
117956
|
this.closed = true;
|
|
117957
|
+
liveLogFiles.delete(this.filePath);
|
|
117949
117958
|
if (this.fd !== null) {
|
|
117950
117959
|
try {
|
|
117951
117960
|
fs29.closeSync(this.fd);
|
|
@@ -117953,12 +117962,47 @@ var LogFileWriter = class {
|
|
|
117953
117962
|
}
|
|
117954
117963
|
this.fd = null;
|
|
117955
117964
|
}
|
|
117965
|
+
if (keepFile) {
|
|
117966
|
+
try {
|
|
117967
|
+
const now = /* @__PURE__ */ new Date();
|
|
117968
|
+
fs29.utimesSync(this.filePath, now, now);
|
|
117969
|
+
} catch {
|
|
117970
|
+
}
|
|
117971
|
+
return;
|
|
117972
|
+
}
|
|
117956
117973
|
try {
|
|
117957
117974
|
fs29.unlinkSync(this.filePath);
|
|
117958
117975
|
} catch {
|
|
117959
117976
|
}
|
|
117960
117977
|
}
|
|
117961
117978
|
};
|
|
117979
|
+
function pruneStaleLogs(dir) {
|
|
117980
|
+
const cutoff = Date.now() - STALE_LOG_MS;
|
|
117981
|
+
let names;
|
|
117982
|
+
try {
|
|
117983
|
+
names = fs29.readdirSync(dir);
|
|
117984
|
+
} catch {
|
|
117985
|
+
return;
|
|
117986
|
+
}
|
|
117987
|
+
for (const name of names) {
|
|
117988
|
+
const pid = Number(/^argent-logs-.*-p(\d+)\.log$/.exec(name)?.[1]);
|
|
117989
|
+
if (!pid) continue;
|
|
117990
|
+
const file2 = path26.join(dir, name);
|
|
117991
|
+
if (pid === process.pid ? liveLogFiles.has(file2) : isAlive(pid)) continue;
|
|
117992
|
+
try {
|
|
117993
|
+
if (fs29.statSync(file2).mtimeMs < cutoff) fs29.unlinkSync(file2);
|
|
117994
|
+
} catch {
|
|
117995
|
+
}
|
|
117996
|
+
}
|
|
117997
|
+
}
|
|
117998
|
+
function isAlive(pid) {
|
|
117999
|
+
try {
|
|
118000
|
+
process.kill(pid, 0);
|
|
118001
|
+
return true;
|
|
118002
|
+
} catch (err) {
|
|
118003
|
+
return err.code === "EPERM";
|
|
118004
|
+
}
|
|
118005
|
+
}
|
|
117962
118006
|
function cleanSourceUrl(url2) {
|
|
117963
118007
|
try {
|
|
117964
118008
|
const { pathname } = new URL(url2);
|
|
@@ -117996,20 +118040,36 @@ var reaped = /* @__PURE__ */ new Map();
|
|
|
117996
118040
|
function key(kind, deviceId) {
|
|
117997
118041
|
return `${kind}:${deviceId.toLowerCase()}`;
|
|
117998
118042
|
}
|
|
117999
|
-
function recordReapedSession(kind,
|
|
118000
|
-
const
|
|
118043
|
+
function recordReapedSession(kind, deviceIds, salvage, connectionLost = false) {
|
|
118044
|
+
const ids = [deviceIds].flat().filter((id) => id !== void 0);
|
|
118045
|
+
const entry = { kind, deviceId: ids[0], ids, atMs: Date.now() };
|
|
118001
118046
|
if (salvage) entry.salvage = salvage;
|
|
118002
|
-
|
|
118047
|
+
if (connectionLost) entry.connectionLost = true;
|
|
118048
|
+
for (const id of ids) reaped.set(key(kind, id), entry);
|
|
118003
118049
|
}
|
|
118004
118050
|
function takeReapedSession(kind, deviceId) {
|
|
118005
|
-
const
|
|
118006
|
-
const entry
|
|
118007
|
-
|
|
118051
|
+
const entry = reaped.get(key(kind, deviceId));
|
|
118052
|
+
for (const id of entry?.ids ?? []) {
|
|
118053
|
+
if (reaped.get(key(kind, id)) === entry) reaped.delete(key(kind, id));
|
|
118054
|
+
}
|
|
118008
118055
|
return entry;
|
|
118009
118056
|
}
|
|
118057
|
+
function takeReapedSessionAnyId(kind, ids) {
|
|
118058
|
+
let first;
|
|
118059
|
+
for (const id of new Set(ids)) {
|
|
118060
|
+
if (id === void 0) continue;
|
|
118061
|
+
const entry = takeReapedSession(kind, id);
|
|
118062
|
+
first ??= entry;
|
|
118063
|
+
}
|
|
118064
|
+
return first;
|
|
118065
|
+
}
|
|
118010
118066
|
function describeReapedSession(entry, what) {
|
|
118011
118067
|
const secondsAgo = Math.max(0, Math.round((Date.now() - entry.atMs) / 1e3));
|
|
118012
|
-
|
|
118068
|
+
const salvage = entry.salvage ? ` ${entry.salvage}` : "";
|
|
118069
|
+
if (entry.connectionLost) {
|
|
118070
|
+
return `The ${what} for device ${entry.deviceId} lost its connection ${secondsAgo}s ago \u2014 the app crashed or quit, or its debugger endpoint went away.${salvage}`;
|
|
118071
|
+
}
|
|
118072
|
+
return `The ${what} for device ${entry.deviceId} was torn down ${secondsAgo}s ago \u2014 by a stop-all-simulator-servers, which reaps every service a device owns, or by another teardown that reaches the same services (a stop-simulator-server on Chromium, or a react-profiler-start reclaiming the session with force). One tool-server serves every agent using this argent install, so this may have been another agent rather than your own call. It was not a session that never started.${salvage}`;
|
|
118013
118073
|
}
|
|
118014
118074
|
|
|
118015
118075
|
// ../tool-server/src/blueprints/chromium-js-runtime-debugger.ts
|
|
@@ -118174,14 +118234,17 @@ var chromiumJsRuntimeDebuggerBlueprint = {
|
|
|
118174
118234
|
cdp.events.off("disconnected", onDisconnected);
|
|
118175
118235
|
await consoleServer.close();
|
|
118176
118236
|
const captured = logWriter.getStats().totalEntries;
|
|
118237
|
+
const keepFile = captured > 0 && !cdp.isConnected();
|
|
118177
118238
|
if (captured > 0) {
|
|
118239
|
+
const entries = `${captured} captured console ${captured === 1 ? "entry" : "entries"}`;
|
|
118178
118240
|
recordReapedSession(
|
|
118179
118241
|
"js-runtime-debugger",
|
|
118180
118242
|
device.id,
|
|
118181
|
-
`The
|
|
118243
|
+
keepFile ? `The log file with its ${entries} is kept at ${logWriter.getFilePath()}.` : `The ${entries} went with it \u2014 the log file is deleted on teardown, so this registry starts empty rather than the app having logged nothing.`,
|
|
118244
|
+
keepFile
|
|
118182
118245
|
);
|
|
118183
118246
|
}
|
|
118184
|
-
logWriter.close();
|
|
118247
|
+
logWriter.close({ keepFile });
|
|
118185
118248
|
},
|
|
118186
118249
|
events
|
|
118187
118250
|
};
|
|
@@ -119997,17 +120060,21 @@ var jsRuntimeDebuggerBlueprint = {
|
|
|
119997
120060
|
api,
|
|
119998
120061
|
dispose: async () => {
|
|
119999
120062
|
const captured = logWriter.getStats().totalEntries;
|
|
120063
|
+
const keepFile = captured > 0 && !cdp.isConnected();
|
|
120000
120064
|
if (captured > 0) {
|
|
120001
|
-
const
|
|
120002
|
-
|
|
120003
|
-
|
|
120004
|
-
|
|
120005
|
-
|
|
120065
|
+
const entries = `${captured} captured console ${captured === 1 ? "entry" : "entries"}`;
|
|
120066
|
+
const salvage = keepFile ? `The log file with its ${entries} is kept at ${logWriter.getFilePath()}.` : `The ${entries} went with it \u2014 the log file is deleted on teardown, so this registry starts empty rather than the app having logged nothing.`;
|
|
120067
|
+
recordReapedSession(
|
|
120068
|
+
"js-runtime-debugger",
|
|
120069
|
+
[deviceId, api.logicalDeviceId],
|
|
120070
|
+
salvage,
|
|
120071
|
+
keepFile
|
|
120072
|
+
);
|
|
120006
120073
|
}
|
|
120007
120074
|
forgetDeviceAlias(api.logicalDeviceId);
|
|
120008
120075
|
forgetLogicalKeyedDevice(deviceId);
|
|
120009
120076
|
await consoleServer.close();
|
|
120010
|
-
logWriter.close();
|
|
120077
|
+
logWriter.close({ keepFile });
|
|
120011
120078
|
await cdp.disconnect();
|
|
120012
120079
|
},
|
|
120013
120080
|
events
|
|
@@ -122976,15 +123043,91 @@ Returns { restarted, bundleId }. Fails if the app is not installed.`,
|
|
|
122976
123043
|
};
|
|
122977
123044
|
}
|
|
122978
123045
|
|
|
123046
|
+
// ../tool-server/src/tools/terminate-app/index.ts
|
|
123047
|
+
var import_node_child_process28 = require("node:child_process");
|
|
123048
|
+
var import_node_util21 = require("node:util");
|
|
123049
|
+
init_zod();
|
|
123050
|
+
init_adb();
|
|
123051
|
+
var execFileAsync21 = (0, import_node_util21.promisify)(import_node_child_process28.execFile);
|
|
123052
|
+
var zodSchema12 = external_exports.object({
|
|
123053
|
+
udid: external_exports.string().min(1).describe("Target device id from `list-devices`."),
|
|
123054
|
+
bundleId: external_exports.string().min(1).regex(BUNDLE_ID_PATTERN, BUNDLE_ID_MESSAGE).describe("App identifier. iOS: bundle id. Android: package name.")
|
|
123055
|
+
});
|
|
123056
|
+
var capability4 = {
|
|
123057
|
+
apple: { simulator: true },
|
|
123058
|
+
appleRemote: { simulator: true },
|
|
123059
|
+
android: { emulator: true, device: true, unknown: true },
|
|
123060
|
+
vega: { vvd: true }
|
|
123061
|
+
};
|
|
123062
|
+
async function tolerateNotRunning(terminate) {
|
|
123063
|
+
try {
|
|
123064
|
+
await terminate;
|
|
123065
|
+
return true;
|
|
123066
|
+
} catch (err) {
|
|
123067
|
+
const e = err;
|
|
123068
|
+
if (/found nothing to terminate/i.test(`${e.stderr ?? ""} ${e.message ?? ""}`)) return false;
|
|
123069
|
+
throw err;
|
|
123070
|
+
}
|
|
123071
|
+
}
|
|
123072
|
+
var terminateAppTool = {
|
|
123073
|
+
id: "terminate-app",
|
|
123074
|
+
interaction: {
|
|
123075
|
+
startedMsg: ({ params }) => `Terminating ${params.bundleId}`,
|
|
123076
|
+
completedMsg: ({ params }) => `Terminated ${params.bundleId}`,
|
|
123077
|
+
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to terminate ${params.bundleId}: ${failureSignal2.error_code}`
|
|
123078
|
+
},
|
|
123079
|
+
description: `Stop a running app without relaunching it, for SDK callers.
|
|
123080
|
+
Use when a program needs the app closed between steps; agents use restart-app.
|
|
123081
|
+
Returns { terminated, bundleId }; terminated is false on iOS when the app was not running.
|
|
123082
|
+
Succeeds when the app is not running or not installed.`,
|
|
123083
|
+
hideFromMcp: true,
|
|
123084
|
+
zodSchema: zodSchema12,
|
|
123085
|
+
capability: capability4,
|
|
123086
|
+
services: () => ({}),
|
|
123087
|
+
execute: dispatchByPlatform({
|
|
123088
|
+
toolId: "terminate-app",
|
|
123089
|
+
capability: capability4,
|
|
123090
|
+
ios: {
|
|
123091
|
+
requires: ["xcrun"],
|
|
123092
|
+
handler: async (_services, { udid, bundleId }) => {
|
|
123093
|
+
const args = await simctlArgsForUdid(udid, ["terminate", udid, bundleId]);
|
|
123094
|
+
const terminated = await tolerateNotRunning(execFileAsync21("xcrun", args));
|
|
123095
|
+
return { terminated, bundleId };
|
|
123096
|
+
}
|
|
123097
|
+
},
|
|
123098
|
+
iosRemote: {
|
|
123099
|
+
requires: ["sim-remote"],
|
|
123100
|
+
handler: async (_services, { udid, bundleId }) => {
|
|
123101
|
+
const terminated = await tolerateNotRunning(remoteSimctl.terminate(udid, bundleId));
|
|
123102
|
+
return { terminated, bundleId };
|
|
123103
|
+
}
|
|
123104
|
+
},
|
|
123105
|
+
android: {
|
|
123106
|
+
requires: ["adb"],
|
|
123107
|
+
handler: async (_services, { udid, bundleId }) => {
|
|
123108
|
+
await adbShell(udid, `am force-stop ${shellQuote(bundleId)}`, { timeoutMs: 15e3 });
|
|
123109
|
+
return { terminated: true, bundleId };
|
|
123110
|
+
}
|
|
123111
|
+
},
|
|
123112
|
+
vega: {
|
|
123113
|
+
requires: ["vega"],
|
|
123114
|
+
handler: async (_services, { udid, bundleId }) => {
|
|
123115
|
+
await vegaDevice(udid, ["terminate-app", "-a", bundleId], { timeoutMs: 4e4 });
|
|
123116
|
+
return { terminated: true, bundleId };
|
|
123117
|
+
}
|
|
123118
|
+
}
|
|
123119
|
+
})
|
|
123120
|
+
};
|
|
123121
|
+
|
|
122979
123122
|
// ../tool-server/src/tools/reinstall-app/index.ts
|
|
122980
123123
|
init_zod();
|
|
122981
123124
|
|
|
122982
123125
|
// ../tool-server/src/tools/reinstall-app/platforms/ios.ts
|
|
122983
|
-
var
|
|
122984
|
-
var
|
|
123126
|
+
var import_node_child_process29 = require("node:child_process");
|
|
123127
|
+
var import_node_util22 = require("node:util");
|
|
122985
123128
|
var import_node_path16 = require("node:path");
|
|
122986
123129
|
init_src2();
|
|
122987
|
-
var
|
|
123130
|
+
var execFileAsync22 = (0, import_node_util22.promisify)(import_node_child_process29.execFile);
|
|
122988
123131
|
var iosImpl = {
|
|
122989
123132
|
requires: ["xcrun"],
|
|
122990
123133
|
handler: async (_services, params) => {
|
|
@@ -122992,11 +123135,11 @@ var iosImpl = {
|
|
|
122992
123135
|
const absolute = (0, import_node_path16.resolve)(appPath);
|
|
122993
123136
|
const { nativeId, prefix } = await simctlTargetForUdid(udid);
|
|
122994
123137
|
try {
|
|
122995
|
-
await
|
|
123138
|
+
await execFileAsync22("xcrun", [...prefix, "uninstall", nativeId, bundleId]);
|
|
122996
123139
|
} catch {
|
|
122997
123140
|
}
|
|
122998
123141
|
try {
|
|
122999
|
-
await
|
|
123142
|
+
await execFileAsync22("xcrun", [...prefix, "install", nativeId, absolute]);
|
|
123000
123143
|
} catch (err) {
|
|
123001
123144
|
throw new FailureError(
|
|
123002
123145
|
`Failed to install iOS app bundle on ${udid}.`,
|
|
@@ -123113,7 +123256,7 @@ ${stderr}`;
|
|
|
123113
123256
|
};
|
|
123114
123257
|
|
|
123115
123258
|
// ../tool-server/src/tools/reinstall-app/index.ts
|
|
123116
|
-
var
|
|
123259
|
+
var zodSchema13 = external_exports.object({
|
|
123117
123260
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
123118
123261
|
bundleId: external_exports.string().regex(BUNDLE_ID_PATTERN, BUNDLE_ID_MESSAGE).describe(
|
|
123119
123262
|
"App identifier that matches the bundle at `appPath`. iOS: bundle id (used to uninstall first). Android: package name (used to uninstall first; the install itself identifies the app from the APK). Vega: interactive component app id (e.g. com.example.app.main), used to uninstall first."
|
|
@@ -123122,7 +123265,7 @@ var zodSchema12 = external_exports.object({
|
|
|
123122
123265
|
"Path to the app bundle. iOS: `.app` directory (e.g. ./build/.../MyApp.app). Android: `.apk` file (e.g. android/app/build/outputs/apk/debug/app-debug.apk). Vega: `.vpkg` file. Relative paths are resolved from the current working directory."
|
|
123123
123266
|
)
|
|
123124
123267
|
});
|
|
123125
|
-
var
|
|
123268
|
+
var capability5 = {
|
|
123126
123269
|
apple: { simulator: true, device: true },
|
|
123127
123270
|
appleRemote: { simulator: true },
|
|
123128
123271
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -123138,13 +123281,13 @@ var reinstallAppTool = {
|
|
|
123138
123281
|
description: `Install or reinstall an app on the device. The previous installation (if any) is uninstalled first so app data and runtime permissions are cleared.
|
|
123139
123282
|
Use for a full reinstall after rebuilding, or to start from a clean app state.
|
|
123140
123283
|
Returns { reinstalled, bundleId }. Fails if the app path does not exist or the package does not match the platform (.app for iOS, .apk for Android, .vpkg for Vega).`,
|
|
123141
|
-
zodSchema:
|
|
123142
|
-
capability:
|
|
123284
|
+
zodSchema: zodSchema13,
|
|
123285
|
+
capability: capability5,
|
|
123143
123286
|
fileInputs: [{ target: "appPath", path: "${appPath}", kind: "tar-upload" }],
|
|
123144
123287
|
services: () => ({}),
|
|
123145
123288
|
execute: dispatchByPlatform({
|
|
123146
123289
|
toolId: "reinstall-app",
|
|
123147
|
-
capability:
|
|
123290
|
+
capability: capability5,
|
|
123148
123291
|
ios: iosImpl,
|
|
123149
123292
|
android: androidImpl3,
|
|
123150
123293
|
iosDevice: iosDeviceImpl3,
|
|
@@ -123173,10 +123316,10 @@ var PERMISSION_NAMES = [
|
|
|
123173
123316
|
];
|
|
123174
123317
|
|
|
123175
123318
|
// ../tool-server/src/tools/settings-permissions/platforms/ios.ts
|
|
123176
|
-
var
|
|
123177
|
-
var
|
|
123319
|
+
var import_node_child_process30 = require("node:child_process");
|
|
123320
|
+
var import_node_util23 = require("node:util");
|
|
123178
123321
|
init_src2();
|
|
123179
|
-
var
|
|
123322
|
+
var execFileAsync23 = (0, import_node_util23.promisify)(import_node_child_process30.execFile);
|
|
123180
123323
|
var SIMCTL_ACTION = {
|
|
123181
123324
|
grant: "grant",
|
|
123182
123325
|
deny: "revoke",
|
|
@@ -123201,7 +123344,7 @@ var NON_TCC_GRANT_NEEDS_INSTALL = /* @__PURE__ */ new Set([
|
|
|
123201
123344
|
]);
|
|
123202
123345
|
var localBackend = {
|
|
123203
123346
|
async run(udid, simctlAction, service, bundleId) {
|
|
123204
|
-
await
|
|
123347
|
+
await execFileAsync23(
|
|
123205
123348
|
"xcrun",
|
|
123206
123349
|
await simctlArgsForUdid(udid, ["privacy", udid, simctlAction, service, bundleId]),
|
|
123207
123350
|
{ timeout: 3e4 }
|
|
@@ -123209,7 +123352,7 @@ var localBackend = {
|
|
|
123209
123352
|
},
|
|
123210
123353
|
async isInstalled(udid, bundleId) {
|
|
123211
123354
|
try {
|
|
123212
|
-
await
|
|
123355
|
+
await execFileAsync23(
|
|
123213
123356
|
"xcrun",
|
|
123214
123357
|
await simctlArgsForUdid(udid, ["get_app_container", udid, bundleId]),
|
|
123215
123358
|
{ timeout: 15e3 }
|
|
@@ -123435,7 +123578,7 @@ var androidImpl4 = {
|
|
|
123435
123578
|
};
|
|
123436
123579
|
|
|
123437
123580
|
// ../tool-server/src/tools/settings-permissions/index.ts
|
|
123438
|
-
var
|
|
123581
|
+
var zodSchema14 = external_exports.object({
|
|
123439
123582
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS simulator UDID or Android serial)."),
|
|
123440
123583
|
action: external_exports.enum(PERMISSION_ACTIONS).describe(
|
|
123441
123584
|
"`grant` pre-authorizes the permission, `deny` refuses it, `reset` returns it to the not-yet-asked state so the app prompts on next use."
|
|
@@ -123452,7 +123595,7 @@ var permissionAction = {
|
|
|
123452
123595
|
deny: { started: "Denying", completed: "Denied" },
|
|
123453
123596
|
reset: { started: "Resetting", completed: "Reset" }
|
|
123454
123597
|
};
|
|
123455
|
-
var
|
|
123598
|
+
var capability6 = {
|
|
123456
123599
|
// `simctl privacy` edits the simulator's TCC store; physical iPhones have no
|
|
123457
123600
|
// equivalent host-side switch, hence no `device: true`.
|
|
123458
123601
|
apple: { simulator: true },
|
|
@@ -123475,12 +123618,12 @@ Android: changes the mapped \`android.permission.*\` runtime permissions (reset
|
|
|
123475
123618
|
Some permission changes terminate the app if it is running (system behavior on both platforms) \u2014 set permissions before launching, or relaunch after.
|
|
123476
123619
|
Returns { action, permission, bundleId, applied, skipped? }: \`applied\` lists the platform-level services/permissions actually changed; \`skipped\` (Android) lists mapped permissions the package manager rejected, e.g. ones the manifest doesn't declare. Fails if nothing could be applied.`,
|
|
123477
123620
|
searchHint: "grant deny reset revoke app permissions privacy camera microphone location settings",
|
|
123478
|
-
zodSchema:
|
|
123479
|
-
capability:
|
|
123621
|
+
zodSchema: zodSchema14,
|
|
123622
|
+
capability: capability6,
|
|
123480
123623
|
services: () => ({}),
|
|
123481
123624
|
execute: dispatchByPlatform({
|
|
123482
123625
|
toolId: "settings-permissions",
|
|
123483
|
-
capability:
|
|
123626
|
+
capability: capability6,
|
|
123484
123627
|
ios: iosImpl2,
|
|
123485
123628
|
iosRemote: iosRemoteImpl4,
|
|
123486
123629
|
android: androidImpl4
|
|
@@ -123492,8 +123635,8 @@ init_zod();
|
|
|
123492
123635
|
init_device_info();
|
|
123493
123636
|
|
|
123494
123637
|
// ../tool-server/src/tools/open-url/platforms/ios.ts
|
|
123495
|
-
var
|
|
123496
|
-
var
|
|
123638
|
+
var import_node_child_process31 = require("node:child_process");
|
|
123639
|
+
var import_node_util24 = require("node:util");
|
|
123497
123640
|
init_src2();
|
|
123498
123641
|
|
|
123499
123642
|
// ../tool-server/src/tools/open-url/deep-link-note.ts
|
|
@@ -123503,12 +123646,12 @@ function httpDeepLinkNote(url2) {
|
|
|
123503
123646
|
}
|
|
123504
123647
|
|
|
123505
123648
|
// ../tool-server/src/tools/open-url/platforms/ios.ts
|
|
123506
|
-
var
|
|
123649
|
+
var execFileAsync24 = (0, import_node_util24.promisify)(import_node_child_process31.execFile);
|
|
123507
123650
|
var iosImpl3 = {
|
|
123508
123651
|
requires: ["xcrun"],
|
|
123509
123652
|
handler: async (_services, params) => {
|
|
123510
123653
|
try {
|
|
123511
|
-
await
|
|
123654
|
+
await execFileAsync24(
|
|
123512
123655
|
"xcrun",
|
|
123513
123656
|
await simctlArgsForUdid(params.udid, ["openurl", params.udid, params.url])
|
|
123514
123657
|
);
|
|
@@ -123607,7 +123750,7 @@ var chromiumImpl2 = {
|
|
|
123607
123750
|
};
|
|
123608
123751
|
|
|
123609
123752
|
// ../tool-server/src/tools/open-url/index.ts
|
|
123610
|
-
var
|
|
123753
|
+
var zodSchema15 = external_exports.object({
|
|
123611
123754
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
|
|
123612
123755
|
url: external_exports.string().describe(
|
|
123613
123756
|
"URL or scheme to open (e.g. https://example.com, messages://, tel:555, geo:37.0,-122.0). For Chromium this navigates the renderer."
|
|
@@ -123624,7 +123767,7 @@ function safeDestination(value) {
|
|
|
123624
123767
|
return "URL";
|
|
123625
123768
|
}
|
|
123626
123769
|
}
|
|
123627
|
-
var
|
|
123770
|
+
var capability7 = {
|
|
123628
123771
|
apple: { simulator: true, device: true },
|
|
123629
123772
|
appleRemote: { simulator: true },
|
|
123630
123773
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -123643,8 +123786,8 @@ Cross-platform schemes: https://, tel:, mailto:. iOS also: messages://, settings
|
|
|
123643
123786
|
Deep-linking caveat: an https:// link opens the native app only when an installed app is verified for the link's domain (iOS Universal Links / Android App Links) \u2014 otherwise it opens in the browser, and on iOS simulators it may open in Safari even when the owning app is installed. To reliably open an installed app, use its custom scheme (scheme://path) or launch-app with its bundle id.
|
|
123644
123787
|
On a physical iPhone, http(s) URLs default to Safari and any other scheme needs bundleId; the receiving app becomes the app under automation.
|
|
123645
123788
|
Returns { opened, url, note? }. note carries the deep-linking caveat when a web URL was opened on a native device. Fails if no app is registered to handle the URI (iOS/Android) or the renderer rejects the navigation (Chromium).`,
|
|
123646
|
-
zodSchema:
|
|
123647
|
-
capability:
|
|
123789
|
+
zodSchema: zodSchema15,
|
|
123790
|
+
capability: capability7,
|
|
123648
123791
|
services: (params) => {
|
|
123649
123792
|
const device = resolveDevice(params.udid);
|
|
123650
123793
|
if (device.platform === "chromium") {
|
|
@@ -123654,7 +123797,7 @@ Returns { opened, url, note? }. note carries the deep-linking caveat when a web
|
|
|
123654
123797
|
},
|
|
123655
123798
|
execute: dispatchByPlatform({
|
|
123656
123799
|
toolId: "open-url",
|
|
123657
|
-
capability:
|
|
123800
|
+
capability: capability7,
|
|
123658
123801
|
ios: iosImpl3,
|
|
123659
123802
|
iosDevice: iosDeviceImpl4,
|
|
123660
123803
|
android: androidImpl5,
|
|
@@ -123664,8 +123807,8 @@ Returns { opened, url, note? }. note carries the deep-linking caveat when a web
|
|
|
123664
123807
|
};
|
|
123665
123808
|
|
|
123666
123809
|
// ../tool-server/src/tools/screenshot/index.ts
|
|
123667
|
-
var
|
|
123668
|
-
var
|
|
123810
|
+
var import_node_child_process32 = require("node:child_process");
|
|
123811
|
+
var import_node_util25 = require("node:util");
|
|
123669
123812
|
var os13 = __toESM(require("node:os"));
|
|
123670
123813
|
var path29 = __toESM(require("node:path"));
|
|
123671
123814
|
init_zod();
|
|
@@ -124237,8 +124380,8 @@ function scalePng(src, scale) {
|
|
|
124237
124380
|
|
|
124238
124381
|
// ../tool-server/src/tools/screenshot/index.ts
|
|
124239
124382
|
var fs35 = __toESM(require("node:fs/promises"));
|
|
124240
|
-
var
|
|
124241
|
-
var
|
|
124383
|
+
var execFileAsync25 = (0, import_node_util25.promisify)(import_node_child_process32.execFile);
|
|
124384
|
+
var zodSchema16 = external_exports.object({
|
|
124242
124385
|
udid: external_exports.string().describe(
|
|
124243
124386
|
"Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, or Chromium id)."
|
|
124244
124387
|
),
|
|
@@ -124255,7 +124398,7 @@ var zodSchema15 = external_exports.object({
|
|
|
124255
124398
|
"Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum. Ignored on physical iPhones."
|
|
124256
124399
|
)
|
|
124257
124400
|
});
|
|
124258
|
-
var
|
|
124401
|
+
var capability8 = {
|
|
124259
124402
|
apple: { simulator: true, device: true },
|
|
124260
124403
|
appleRemote: { simulator: true },
|
|
124261
124404
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -124278,11 +124421,11 @@ async function tvScreenshot(udid, scale, signal) {
|
|
|
124278
124421
|
os13.tmpdir(),
|
|
124279
124422
|
`argent-tv-screenshot-${udid.slice(0, 8)}-${process.hrtime.bigint()}.png`
|
|
124280
124423
|
);
|
|
124281
|
-
await
|
|
124424
|
+
await execFileAsync25("xcrun", await simctlArgsForUdid(udid, ["io", udid, "screenshot", file2]), {
|
|
124282
124425
|
signal
|
|
124283
124426
|
});
|
|
124284
124427
|
if (scale < 1) {
|
|
124285
|
-
await
|
|
124428
|
+
await execFileAsync25("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
|
|
124286
124429
|
signal
|
|
124287
124430
|
}).catch(() => {
|
|
124288
124431
|
});
|
|
@@ -124292,7 +124435,7 @@ async function tvScreenshot(udid, scale, signal) {
|
|
|
124292
124435
|
async function tvTargetLongSide(file2, scale) {
|
|
124293
124436
|
let longSide = 3840;
|
|
124294
124437
|
try {
|
|
124295
|
-
const { stdout } = await
|
|
124438
|
+
const { stdout } = await execFileAsync25("sips", ["-g", "pixelWidth", "-g", "pixelHeight", file2]);
|
|
124296
124439
|
const width = Number(/pixelWidth:\s*(\d+)/.exec(stdout)?.[1]);
|
|
124297
124440
|
const height = Number(/pixelHeight:\s*(\d+)/.exec(stdout)?.[1]);
|
|
124298
124441
|
if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
|
|
@@ -124306,7 +124449,7 @@ async function downscalePngInPlace(file2, scale, signal) {
|
|
|
124306
124449
|
if (scale >= 1) {
|
|
124307
124450
|
return;
|
|
124308
124451
|
}
|
|
124309
|
-
await
|
|
124452
|
+
await execFileAsync25("sips", ["-Z", String(await tvTargetLongSide(file2, scale)), file2], {
|
|
124310
124453
|
signal
|
|
124311
124454
|
}).catch(() => {
|
|
124312
124455
|
});
|
|
@@ -124324,9 +124467,9 @@ Use when you need a baseline image before an interaction or to inspect the curre
|
|
|
124324
124467
|
Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device.`,
|
|
124325
124468
|
alwaysLoad: true,
|
|
124326
124469
|
searchHint: "device simulator emulator chromium screen image capture baseline tvos apple tv",
|
|
124327
|
-
zodSchema:
|
|
124470
|
+
zodSchema: zodSchema16,
|
|
124328
124471
|
outputHint: "image",
|
|
124329
|
-
capability:
|
|
124472
|
+
capability: capability8,
|
|
124330
124473
|
// No eager service: a tvOS udid classifies as iOS by shape, so declaring
|
|
124331
124474
|
// simulator-server here would spawn it for a device it cannot drive and hang
|
|
124332
124475
|
// on the ready timeout. Resolve the backend lazily instead.
|
|
@@ -124450,7 +124593,7 @@ async function assertChromiumWindowVisible(chromium, action) {
|
|
|
124450
124593
|
// ../tool-server/src/tools/gesture-tap/index.ts
|
|
124451
124594
|
init_device_info();
|
|
124452
124595
|
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
124453
|
-
var
|
|
124596
|
+
var zodSchema17 = external_exports.object({
|
|
124454
124597
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
|
|
124455
124598
|
x: external_exports.number().describe("Normalized horizontal position 0.0\u20131.0 (left=0, right=1), not pixels"),
|
|
124456
124599
|
y: external_exports.number().describe("Normalized vertical position 0.0\u20131.0 (top=0, bottom=1), not pixels"),
|
|
@@ -124463,7 +124606,7 @@ function tapDescription(params, tense) {
|
|
|
124463
124606
|
const action = count2 === 1 ? tense === "present" ? "Tapping" : "Tapped" : count2 === 2 ? tense === "present" ? "Double-tapping" : "Double-tapped" : `${tense === "present" ? "Tapping" : "Tapped"} ${count2} times`;
|
|
124464
124607
|
return `${action} at (${Math.round(params.x * 100)}%, ${Math.round(params.y * 100)}%)`;
|
|
124465
124608
|
}
|
|
124466
|
-
var
|
|
124609
|
+
var capability9 = {
|
|
124467
124610
|
apple: { simulator: true, device: true },
|
|
124468
124611
|
appleRemote: { simulator: true },
|
|
124469
124612
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -124499,8 +124642,8 @@ On a physical iPhone use \`describe\`; \`native-describe-screen\` is simulator-o
|
|
|
124499
124642
|
Before tapping, determine the correct coordinates by using discovery tools \u2014 pick by platform: iOS / Android use \`describe\`, \`native-describe-screen\`, or \`debugger-component-tree\`; Chromium uses \`describe\` (the DOM walker), since the native and RN-specific discovery tools don't apply. More information in \`argent-device-interact\` skill`,
|
|
124500
124643
|
alwaysLoad: true,
|
|
124501
124644
|
searchHint: "tap press button element device simulator emulator chromium touch down up click",
|
|
124502
|
-
zodSchema:
|
|
124503
|
-
capability:
|
|
124645
|
+
zodSchema: zodSchema17,
|
|
124646
|
+
capability: capability9,
|
|
124504
124647
|
services: (params) => {
|
|
124505
124648
|
const device = resolveDevice(params.udid);
|
|
124506
124649
|
if (device.platform === "chromium") {
|
|
@@ -124565,7 +124708,7 @@ var MOMENTUM_FREE_EASE_EXPONENT = 3;
|
|
|
124565
124708
|
var DEFAULT_DURATION_MS = 300;
|
|
124566
124709
|
var MOMENTUM_FREE_MIN_DURATION_MS = 150;
|
|
124567
124710
|
var MAX_DURATION_MS = 1e4;
|
|
124568
|
-
var
|
|
124711
|
+
var zodSchema18 = external_exports.object({
|
|
124569
124712
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
124570
124713
|
fromX: external_exports.number().describe("Start x: normalized 0.0\u20131.0 (not pixels; same as tap)"),
|
|
124571
124714
|
fromY: external_exports.number().describe("Start y: normalized 0.0\u20131.0 (not pixels; same as tap)"),
|
|
@@ -124594,7 +124737,7 @@ var zodSchema17 = external_exports.object({
|
|
|
124594
124737
|
path: ["durationMs"]
|
|
124595
124738
|
}
|
|
124596
124739
|
);
|
|
124597
|
-
var
|
|
124740
|
+
var capability10 = {
|
|
124598
124741
|
apple: { simulator: true, device: true },
|
|
124599
124742
|
appleRemote: { simulator: true },
|
|
124600
124743
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -124616,8 +124759,8 @@ Physical iOS: an edge gesture (back-swipe) needs fromX 0 exactly; durationMs set
|
|
|
124616
124759
|
Pass momentum:false for a momentum-free swipe that lands where the finger lifts (little to no fling at the 300 default), when you need a deterministic scroll distance; it needs durationMs >= 150 and is rejected below that, a shorter ease-out leaving the OS too little wall clock to read the deceleration as a stop. At 150 it lands short of the lift point instead, and 2 of 47 runs still flung backwards. A plain swipe takes any duration up to 10000ms and is delivered as close to the speed it was authored as a 16ms frame allows: below ~32ms the whole travel lands in one or two frames, which the OS flings as hard as it flings anything. Returns { swiped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend is not reachable for the given device.`,
|
|
124617
124760
|
alwaysLoad: true,
|
|
124618
124761
|
searchHint: "swipe scroll drag pan gesture device simulator emulator touch move",
|
|
124619
|
-
zodSchema:
|
|
124620
|
-
capability:
|
|
124762
|
+
zodSchema: zodSchema18,
|
|
124763
|
+
capability: capability10,
|
|
124621
124764
|
services: (params) => {
|
|
124622
124765
|
const device = resolveDevice(params.udid);
|
|
124623
124766
|
if (isIosPhysicalDevice(device)) {
|
|
@@ -124711,7 +124854,7 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
|
|
|
124711
124854
|
init_zod();
|
|
124712
124855
|
init_device_info();
|
|
124713
124856
|
var sleep4 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
124714
|
-
var
|
|
124857
|
+
var zodSchema19 = external_exports.object({
|
|
124715
124858
|
udid: external_exports.string().describe("Target Chromium device id from `list-devices` (chromium-cdp-<port>)."),
|
|
124716
124859
|
x: external_exports.number().describe(
|
|
124717
124860
|
"Anchor x: normalized 0.0\u20131.0 (fraction of window width, not pixels). The wheel events land here \u2014 put it over the element you want to scroll."
|
|
@@ -124736,7 +124879,7 @@ function scrollDirection(params) {
|
|
|
124736
124879
|
if ((params.deltaY ?? 0) === 0) return horizontal;
|
|
124737
124880
|
return `${vertical} and ${horizontal}`;
|
|
124738
124881
|
}
|
|
124739
|
-
var
|
|
124882
|
+
var capability11 = {
|
|
124740
124883
|
chromium: { app: true }
|
|
124741
124884
|
};
|
|
124742
124885
|
var gestureScrollTool = {
|
|
@@ -124751,8 +124894,8 @@ Use when content is below/above the fold (describe shows off-screen elements wit
|
|
|
124751
124894
|
Returns { scrolled: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.`,
|
|
124752
124895
|
alwaysLoad: true,
|
|
124753
124896
|
searchHint: "scroll wheel list page chromium mouse down up content fold",
|
|
124754
|
-
zodSchema:
|
|
124755
|
-
capability:
|
|
124897
|
+
zodSchema: zodSchema19,
|
|
124898
|
+
capability: capability11,
|
|
124756
124899
|
services: (params) => ({
|
|
124757
124900
|
chromium: chromiumCdpRef(resolveDevice(params.udid))
|
|
124758
124901
|
}),
|
|
@@ -124781,7 +124924,7 @@ var sleep5 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
124781
124924
|
var MOMENTUM_FREE_EASE_EXPONENT2 = 3;
|
|
124782
124925
|
var MOMENTUM_FREE_MIN_STEPS = 8;
|
|
124783
124926
|
var MAX_DURATION_MS2 = 1e4;
|
|
124784
|
-
var
|
|
124927
|
+
var zodSchema20 = external_exports.object({
|
|
124785
124928
|
udid: external_exports.string().describe("Target Chromium device id from `list-devices` (chromium-cdp-<port>)."),
|
|
124786
124929
|
fromX: external_exports.number().describe("Press x: normalized 0.0\u20131.0 (fraction of window width, not pixels)."),
|
|
124787
124930
|
fromY: external_exports.number().describe("Press y: normalized 0.0\u20131.0 (fraction of window height, not pixels)."),
|
|
@@ -124803,7 +124946,7 @@ var zodSchema19 = external_exports.object({
|
|
|
124803
124946
|
"Retired: renamed to `momentum` with the opposite sense. Pass `momentum: false` for what `settle: true` meant; `settle: false` was the default, so drop the key."
|
|
124804
124947
|
)
|
|
124805
124948
|
});
|
|
124806
|
-
var
|
|
124949
|
+
var capability12 = {
|
|
124807
124950
|
chromium: { app: true }
|
|
124808
124951
|
};
|
|
124809
124952
|
var gestureDragTool = {
|
|
@@ -124818,8 +124961,8 @@ Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements.
|
|
|
124818
124961
|
Pass momentum:false for a momentum-free drag that decelerates into the release, so apps that compute a fling from the pointer stream read ~0 velocity and the drag ends where it was aimed instead of flinging past it (a durationMs under ~100ms is too short for the deceleration to suppress the fling entirely). Returns { dragged: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.`,
|
|
124819
124962
|
alwaysLoad: true,
|
|
124820
124963
|
searchHint: "drag drop slider mouse press move release chromium select",
|
|
124821
|
-
zodSchema:
|
|
124822
|
-
capability:
|
|
124964
|
+
zodSchema: zodSchema20,
|
|
124965
|
+
capability: capability12,
|
|
124823
124966
|
services: (params) => ({
|
|
124824
124967
|
chromium: chromiumCdpRef(resolveDevice(params.udid))
|
|
124825
124968
|
}),
|
|
@@ -124959,7 +125102,7 @@ var eventSchema = external_exports.object({
|
|
|
124959
125102
|
y2: external_exports.number().optional().describe("Second touch y for two-finger gestures: normalized 0.0\u20131.0 (not pixels)"),
|
|
124960
125103
|
delayMs: external_exports.number().optional().describe("Delay before this event in milliseconds (default 16ms \u2248 60fps)")
|
|
124961
125104
|
});
|
|
124962
|
-
var
|
|
125105
|
+
var zodSchema21 = external_exports.object({
|
|
124963
125106
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
124964
125107
|
events: external_exports.array(eventSchema).describe(
|
|
124965
125108
|
"Sequence of touch events; x/y (and optional second touch) are normalized 0.0\u20131.0, not pixels"
|
|
@@ -124968,7 +125111,7 @@ var zodSchema20 = external_exports.object({
|
|
|
124968
125111
|
"Number of intermediate Move events to auto-insert between each pair of consecutive events. Smooths out gestures by linearly interpolating both primary (x,y) and secondary (x2,y2) coordinates. The delay is split evenly across interpolated frames. Default: no interpolation."
|
|
124969
125112
|
)
|
|
124970
125113
|
});
|
|
124971
|
-
var
|
|
125114
|
+
var capability13 = {
|
|
124972
125115
|
apple: { simulator: true, device: true },
|
|
124973
125116
|
appleRemote: { simulator: true },
|
|
124974
125117
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -125052,8 +125195,8 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
|
|
|
125052
125195
|
events: [{"type":"Down","x":0.4,"y":0.5,"x2":0.6,"y2":0.5},
|
|
125053
125196
|
{"type":"Up","x":0.2,"y":0.5,"x2":0.8,"y2":0.5}]
|
|
125054
125197
|
interpolate: 10`,
|
|
125055
|
-
zodSchema:
|
|
125056
|
-
capability:
|
|
125198
|
+
zodSchema: zodSchema21,
|
|
125199
|
+
capability: capability13,
|
|
125057
125200
|
// Declare the runner only for a train execute can replay. A rejected train must not pay a runner cold start.
|
|
125058
125201
|
services: (params) => {
|
|
125059
125202
|
const device = resolveDevice(params.udid);
|
|
@@ -125093,7 +125236,7 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
|
|
|
125093
125236
|
// ../tool-server/src/tools/gesture-pinch/index.ts
|
|
125094
125237
|
init_zod();
|
|
125095
125238
|
init_device_info();
|
|
125096
|
-
var
|
|
125239
|
+
var zodSchema22 = external_exports.object({
|
|
125097
125240
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
125098
125241
|
centerX: external_exports.number().describe(
|
|
125099
125242
|
"Center of pinch, horizontal: normalized 0.0\u20131.0 (fraction of screen width, not pixels)"
|
|
@@ -125116,7 +125259,7 @@ var zodSchema21 = external_exports.object({
|
|
|
125116
125259
|
angle: external_exports.number().optional().describe("Axis angle in degrees along which the fingers are placed (default 0 = horizontal)."),
|
|
125117
125260
|
durationMs: external_exports.number().optional().describe("Total gesture duration in milliseconds (default 300)")
|
|
125118
125261
|
});
|
|
125119
|
-
var
|
|
125262
|
+
var capability14 = {
|
|
125120
125263
|
apple: { simulator: true },
|
|
125121
125264
|
appleRemote: { simulator: true },
|
|
125122
125265
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -125133,8 +125276,8 @@ startDistance > endDistance = pinch in (zoom out). startDistance < endDistance =
|
|
|
125133
125276
|
Typical values: startDistance 0.2, endDistance 0.6 for a zoom-in pinch at screen center.
|
|
125134
125277
|
Auto-generates interpolated frames at ~60fps. The angle parameter controls the axis (0 = horizontal, 90 = vertical). Optional endCenterX/endCenterY drift the centroid linearly over the gesture (omitted = fixed center).
|
|
125135
125278
|
Use when you need to zoom in or out on a map, image, or zoomable view. Returns { pinched: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.`,
|
|
125136
|
-
zodSchema:
|
|
125137
|
-
capability:
|
|
125279
|
+
zodSchema: zodSchema22,
|
|
125280
|
+
capability: capability14,
|
|
125138
125281
|
services: (params) => ({
|
|
125139
125282
|
simulatorServer: simulatorServerRef(resolveDevice(params.udid))
|
|
125140
125283
|
}),
|
|
@@ -125173,7 +125316,7 @@ Use when you need to zoom in or out on a map, image, or zoomable view. Returns {
|
|
|
125173
125316
|
// ../tool-server/src/tools/gesture-rotate/index.ts
|
|
125174
125317
|
init_zod();
|
|
125175
125318
|
init_device_info();
|
|
125176
|
-
var
|
|
125319
|
+
var zodSchema23 = external_exports.object({
|
|
125177
125320
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
125178
125321
|
centerX: external_exports.number().describe(
|
|
125179
125322
|
"Center of rotation, horizontal: normalized 0.0\u20131.0 (fraction of screen width, not pixels)"
|
|
@@ -125198,7 +125341,7 @@ var zodSchema22 = external_exports.object({
|
|
|
125198
125341
|
}).refine((p) => p.radius !== void 0 || p.radiusX !== void 0, {
|
|
125199
125342
|
message: "Pass radius, or both radiusX and radiusY."
|
|
125200
125343
|
});
|
|
125201
|
-
var
|
|
125344
|
+
var capability15 = {
|
|
125202
125345
|
apple: { simulator: true },
|
|
125203
125346
|
appleRemote: { simulator: true },
|
|
125204
125347
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -125224,8 +125367,8 @@ Auto-generates interpolated frames at ~60fps.
|
|
|
125224
125367
|
Unlike gesture-pinch which moves fingers linearly to zoom, this orbits fingers in an arc to change orientation.
|
|
125225
125368
|
Use when you need to rotate a map, image picker, or any rotateable UI element. Returns { rotated: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.
|
|
125226
125369
|
Size the orbit with radius, or with radiusX and radiusY together (the pair overrides radius); one half of the pair alone, or none of the three, is rejected.`,
|
|
125227
|
-
zodSchema:
|
|
125228
|
-
capability:
|
|
125370
|
+
zodSchema: zodSchema23,
|
|
125371
|
+
capability: capability15,
|
|
125229
125372
|
services: (params) => ({
|
|
125230
125373
|
simulatorServer: simulatorServerRef(resolveDevice(params.udid))
|
|
125231
125374
|
}),
|
|
@@ -125281,7 +125424,7 @@ Size the orbit with radius, or with radiusX and radiusY together (the pair overr
|
|
|
125281
125424
|
init_zod();
|
|
125282
125425
|
init_device_info();
|
|
125283
125426
|
var sleep7 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
125284
|
-
var
|
|
125427
|
+
var zodSchema24 = external_exports.object({
|
|
125285
125428
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
125286
125429
|
button: external_exports.enum(["home", "back", "power", "volumeUp", "volumeDown", "appSwitch", "actionButton"]).describe("Hardware button to press")
|
|
125287
125430
|
});
|
|
@@ -125295,7 +125438,7 @@ var BUTTONS_BY_PLATFORM = {
|
|
|
125295
125438
|
// `vega`, so this entry only keeps the record total.
|
|
125296
125439
|
"vega": /* @__PURE__ */ new Set([])
|
|
125297
125440
|
};
|
|
125298
|
-
var
|
|
125441
|
+
var capability16 = {
|
|
125299
125442
|
apple: { simulator: true, device: true },
|
|
125300
125443
|
appleRemote: { simulator: true },
|
|
125301
125444
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -125322,8 +125465,8 @@ Supported buttons depend on the platform: home, back, power, volumeUp, volumeDow
|
|
|
125322
125465
|
Use when you need to trigger hardware button events.
|
|
125323
125466
|
Returns { pressed: buttonName }.
|
|
125324
125467
|
Fails if the device backend is not reachable: the simulator-server for iOS, or \`adb\` for Android (Android presses are injected with \`adb shell input keyevent\`).`,
|
|
125325
|
-
zodSchema:
|
|
125326
|
-
capability:
|
|
125468
|
+
zodSchema: zodSchema24,
|
|
125469
|
+
capability: capability16,
|
|
125327
125470
|
// Declare only the service the resolved path actually consumes. The Android
|
|
125328
125471
|
// path uses `adb`, so a sim-server here would spawn a service the tool never
|
|
125329
125472
|
// uses (up to a 30s ready-wait) and could throw ServiceInitializationError
|
|
@@ -126014,7 +126157,7 @@ var vegaImpl4 = {
|
|
|
126014
126157
|
};
|
|
126015
126158
|
|
|
126016
126159
|
// ../tool-server/src/tools/keyboard/index.ts
|
|
126017
|
-
var
|
|
126160
|
+
var zodSchema25 = external_exports.object({
|
|
126018
126161
|
udid: external_exports.string().describe(
|
|
126019
126162
|
"Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id)."
|
|
126020
126163
|
),
|
|
@@ -126028,7 +126171,7 @@ var zodSchema24 = external_exports.object({
|
|
|
126028
126171
|
"Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on Vega (text/keys injected in a single shot), on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence), and on physical iOS."
|
|
126029
126172
|
)
|
|
126030
126173
|
});
|
|
126031
|
-
var
|
|
126174
|
+
var capability17 = {
|
|
126032
126175
|
apple: { simulator: true, device: true },
|
|
126033
126176
|
appleRemote: { simulator: true },
|
|
126034
126177
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -126038,7 +126181,7 @@ var capability16 = {
|
|
|
126038
126181
|
function createKeyboardTool(registry2) {
|
|
126039
126182
|
const dispatch = dispatchByPlatform({
|
|
126040
126183
|
toolId: "keyboard",
|
|
126041
|
-
capability:
|
|
126184
|
+
capability: capability17,
|
|
126042
126185
|
ios: makeIosImpl3(registry2),
|
|
126043
126186
|
iosDevice: makeIosDeviceImpl(registry2),
|
|
126044
126187
|
iosRemote: makeIosRemoteImpl(registry2),
|
|
@@ -126072,8 +126215,9 @@ A failure is not rolled back. An unsupported key name is always rejected before
|
|
|
126072
126215
|
- key: presses a single named key (enter, escape, backspace, tab, arrow-up/down/left/right, f1-f12). NOT supported on TV targets; move focus with \`tv-remote\` instead. Physical iOS: only \`enter\` and \`backspace\`.
|
|
126073
126216
|
On a TV target (runtimeKind 'tv') only \`text\` applies \u2014 focus a text field first (with \`tv-remote\`), then type into it (injected HID keyboard on Apple TV, \`adb input text\` on Android TV).
|
|
126074
126217
|
One call does one action: pass text OR key, never both. To type and then press a key, send two \`keyboard\` steps in one \`run-sequence\` \u2014 { text: "hello" } then { key: "enter" } \u2014 which also keeps it to a single round-trip.`,
|
|
126075
|
-
zodSchema:
|
|
126076
|
-
capability:
|
|
126218
|
+
zodSchema: zodSchema25,
|
|
126219
|
+
capability: capability17,
|
|
126220
|
+
alwaysLoad: true,
|
|
126077
126221
|
searchHint: "type text keyboard input named key enter escape arrow tv vega fire tv search field hid leanback",
|
|
126078
126222
|
services: () => ({}),
|
|
126079
126223
|
execute: async (services, params, options) => {
|
|
@@ -126231,7 +126375,7 @@ function makeAndroidImpl2(registry2) {
|
|
|
126231
126375
|
}
|
|
126232
126376
|
|
|
126233
126377
|
// ../tool-server/src/tools/paste/index.ts
|
|
126234
|
-
var
|
|
126378
|
+
var capability18 = {
|
|
126235
126379
|
apple: { simulator: true },
|
|
126236
126380
|
// A remote sim pastes over the MoQ transport (`simctl pbcopy` + ⌘V); the HTTP
|
|
126237
126381
|
// clipboard route does not exist there.
|
|
@@ -126265,7 +126409,7 @@ function serializedPerDevice(deviceId, task) {
|
|
|
126265
126409
|
function createPasteTool(registry2) {
|
|
126266
126410
|
const dispatch = dispatchByPlatform({
|
|
126267
126411
|
toolId: "paste",
|
|
126268
|
-
capability:
|
|
126412
|
+
capability: capability18,
|
|
126269
126413
|
ios: makeIosImpl4(registry2),
|
|
126270
126414
|
iosRemote: makeIosRemoteImpl2(registry2),
|
|
126271
126415
|
android: makeAndroidImpl2(registry2)
|
|
@@ -126283,7 +126427,7 @@ Tap the field first so it has focus. Returns { pasted: true }, plus via: "keyboa
|
|
|
126283
126427
|
Supports \`{{secret:<NAME>}}\` placeholders like \`keyboard\`; the value is never echoed back.`,
|
|
126284
126428
|
searchHint: "paste clipboard pasteboard otp 2fa code fill field",
|
|
126285
126429
|
zodSchema: pasteZodSchema,
|
|
126286
|
-
capability:
|
|
126430
|
+
capability: capability18,
|
|
126287
126431
|
services: () => ({}),
|
|
126288
126432
|
execute: async (services, params, options) => {
|
|
126289
126433
|
const { text, secrets } = resolveSecretPlaceholders(params.text);
|
|
@@ -126302,11 +126446,11 @@ Supports \`{{secret:<NAME>}}\` placeholders like \`keyboard\`; the value is neve
|
|
|
126302
126446
|
// ../tool-server/src/tools/rotate/index.ts
|
|
126303
126447
|
init_zod();
|
|
126304
126448
|
init_device_info();
|
|
126305
|
-
var
|
|
126449
|
+
var zodSchema26 = external_exports.object({
|
|
126306
126450
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
126307
126451
|
orientation: external_exports.enum(["Portrait", "LandscapeLeft", "LandscapeRight", "PortraitUpsideDown"]).describe("Target orientation")
|
|
126308
126452
|
});
|
|
126309
|
-
var
|
|
126453
|
+
var capability19 = {
|
|
126310
126454
|
apple: { simulator: true },
|
|
126311
126455
|
appleRemote: { simulator: true },
|
|
126312
126456
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -126322,8 +126466,8 @@ var rotateTool = {
|
|
|
126322
126466
|
Use to test layout in a different orientation. Re-run \`describe\` afterwards \u2014 frame coordinates change with the orientation.
|
|
126323
126467
|
On an unfolded foldable iOS simulator (the iPhone Duo), the value sets the orientation of the device, not of the UI: \`Portrait\` gives a landscape UI and \`LandscapeLeft\` gives a portrait UI. To fold or unfold the device, use \`fold\`.
|
|
126324
126468
|
Returns { orientation }. Fails if the target device is not booted.`,
|
|
126325
|
-
zodSchema:
|
|
126326
|
-
capability:
|
|
126469
|
+
zodSchema: zodSchema26,
|
|
126470
|
+
capability: capability19,
|
|
126327
126471
|
services: (params) => ({
|
|
126328
126472
|
simulatorServer: simulatorServerRef(resolveDevice(params.udid))
|
|
126329
126473
|
}),
|
|
@@ -126347,12 +126491,12 @@ var shakeZodSchema = external_exports.object({
|
|
|
126347
126491
|
});
|
|
126348
126492
|
|
|
126349
126493
|
// ../tool-server/src/tools/shake/platforms/ios.ts
|
|
126350
|
-
var
|
|
126351
|
-
var
|
|
126494
|
+
var import_node_child_process34 = require("node:child_process");
|
|
126495
|
+
var import_node_util26 = require("node:util");
|
|
126352
126496
|
init_src2();
|
|
126353
126497
|
|
|
126354
126498
|
// ../tool-server/src/utils/window-shake.ts
|
|
126355
|
-
var
|
|
126499
|
+
var import_node_child_process33 = require("node:child_process");
|
|
126356
126500
|
init_src();
|
|
126357
126501
|
var MICROINTERACTIONS_FLAG = "microinteractions";
|
|
126358
126502
|
var AMPLITUDE = 22;
|
|
@@ -126459,7 +126603,7 @@ end run
|
|
|
126459
126603
|
}
|
|
126460
126604
|
function runOsascript(script) {
|
|
126461
126605
|
return new Promise((resolve14, reject) => {
|
|
126462
|
-
const child = (0,
|
|
126606
|
+
const child = (0, import_node_child_process33.execFile)(
|
|
126463
126607
|
"/usr/bin/osascript",
|
|
126464
126608
|
["-"],
|
|
126465
126609
|
{ timeout: OSASCRIPT_TIMEOUT_MS },
|
|
@@ -126552,7 +126696,7 @@ async function prepareHostWindowShake(target) {
|
|
|
126552
126696
|
}
|
|
126553
126697
|
|
|
126554
126698
|
// ../tool-server/src/tools/shake/platforms/ios.ts
|
|
126555
|
-
var
|
|
126699
|
+
var execFileAsync26 = (0, import_node_util26.promisify)(import_node_child_process34.execFile);
|
|
126556
126700
|
var SHAKE_NOTIFICATION = "com.apple.UIKit.SimulatorShake";
|
|
126557
126701
|
var SHAKE_INTERVAL_MS = 400;
|
|
126558
126702
|
var sleep11 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -126594,7 +126738,7 @@ var iosImpl4 = {
|
|
|
126594
126738
|
if (i > 0) await sleep11(SHAKE_INTERVAL_MS);
|
|
126595
126739
|
shaker.begin();
|
|
126596
126740
|
try {
|
|
126597
|
-
await
|
|
126741
|
+
await execFileAsync26("xcrun", args, { timeout: 15e3 });
|
|
126598
126742
|
} catch (err) {
|
|
126599
126743
|
const error52 = err instanceof Error ? err : new Error(String(err));
|
|
126600
126744
|
throw shakeFailure(udid, error52.message, error52);
|
|
@@ -126757,7 +126901,7 @@ var androidImpl6 = {
|
|
|
126757
126901
|
};
|
|
126758
126902
|
|
|
126759
126903
|
// ../tool-server/src/tools/shake/index.ts
|
|
126760
|
-
var
|
|
126904
|
+
var capability20 = {
|
|
126761
126905
|
// Simulator only: a physical iPhone's motion is real hardware, with no
|
|
126762
126906
|
// host-side hook to fake it.
|
|
126763
126907
|
apple: { simulator: true },
|
|
@@ -126791,13 +126935,13 @@ Works on local and remote (sim-remote) iOS simulators.
|
|
|
126791
126935
|
Only phone/tablet simulators and emulators are supported.`,
|
|
126792
126936
|
searchHint: "shake motion accelerometer undo typing dev menu gesture",
|
|
126793
126937
|
zodSchema: shakeZodSchema,
|
|
126794
|
-
capability:
|
|
126938
|
+
capability: capability20,
|
|
126795
126939
|
// No simulator-server is resolved: `simctl`/`adb` are called directly, so a
|
|
126796
126940
|
// tool that never uses one doesn't spawn it or wait for it to be ready.
|
|
126797
126941
|
services: () => ({}),
|
|
126798
126942
|
execute: dispatchByPlatform({
|
|
126799
126943
|
toolId: "shake",
|
|
126800
|
-
capability:
|
|
126944
|
+
capability: capability20,
|
|
126801
126945
|
ios: iosImpl4,
|
|
126802
126946
|
iosRemote: iosRemoteImpl6,
|
|
126803
126947
|
android: androidImpl6
|
|
@@ -126811,7 +126955,7 @@ init_device_info();
|
|
|
126811
126955
|
var POSTURES = ["closed", "half-open", "open"];
|
|
126812
126956
|
var POSTURE_ANGLE = { "closed": 0, "half-open": 120, "open": 180 };
|
|
126813
126957
|
var HINGE_REQUEST_TIMEOUT_MS = 3e4;
|
|
126814
|
-
var
|
|
126958
|
+
var zodSchema27 = external_exports.object({
|
|
126815
126959
|
udid: external_exports.string().describe("Target device id from `list-devices` (a foldable iOS simulator UDID)."),
|
|
126816
126960
|
posture: external_exports.enum(POSTURES).optional().describe(
|
|
126817
126961
|
"Where to move the hinge: `closed` (0\xB0, the cover panel), `half-open` (120\xB0) or `open` (180\xB0, the inner panel). Exactly one of `posture` and `angle`."
|
|
@@ -126822,7 +126966,7 @@ var zodSchema26 = external_exports.object({
|
|
|
126822
126966
|
}).refine((p) => p.posture === void 0 !== (p.angle === void 0), {
|
|
126823
126967
|
message: "Pass exactly one of `posture` and `angle`."
|
|
126824
126968
|
});
|
|
126825
|
-
var
|
|
126969
|
+
var capability21 = {
|
|
126826
126970
|
// Local simulators only. A remote (MoQ) simulator is driven on its main
|
|
126827
126971
|
// screen and carries no hinge message; the server itself rejects a device
|
|
126828
126972
|
// that is not foldable, with its own reason.
|
|
@@ -126891,8 +127035,8 @@ A fold between two angles that are not closed or open can keep the current panel
|
|
|
126891
127035
|
Returns { activeScreen, screen: { id, panel, width, height }, posture?, hingeAngle, warning? }. screen names the active panel and gives its size in pixels. posture is set only at 0\xB0, 120\xB0 and 180\xB0. warning is set when argent cannot find the active panel, or when the device did not change to the expected panel.
|
|
126892
127036
|
Fails if the device is not foldable or is a remote simulator.`,
|
|
126893
127037
|
searchHint: "fold unfold hinge foldable duo posture open closed half-open panel screen",
|
|
126894
|
-
zodSchema:
|
|
126895
|
-
capability:
|
|
127038
|
+
zodSchema: zodSchema27,
|
|
127039
|
+
capability: capability21,
|
|
126896
127040
|
services: (params) => ({
|
|
126897
127041
|
simulatorServer: simulatorServerRef(resolveDevice(params.udid))
|
|
126898
127042
|
}),
|
|
@@ -127044,14 +127188,14 @@ var buttonSchema = external_exports.preprocess(
|
|
|
127044
127188
|
).describe(
|
|
127045
127189
|
'A single TV-remote button, or a path of them run in one call. Buttons: up/down/left/right (D-pad), select (OK), back, home, menu, playPause, rewind, fastForward, next, previous, volumeUp, volumeDown, mute. The media-transport and volume keys work on Android TV and Vega; on the Apple TV simulator they are rejected (its HID stack ignores them) \u2014 the D-pad/select/back/menu/home/playPause core works on all three. For multi-step navigation pass an array, e.g. ["up","right","right","select"] \u2014 strongly prefer this over multiple `tv-remote` calls: the whole path runs in a single call.'
|
|
127046
127190
|
);
|
|
127047
|
-
var
|
|
127191
|
+
var zodSchema28 = external_exports.object({
|
|
127048
127192
|
udid: external_exports.string().describe("Target TV device id from `list-devices` (Apple TV, Android TV, or Vega)."),
|
|
127049
127193
|
button: buttonSchema,
|
|
127050
127194
|
repeat: external_exports.number().int().min(1).max(50).optional().describe(
|
|
127051
127195
|
'Repeat the whole `button` value this many times (default 1). Compact for long same-button runs, e.g. { button: "down", repeat: 12 }.'
|
|
127052
127196
|
)
|
|
127053
127197
|
});
|
|
127054
|
-
var
|
|
127198
|
+
var capability22 = {
|
|
127055
127199
|
apple: { simulator: true },
|
|
127056
127200
|
android: { emulator: true, device: true, unknown: true },
|
|
127057
127201
|
vega: { vvd: true }
|
|
@@ -127075,12 +127219,12 @@ Returns { pressed, count }.`,
|
|
|
127075
127219
|
// one round-trip at a time on the Apple/Android path — minutes of wall-clock.
|
|
127076
127220
|
longRunning: true,
|
|
127077
127221
|
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",
|
|
127078
|
-
zodSchema:
|
|
127079
|
-
capability:
|
|
127222
|
+
zodSchema: zodSchema28,
|
|
127223
|
+
capability: capability22,
|
|
127080
127224
|
services: () => ({}),
|
|
127081
127225
|
execute: dispatchByPlatform({
|
|
127082
127226
|
toolId: "tv-remote",
|
|
127083
|
-
capability:
|
|
127227
|
+
capability: capability22,
|
|
127084
127228
|
ios: makeIosImpl5(registry2),
|
|
127085
127229
|
android: makeAndroidImpl3(registry2),
|
|
127086
127230
|
vega: vegaImpl5
|
|
@@ -127121,9 +127265,9 @@ async function invokeSubTool(registry2, ctx, toolId, args, extra) {
|
|
|
127121
127265
|
}
|
|
127122
127266
|
function describeNestedParamError(registry2, err, toolId, dispatchedArgs, authoredArgs) {
|
|
127123
127267
|
if (getFailureSignal(err)?.error_code !== FAILURE_CODES.TOOL_INPUT_INVALID) return void 0;
|
|
127124
|
-
const
|
|
127125
|
-
if (!
|
|
127126
|
-
const parsed =
|
|
127268
|
+
const zodSchema81 = registry2.getTool(toolId)?.zodSchema;
|
|
127269
|
+
if (!zodSchema81) return void 0;
|
|
127270
|
+
const parsed = zodSchema81.safeParse(dispatchedArgs ?? {});
|
|
127127
127271
|
if (parsed.success) return void 0;
|
|
127128
127272
|
return `Invalid params for tool "${toolId}": ${describeParamIssues(parsed.error, authoredArgs)}`;
|
|
127129
127273
|
}
|
|
@@ -133417,7 +133561,7 @@ function unmetUiWaitCause(result) {
|
|
|
133417
133561
|
}
|
|
133418
133562
|
var DEFAULT_TIMEOUT_MS3 = 5e3;
|
|
133419
133563
|
var DEFAULT_POLL_INTERVAL_MS = 400;
|
|
133420
|
-
var
|
|
133564
|
+
var zodSchema29 = external_exports.object({
|
|
133421
133565
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
|
|
133422
133566
|
condition: external_exports.enum(["exists", "visible", "hidden", "text"]).describe(
|
|
133423
133567
|
"What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first visible match in reading order (topmost), falling back to the first match overall if none is visible, contains (or, with textMatch `equals`, exactly matches) expectedText \u2014 if a loose selector hits several elements, only that one is checked, so narrow it to target the intended element."
|
|
@@ -133436,7 +133580,7 @@ var zodSchema28 = external_exports.object({
|
|
|
133436
133580
|
`Max time to wait for the condition before giving up (default ${DEFAULT_TIMEOUT_MS3}).`
|
|
133437
133581
|
),
|
|
133438
133582
|
pollIntervalMs: external_exports.number().int().min(50).max(5e3).optional().describe(`How often to re-check the tree (default ${DEFAULT_POLL_INTERVAL_MS}).`)
|
|
133439
|
-
}).refine((p) => p.condition !== "text" || p.expectedText !== void 0, {
|
|
133583
|
+
}).strict().refine((p) => p.condition !== "text" || p.expectedText !== void 0, {
|
|
133440
133584
|
message: "condition `text` requires expectedText",
|
|
133441
133585
|
path: ["expectedText"]
|
|
133442
133586
|
});
|
|
@@ -133465,7 +133609,7 @@ function timeoutCause(condition, lastTrustedReadAt, finalRead, pollIntervalMs) {
|
|
|
133465
133609
|
);
|
|
133466
133610
|
return darkTailMs > tolerance ? "unreadable" : "unmet";
|
|
133467
133611
|
}
|
|
133468
|
-
var
|
|
133612
|
+
var capability23 = {
|
|
133469
133613
|
apple: { simulator: true, device: true },
|
|
133470
133614
|
appleRemote: { simulator: true },
|
|
133471
133615
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -133559,8 +133703,8 @@ tap/navigation to wait for the next screen, or before tapping an element that ap
|
|
|
133559
133703
|
alwaysLoad: true,
|
|
133560
133704
|
searchHint: "wait await poll until visible hidden exists text appears disappears timeout element condition settle",
|
|
133561
133705
|
longRunning: true,
|
|
133562
|
-
zodSchema:
|
|
133563
|
-
capability:
|
|
133706
|
+
zodSchema: zodSchema29,
|
|
133707
|
+
capability: capability23,
|
|
133564
133708
|
services: (params) => {
|
|
133565
133709
|
const device = resolveDevice(params.udid);
|
|
133566
133710
|
if (device.platform === "chromium") {
|
|
@@ -133571,7 +133715,7 @@ tap/navigation to wait for the next screen, or before tapping an element that ap
|
|
|
133571
133715
|
async execute(services, params, ctx) {
|
|
133572
133716
|
const signal = ctx?.signal;
|
|
133573
133717
|
const device = resolveDevice(params.udid);
|
|
133574
|
-
assertSupported(AWAIT_UI_ELEMENT_TOOL_ID,
|
|
133718
|
+
assertSupported(AWAIT_UI_ELEMENT_TOOL_ID, capability23, device);
|
|
133575
133719
|
if (device.platform === "ios") await ensureDeps(iosRequires);
|
|
133576
133720
|
else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
|
|
133577
133721
|
else if (device.platform === "android") await ensureDeps(androidRequires);
|
|
@@ -133648,7 +133792,7 @@ var ALLOWED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
133648
133792
|
"tv-remote",
|
|
133649
133793
|
AWAIT_UI_ELEMENT_TOOL_ID
|
|
133650
133794
|
]);
|
|
133651
|
-
var
|
|
133795
|
+
var zodSchema30 = external_exports.object({
|
|
133652
133796
|
udid: external_exports.string().describe(
|
|
133653
133797
|
"Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id) \u2014 shared across all steps."
|
|
133654
133798
|
),
|
|
@@ -133664,7 +133808,7 @@ var zodSchema29 = external_exports.object({
|
|
|
133664
133808
|
})
|
|
133665
133809
|
).min(1).describe("Ordered list of interaction steps to execute sequentially")
|
|
133666
133810
|
});
|
|
133667
|
-
var
|
|
133811
|
+
var capability24 = {
|
|
133668
133812
|
// Physical iOS is a valid outer target. Unsupported steps fail at their own gate, not the whole sequence.
|
|
133669
133813
|
apple: { simulator: true, device: true },
|
|
133670
133814
|
appleRemote: { simulator: true },
|
|
@@ -133746,8 +133890,8 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
|
|
|
133746
133890
|
alwaysLoad: true,
|
|
133747
133891
|
longRunning: true,
|
|
133748
133892
|
searchHint: "batch sequence multiple gesture steps sequentially",
|
|
133749
|
-
zodSchema:
|
|
133750
|
-
capability:
|
|
133893
|
+
zodSchema: zodSchema30,
|
|
133894
|
+
capability: capability24,
|
|
133751
133895
|
// Each step resolves its own services. An eager resolver can't be used
|
|
133752
133896
|
// because a tvOS udid shape-classifies as `ios` (there is no `tvos`
|
|
133753
133897
|
// platform), so declaring simulator-server would spawn a controller it
|
|
@@ -133844,7 +133988,7 @@ function debuggerServiceRef(params) {
|
|
|
133844
133988
|
}
|
|
133845
133989
|
|
|
133846
133990
|
// ../tool-server/src/tools/debugger/debugger-connect.ts
|
|
133847
|
-
var
|
|
133991
|
+
var zodSchema31 = external_exports.object({
|
|
133848
133992
|
port: metroPortField,
|
|
133849
133993
|
device_id: external_exports.string().describe(
|
|
133850
133994
|
"Device id from list-devices: iOS simulator UDID, Android serial, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>). Pass this SAME id as device_id to every subsequent debugger-* call to pin them to this device. The returned logicalDeviceId is informational (Metro's own per-connection handle, absent on Vega); you do not switch to it \u2014 forwarding it still resolves here, but the list-devices id is the stable one."
|
|
@@ -133859,20 +134003,19 @@ var debuggerConnectTool = {
|
|
|
133859
134003
|
},
|
|
133860
134004
|
description: `Connect to a JS runtime CDP debugger.
|
|
133861
134005
|
iOS / Android / Vega: connects to Metro's CDP endpoint on the given port. Chromium: re-uses the page CDP session opened by boot-device \u2014 port is ignored.
|
|
133862
|
-
Returns connection info including port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), and isNewDebugger. If already connected, returns the existing connection.
|
|
134006
|
+
Returns connection info including port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), and isNewDebugger, plus a note naming the kept log file when the previous session ended because the app crashed. If already connected, returns the existing connection.
|
|
133863
134007
|
Use when starting a debug session or before calling other debugger-* tools. Fails if the runtime is unreachable (Metro down, or Chromium CDP terminated).`,
|
|
133864
|
-
zodSchema:
|
|
134008
|
+
zodSchema: zodSchema31,
|
|
133865
134009
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
133866
134010
|
services: (params) => ({
|
|
133867
134011
|
debugger: debuggerServiceRef(params)
|
|
133868
134012
|
}),
|
|
133869
134013
|
async execute(services, params) {
|
|
133870
134014
|
const api = services.debugger;
|
|
133871
|
-
|
|
133872
|
-
|
|
133873
|
-
|
|
133874
|
-
|
|
133875
|
-
}
|
|
134015
|
+
const reaped2 = takeReapedSessionAnyId("js-runtime-debugger", [
|
|
134016
|
+
params.device_id,
|
|
134017
|
+
api.logicalDeviceId
|
|
134018
|
+
]);
|
|
133876
134019
|
return {
|
|
133877
134020
|
port: api.port,
|
|
133878
134021
|
projectRoot: api.projectRoot,
|
|
@@ -133880,7 +134023,8 @@ Use when starting a debug session or before calling other debugger-* tools. Fail
|
|
|
133880
134023
|
appName: api.appName,
|
|
133881
134024
|
logicalDeviceId: api.logicalDeviceId,
|
|
133882
134025
|
isNewDebugger: api.isNewDebugger,
|
|
133883
|
-
connected: api.cdp.isConnected()
|
|
134026
|
+
connected: api.cdp.isConnected(),
|
|
134027
|
+
...reaped2?.connectionLost ? { note: describeReapedSession(reaped2, "previous JS-runtime debugger session") } : {}
|
|
133884
134028
|
};
|
|
133885
134029
|
}
|
|
133886
134030
|
};
|
|
@@ -133967,7 +134111,7 @@ function isDebuggerNotConnectedResult(toolId, result) {
|
|
|
133967
134111
|
}
|
|
133968
134112
|
|
|
133969
134113
|
// ../tool-server/src/tools/debugger/debugger-status.ts
|
|
133970
|
-
var
|
|
134114
|
+
var zodSchema32 = external_exports.object({
|
|
133971
134115
|
port: metroPortField,
|
|
133972
134116
|
device_id: external_exports.string().describe(
|
|
133973
134117
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
|
|
@@ -133985,7 +134129,7 @@ function createDebuggerStatusTool(registry2) {
|
|
|
133985
134129
|
Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable \u2014 it returns a discriminated result instead:
|
|
133986
134130
|
- { status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true \u2014 waits for pending source maps before returning; no-op on Chromium).
|
|
133987
134131
|
- { status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field \u2014 do not retry in a loop.`,
|
|
133988
|
-
zodSchema:
|
|
134132
|
+
zodSchema: zodSchema32,
|
|
133989
134133
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
133990
134134
|
// Resolved manually in execute so a not-connected precondition becomes a
|
|
133991
134135
|
// structured result instead of a tool failure.
|
|
@@ -134042,7 +134186,7 @@ Use when you need to verify connectivity before using other debugger tools. Neve
|
|
|
134042
134186
|
// ../tool-server/src/tools/debugger/debugger-evaluate.ts
|
|
134043
134187
|
init_zod();
|
|
134044
134188
|
init_src2();
|
|
134045
|
-
var
|
|
134189
|
+
var zodSchema33 = external_exports.object({
|
|
134046
134190
|
port: metroPortField,
|
|
134047
134191
|
device_id: external_exports.string().describe(
|
|
134048
134192
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
|
|
@@ -134058,7 +134202,7 @@ var debuggerEvaluateTool = {
|
|
|
134058
134202
|
},
|
|
134059
134203
|
description: `Execute arbitrary JavaScript in the app's JS runtime via CDP \u2014 Hermes on iOS / Android / Vega, V8 on Chromium.
|
|
134060
134204
|
Returns the evaluation result as a JSON-serializable value, along with deviceName, appName, and logicalDeviceId for context. Use when you need to read app state, call app functions, or test logic at runtime. The result is serialized by value, so cyclic objects (many RN runtime values \u2014 fiber nodes, navigation refs, global \u2014 are cyclic) fail with a serialization error rather than returning silently. Fails if the expression throws or the runtime is not connected.`,
|
|
134061
|
-
zodSchema:
|
|
134205
|
+
zodSchema: zodSchema33,
|
|
134062
134206
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
134063
134207
|
services: (params) => ({
|
|
134064
134208
|
debugger: debuggerServiceRef(params)
|
|
@@ -134095,7 +134239,7 @@ Returns the evaluation result as a JSON-serializable value, along with deviceNam
|
|
|
134095
134239
|
// ../tool-server/src/tools/debugger/debugger-reload-metro.ts
|
|
134096
134240
|
init_zod();
|
|
134097
134241
|
init_src2();
|
|
134098
|
-
var
|
|
134242
|
+
var zodSchema34 = external_exports.object({
|
|
134099
134243
|
port: metroPortField,
|
|
134100
134244
|
device_id: external_exports.string().describe(
|
|
134101
134245
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -134110,7 +134254,7 @@ var debuggerReloadMetroTool = {
|
|
|
134110
134254
|
},
|
|
134111
134255
|
description: `Restart the Metro JS bundle in the connected React Native app without restarting the native process.
|
|
134112
134256
|
Use when you want to apply code changes or reset JS state. Returns { reloaded, port, method, deviceName, appName, logicalDeviceId } indicating which reload path was used and which device/app was targeted. Fails if Metro is not running on the given port.`,
|
|
134113
|
-
zodSchema:
|
|
134257
|
+
zodSchema: zodSchema34,
|
|
134114
134258
|
// RN-only: reloading a Chromium page is a different operation from restarting
|
|
134115
134259
|
// the Metro bundle, so it would need its own tool.
|
|
134116
134260
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -135047,7 +135191,7 @@ async function readTapAxes(registry2, app) {
|
|
|
135047
135191
|
clearTimeout(timer);
|
|
135048
135192
|
}
|
|
135049
135193
|
}
|
|
135050
|
-
var
|
|
135194
|
+
var zodSchema35 = external_exports.object({
|
|
135051
135195
|
port: metroPortField,
|
|
135052
135196
|
device_id: external_exports.string().describe(
|
|
135053
135197
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -135096,7 +135240,7 @@ Set includeSkipped=true to see a summary of all filtered components.
|
|
|
135096
135240
|
Use when you need tap coordinates for a React Native UI element. Returns a compact text tree with (tap: x,y) coords. Fails if Metro debugger is not connected.`,
|
|
135097
135241
|
alwaysLoad: true,
|
|
135098
135242
|
searchHint: "react native component tree discovery tap coordinates",
|
|
135099
|
-
zodSchema:
|
|
135243
|
+
zodSchema: zodSchema35,
|
|
135100
135244
|
// RN-only: needs the React DevTools backend from the dev JS bundle. Chromium has
|
|
135101
135245
|
// no equivalent — use `describe` there.
|
|
135102
135246
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -135574,7 +135718,7 @@ function filterInspectItems(items, includeSkipped = false) {
|
|
|
135574
135718
|
}
|
|
135575
135719
|
return result;
|
|
135576
135720
|
}
|
|
135577
|
-
var
|
|
135721
|
+
var zodSchema36 = external_exports.object({
|
|
135578
135722
|
port: metroPortField,
|
|
135579
135723
|
device_id: external_exports.string().describe(
|
|
135580
135724
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -135612,7 +135756,7 @@ Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate.
|
|
|
135612
135756
|
Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead.
|
|
135613
135757
|
Set includeSkipped=true to see filtered items annotated with skip reasons.
|
|
135614
135758
|
Use when you need the source file and line for a component at a tap coordinate. Fails if the app is not connected or the coordinate is outside the screen.`,
|
|
135615
|
-
zodSchema:
|
|
135759
|
+
zodSchema: zodSchema36,
|
|
135616
135760
|
// RN-only: needs React Native's internal getInspectorDataForViewAtPoint and
|
|
135617
135761
|
// Metro's /symbolicate; the Chromium session has no source resolver.
|
|
135618
135762
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -135711,7 +135855,7 @@ Use when you need the source file and line for a component at a tap coordinate.
|
|
|
135711
135855
|
|
|
135712
135856
|
// ../tool-server/src/tools/debugger/debugger-log-registry.ts
|
|
135713
135857
|
init_zod();
|
|
135714
|
-
var
|
|
135858
|
+
var zodSchema37 = external_exports.object({
|
|
135715
135859
|
port: metroPortField,
|
|
135716
135860
|
device_id: external_exports.string().describe(
|
|
135717
135861
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
|
|
@@ -135727,9 +135871,9 @@ function createDebuggerLogRegistryTool(registry2) {
|
|
|
135727
135871
|
},
|
|
135728
135872
|
description: `Get a summary of all console logs captured from the app's JS runtime.
|
|
135729
135873
|
Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium).
|
|
135730
|
-
Use when investigating warnings, errors, or unexpected output \u2014 call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet \u2014 but check { note }, which is present only when the stats are empty BECAUSE
|
|
135731
|
-
When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file \u2014 follow the guidance (do not retry in a loop
|
|
135732
|
-
zodSchema:
|
|
135874
|
+
Use when investigating warnings, errors, or unexpected output \u2014 call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet \u2014 but check { note }, which is present only when the stats are empty BECAUSE the previous debugger session ended: torn down (e.g. by stop-all-simulator-servers) with its log file deleted, or cut off by the app crashing with its log file kept at the path the note names. Absent that note, empty really does mean the app has logged nothing.
|
|
135875
|
+
When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file \u2014 follow the guidance (do not retry in a loop). Read a log file in this state only when a { note } names one kept from before the app crashed. A "connected" result's stats may come from a session whose socket has since died \u2014 use debugger-status, not this tool, to judge debugger health.`,
|
|
135876
|
+
zodSchema: zodSchema37,
|
|
135733
135877
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
135734
135878
|
// Resolved manually in execute so a not-connected precondition becomes a
|
|
135735
135879
|
// structured result instead of a service-resolution tool failure.
|
|
@@ -135749,16 +135893,11 @@ When the debugger cannot be reached, this tool does not fail: it returns { statu
|
|
|
135749
135893
|
logicalDeviceId: api.logicalDeviceId
|
|
135750
135894
|
};
|
|
135751
135895
|
if (stats.totalEntries === 0) {
|
|
135752
|
-
const
|
|
135896
|
+
const reaped2 = takeReapedSessionAnyId("js-runtime-debugger", [
|
|
135753
135897
|
canonicalDeviceId(params.device_id),
|
|
135754
135898
|
params.device_id,
|
|
135755
135899
|
api.logicalDeviceId
|
|
135756
|
-
]
|
|
135757
|
-
let reaped2;
|
|
135758
|
-
for (const id of new Set(aliases)) {
|
|
135759
|
-
const entry = takeReapedSession("js-runtime-debugger", id);
|
|
135760
|
-
reaped2 ??= entry;
|
|
135761
|
-
}
|
|
135900
|
+
]);
|
|
135762
135901
|
if (reaped2) response.note = describeReapedSession(reaped2, "JS-runtime debugger session");
|
|
135763
135902
|
}
|
|
135764
135903
|
return response;
|
|
@@ -135766,7 +135905,17 @@ When the debugger cannot be reached, this tool does not fail: it returns { statu
|
|
|
135766
135905
|
const reason = classifyNotConnected(err);
|
|
135767
135906
|
if (!reason) throw err;
|
|
135768
135907
|
trackDebuggerOutcome("debugger-log-registry", reason, params, ctx);
|
|
135769
|
-
|
|
135908
|
+
const result = buildNotConnected(
|
|
135909
|
+
reason,
|
|
135910
|
+
err,
|
|
135911
|
+
params
|
|
135912
|
+
);
|
|
135913
|
+
const reaped2 = takeReapedSessionAnyId("js-runtime-debugger", [
|
|
135914
|
+
canonicalDeviceId(params.device_id),
|
|
135915
|
+
params.device_id
|
|
135916
|
+
]);
|
|
135917
|
+
if (reaped2) result.note = describeReapedSession(reaped2, "JS-runtime debugger session");
|
|
135918
|
+
return result;
|
|
135770
135919
|
}
|
|
135771
135920
|
}
|
|
135772
135921
|
};
|
|
@@ -135832,7 +135981,7 @@ function renderChromiumPage(records, pageIndexParam) {
|
|
|
135832
135981
|
|
|
135833
135982
|
${lines.join("\n")}`;
|
|
135834
135983
|
}
|
|
135835
|
-
var
|
|
135984
|
+
var zodSchema38 = external_exports.object({
|
|
135836
135985
|
port: metroPortField,
|
|
135837
135986
|
device_id: external_exports.string().describe(
|
|
135838
135987
|
"Device id from list-devices (iOS simulator UDID or Android serial) \u2014 the same id used with debugger-connect."
|
|
@@ -135854,7 +136003,7 @@ Each entry includes a requestId that can be passed to view-network-request-detai
|
|
|
135854
136003
|
On React Native (iOS / Android / Vega) interception is injected into the JS runtime \u2014 it captures fetch() calls. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types).
|
|
135855
136004
|
Use when inspecting outbound HTTP traffic or debugging API calls in the running app.
|
|
135856
136005
|
Fails if the app is not connected (RN) or the device is not reachable (Chromium).`,
|
|
135857
|
-
zodSchema:
|
|
136006
|
+
zodSchema: zodSchema38,
|
|
135858
136007
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
135859
136008
|
services: (params) => {
|
|
135860
136009
|
const device = resolveDevice(params.device_id);
|
|
@@ -135926,7 +136075,7 @@ function redactHeaders(headers) {
|
|
|
135926
136075
|
return result;
|
|
135927
136076
|
}
|
|
135928
136077
|
var MAX_BODY_SIZE = 1e3;
|
|
135929
|
-
var
|
|
136078
|
+
var zodSchema39 = external_exports.object({
|
|
135930
136079
|
port: metroPortField,
|
|
135931
136080
|
device_id: external_exports.string().describe(
|
|
135932
136081
|
"Device id from list-devices (iOS simulator UDID or Android serial) \u2014 the same id used with debugger-connect."
|
|
@@ -135945,7 +136094,7 @@ var networkRequestTool = {
|
|
|
135945
136094
|
Returns request/response headers (sensitive headers redacted), status, timing, and optionally the response body.
|
|
135946
136095
|
Large response bodies are truncated. Use when you need headers, body, or timing for a specific request after listing logs.
|
|
135947
136096
|
Returns an error message string if the requestId is not found \u2014 use view-network-logs to get valid requestId values.`,
|
|
135948
|
-
zodSchema:
|
|
136097
|
+
zodSchema: zodSchema39,
|
|
135949
136098
|
capability: DEBUGGER_TOOL_CAPABILITY,
|
|
135950
136099
|
services: (params) => {
|
|
135951
136100
|
const device = resolveDevice(params.device_id);
|
|
@@ -136260,7 +136409,7 @@ function withDescription(data) {
|
|
|
136260
136409
|
if (data.hint) out.hint = data.hint;
|
|
136261
136410
|
return out;
|
|
136262
136411
|
}
|
|
136263
|
-
var
|
|
136412
|
+
var zodSchema40 = external_exports.object({
|
|
136264
136413
|
udid: external_exports.string().min(1).describe(
|
|
136265
136414
|
"Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id)."
|
|
136266
136415
|
),
|
|
@@ -136268,7 +136417,7 @@ var zodSchema39 = external_exports.object({
|
|
|
136268
136417
|
"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, and on a physical iOS device."
|
|
136269
136418
|
)
|
|
136270
136419
|
});
|
|
136271
|
-
var
|
|
136420
|
+
var capability25 = {
|
|
136272
136421
|
apple: { simulator: true, device: true },
|
|
136273
136422
|
appleRemote: { simulator: true },
|
|
136274
136423
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -136278,7 +136427,7 @@ var capability24 = {
|
|
|
136278
136427
|
function makeDescribeExecute(registry2) {
|
|
136279
136428
|
return dispatchByPlatform({
|
|
136280
136429
|
toolId: "describe",
|
|
136281
|
-
capability:
|
|
136430
|
+
capability: capability25,
|
|
136282
136431
|
ios: {
|
|
136283
136432
|
requires: iosRequires,
|
|
136284
136433
|
handler: async (_services, params, device) => (
|
|
@@ -136368,8 +136517,8 @@ since a TV UI has no tap coordinates. Move the highlight with \`tv-remote\` (up/
|
|
|
136368
136517
|
back/menu/home), then call describe again to confirm where focus landed.`,
|
|
136369
136518
|
alwaysLoad: true,
|
|
136370
136519
|
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",
|
|
136371
|
-
zodSchema:
|
|
136372
|
-
capability:
|
|
136520
|
+
zodSchema: zodSchema40,
|
|
136521
|
+
capability: capability25,
|
|
136373
136522
|
services: (params) => {
|
|
136374
136523
|
const device = resolveDevice(params.udid);
|
|
136375
136524
|
if (device.platform === "chromium") {
|
|
@@ -136846,10 +136995,10 @@ async function readAndroidUiTree(registry2, device) {
|
|
|
136846
136995
|
}
|
|
136847
136996
|
|
|
136848
136997
|
// ../tool-server/src/tools/ui-tree/index.ts
|
|
136849
|
-
var
|
|
136998
|
+
var zodSchema41 = external_exports.object({
|
|
136850
136999
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices`.")
|
|
136851
137000
|
});
|
|
136852
|
-
var
|
|
137001
|
+
var capability26 = {
|
|
136853
137002
|
apple: { simulator: true },
|
|
136854
137003
|
appleRemote: { simulator: true },
|
|
136855
137004
|
android: { emulator: true, device: true, unknown: true }
|
|
@@ -136867,12 +137016,12 @@ Use when a program needs element ancestry, such as an e2e engine's scoped select
|
|
|
136867
137016
|
Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, foregroundApp, unsupportedFields }.
|
|
136868
137017
|
Fails if the iOS ax-service predates the tree command; update argent.`,
|
|
136869
137018
|
hideFromMcp: true,
|
|
136870
|
-
zodSchema:
|
|
136871
|
-
capability:
|
|
137019
|
+
zodSchema: zodSchema41,
|
|
137020
|
+
capability: capability26,
|
|
136872
137021
|
services: () => ({}),
|
|
136873
137022
|
execute: dispatchByPlatform({
|
|
136874
137023
|
toolId: "ui-tree",
|
|
136875
|
-
capability:
|
|
137024
|
+
capability: capability26,
|
|
136876
137025
|
ios: {
|
|
136877
137026
|
requires: iosRequires,
|
|
136878
137027
|
handler: async (_services, _params, device) => {
|
|
@@ -136896,6 +137045,73 @@ Fails if the iOS ax-service predates the tree command; update argent.`,
|
|
|
136896
137045
|
};
|
|
136897
137046
|
}
|
|
136898
137047
|
|
|
137048
|
+
// ../tool-server/src/tools/foreground-app/index.ts
|
|
137049
|
+
init_zod();
|
|
137050
|
+
var zodSchema42 = external_exports.object({
|
|
137051
|
+
udid: external_exports.string().min(1).describe("Target device id from `list-devices`.")
|
|
137052
|
+
});
|
|
137053
|
+
var capability27 = {
|
|
137054
|
+
apple: { simulator: true },
|
|
137055
|
+
appleRemote: { simulator: true },
|
|
137056
|
+
android: { emulator: true, device: true, unknown: true }
|
|
137057
|
+
};
|
|
137058
|
+
async function readIosForegroundApp(registry2, device) {
|
|
137059
|
+
const ref = axServiceRef(device);
|
|
137060
|
+
const ax = await registry2.resolveService(ref.urn, ref.options);
|
|
137061
|
+
const { bundleId, name, alertVisible } = await ax.foregroundApp();
|
|
137062
|
+
return { bundleId, name, alertVisible };
|
|
137063
|
+
}
|
|
137064
|
+
async function readAndroidForegroundApp(registry2, device) {
|
|
137065
|
+
const ref = androidDevtoolsRef(device);
|
|
137066
|
+
const devtools = await registry2.resolveService(ref.urn, ref.options);
|
|
137067
|
+
const [capture, size] = await Promise.all([
|
|
137068
|
+
// The default settle, as ui-tree: free on a settled screen, and it keeps a
|
|
137069
|
+
// mid-transition window list (right after home or a launch) from naming the old app.
|
|
137070
|
+
devtools.getHierarchy({ maxDepth: 0, clearCache: true }),
|
|
137071
|
+
devtools.getScreenSize()
|
|
137072
|
+
]);
|
|
137073
|
+
const tree = adaptAndroidTree({ ...capture, truncated: false }, size);
|
|
137074
|
+
return { bundleId: tree.foregroundApp, alertVisible: tree.alertVisible };
|
|
137075
|
+
}
|
|
137076
|
+
function createForegroundAppTool(registry2) {
|
|
137077
|
+
return {
|
|
137078
|
+
id: "foreground-app",
|
|
137079
|
+
interaction: {
|
|
137080
|
+
startedMsg: () => "Reading foreground app",
|
|
137081
|
+
completedMsg: () => "Read foreground app",
|
|
137082
|
+
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read foreground app: ${failureSignal2.error_code}`
|
|
137083
|
+
},
|
|
137084
|
+
description: `Read which app is in front, for SDK callers.
|
|
137085
|
+
Returns { bundleId, name, alertVisible }; under a system alert, bundleId is the app it covers.
|
|
137086
|
+
A field is unset when it is unknown.`,
|
|
137087
|
+
hideFromMcp: true,
|
|
137088
|
+
zodSchema: zodSchema42,
|
|
137089
|
+
capability: capability27,
|
|
137090
|
+
services: () => ({}),
|
|
137091
|
+
execute: dispatchByPlatform({
|
|
137092
|
+
toolId: "foreground-app",
|
|
137093
|
+
capability: capability27,
|
|
137094
|
+
ios: {
|
|
137095
|
+
requires: iosRequires,
|
|
137096
|
+
handler: async (_services, _params, device) => {
|
|
137097
|
+
if (await isTvOsSimulator(device.id)) {
|
|
137098
|
+
throw new UnsupportedOperationError("foreground-app", device, "tvOS");
|
|
137099
|
+
}
|
|
137100
|
+
return readIosForegroundApp(registry2, device);
|
|
137101
|
+
}
|
|
137102
|
+
},
|
|
137103
|
+
iosRemote: {
|
|
137104
|
+
requires: ["sim-remote"],
|
|
137105
|
+
handler: async (_services, _params, device) => readIosForegroundApp(registry2, device)
|
|
137106
|
+
},
|
|
137107
|
+
android: {
|
|
137108
|
+
requires: androidRequires,
|
|
137109
|
+
handler: async (_services, _params, device) => readAndroidForegroundApp(registry2, device)
|
|
137110
|
+
}
|
|
137111
|
+
})
|
|
137112
|
+
};
|
|
137113
|
+
}
|
|
137114
|
+
|
|
136899
137115
|
// ../tool-server/src/tools/await-screen-idle/index.ts
|
|
136900
137116
|
init_zod();
|
|
136901
137117
|
init_device_info();
|
|
@@ -136904,7 +137120,7 @@ var AWAIT_SCREEN_IDLE_TOOL_ID = "await-screen-idle";
|
|
|
136904
137120
|
var DEFAULT_TIMEOUT_MS4 = 3e3;
|
|
136905
137121
|
var DEFAULT_POLL_INTERVAL_MS2 = 200;
|
|
136906
137122
|
var DEFAULT_MIN_STABLE_MS = 250;
|
|
136907
|
-
var
|
|
137123
|
+
var zodSchema43 = external_exports.object({
|
|
136908
137124
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
|
|
136909
137125
|
timeoutMs: external_exports.number().int().positive().max(12e4).optional().describe(
|
|
136910
137126
|
`Max time to wait for the screen to settle before giving up (default ${DEFAULT_TIMEOUT_MS4}).`
|
|
@@ -136913,8 +137129,8 @@ var zodSchema41 = external_exports.object({
|
|
|
136913
137129
|
minStableMs: external_exports.number().int().min(0).max(1e4).optional().describe(
|
|
136914
137130
|
`The screen must hold the same content for at least this long to count as settled (default ${DEFAULT_MIN_STABLE_MS}).`
|
|
136915
137131
|
)
|
|
136916
|
-
});
|
|
136917
|
-
var
|
|
137132
|
+
}).strict();
|
|
137133
|
+
var capability28 = {
|
|
136918
137134
|
apple: { simulator: true, device: true },
|
|
136919
137135
|
appleRemote: { simulator: true },
|
|
136920
137136
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -136961,8 +137177,8 @@ ${DEFAULT_TIMEOUT_MS4}ms) is reached. Returns { settled, waitedMs, polls } \u201
|
|
|
136961
137177
|
still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
|
|
136962
137178
|
searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
|
|
136963
137179
|
longRunning: true,
|
|
136964
|
-
zodSchema:
|
|
136965
|
-
capability:
|
|
137180
|
+
zodSchema: zodSchema43,
|
|
137181
|
+
capability: capability28,
|
|
136966
137182
|
services: (params) => {
|
|
136967
137183
|
const device = resolveDevice(params.udid);
|
|
136968
137184
|
if (device.platform === "chromium") {
|
|
@@ -136972,7 +137188,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
|
|
|
136972
137188
|
},
|
|
136973
137189
|
async execute(services, params, ctx) {
|
|
136974
137190
|
const device = resolveDevice(params.udid);
|
|
136975
|
-
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID,
|
|
137191
|
+
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability28, device);
|
|
136976
137192
|
if (device.platform === "ios") await ensureDeps(iosRequires);
|
|
136977
137193
|
else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
|
|
136978
137194
|
else if (device.platform === "android") await ensureDeps(androidRequires);
|
|
@@ -137059,7 +137275,7 @@ function bootstrapFailureMessage(bootstrap) {
|
|
|
137059
137275
|
// ../tool-server/src/tools/profiler/react/react-profiler-start.ts
|
|
137060
137276
|
var NO_DEVTOOLS_HOOK_ERROR = "React DevTools hook (__REACT_DEVTOOLS_GLOBAL_HOOK__) is not present in this app's JavaScript runtime. React profiling requires a development build with React DevTools enabled. Likely causes: (1) the app is a release/production build \u2014 DevTools is stripped to reduce bundle size; (2) you connected to the wrong JS runtime; (3) this isn't a React (Native) app. Fix: rebuild in debug/dev mode (e.g. `npx react-native run-ios` without --configuration Release; for Expo, run a dev client). Once the app is running with DevTools attached, call react-profiler-start again.";
|
|
137061
137277
|
var NO_RENDERERS_ATTACHED_ERROR = "React DevTools hook is present but no React renderer has registered yet. The hook is loaded but no fiber renderer has attached \u2014 typically because the app has not committed its first render, or the DevTools backend has not been bootstrapped on a bridgeless React Native dev build. Fix: ensure the app has rendered (interact with it once, then retry); if it stays empty, call react-profiler-start first \u2014 it will attempt to attach the DevTools backend automatically.";
|
|
137062
|
-
var
|
|
137278
|
+
var zodSchema44 = external_exports.object({
|
|
137063
137279
|
port: metroPortField,
|
|
137064
137280
|
device_id: external_exports.string().describe(
|
|
137065
137281
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -137091,7 +137307,7 @@ Before calling this, ask the user if they also want native profiling (native-pro
|
|
|
137091
137307
|
After starting, ask the user to perform the interaction to profile, then call react-profiler-stop.
|
|
137092
137308
|
Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above.
|
|
137093
137309
|
Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.`,
|
|
137094
|
-
zodSchema:
|
|
137310
|
+
zodSchema: zodSchema44,
|
|
137095
137311
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
137096
137312
|
services: () => ({}),
|
|
137097
137313
|
async execute(_services, params) {
|
|
@@ -137362,7 +137578,7 @@ async function readCommitTree(path53) {
|
|
|
137362
137578
|
}
|
|
137363
137579
|
|
|
137364
137580
|
// ../tool-server/src/tools/profiler/react/react-profiler-stop.ts
|
|
137365
|
-
var
|
|
137581
|
+
var zodSchema45 = external_exports.object({
|
|
137366
137582
|
port: metroPortField,
|
|
137367
137583
|
device_id: external_exports.string().describe(
|
|
137368
137584
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -137451,7 +137667,7 @@ Call react-profiler-start first, then exercise the app, then call this.
|
|
|
137451
137667
|
Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session.
|
|
137452
137668
|
When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count } \u2014 these quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct).
|
|
137453
137669
|
Fails if no active profiling session exists or the CDP connection was lost during recording.`,
|
|
137454
|
-
zodSchema:
|
|
137670
|
+
zodSchema: zodSchema45,
|
|
137455
137671
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
137456
137672
|
services: () => ({}),
|
|
137457
137673
|
async execute(_services, params) {
|
|
@@ -137676,7 +137892,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
|
|
|
137676
137892
|
|
|
137677
137893
|
// ../tool-server/src/tools/profiler/react/react-profiler-status.ts
|
|
137678
137894
|
init_zod();
|
|
137679
|
-
var
|
|
137895
|
+
var zodSchema46 = external_exports.object({
|
|
137680
137896
|
port: metroPortField,
|
|
137681
137897
|
device_id: external_exports.string().describe(
|
|
137682
137898
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -137691,7 +137907,7 @@ function createReactProfilerStatusTool(registry2) {
|
|
|
137691
137907
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
|
|
137692
137908
|
},
|
|
137693
137909
|
description: `Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session \u2014 no token-threading is required. Returns { session_status, is_running, current_owner, \u2026 }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.`,
|
|
137694
|
-
zodSchema:
|
|
137910
|
+
zodSchema: zodSchema46,
|
|
137695
137911
|
// RN-only: companion to react-profiler-start.
|
|
137696
137912
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
137697
137913
|
services: () => ({}),
|
|
@@ -139305,7 +139521,7 @@ var annotationSchema = external_exports.object({
|
|
|
139305
139521
|
),
|
|
139306
139522
|
label: external_exports.string().describe("Description of the action performed")
|
|
139307
139523
|
});
|
|
139308
|
-
var
|
|
139524
|
+
var zodSchema47 = external_exports.object({
|
|
139309
139525
|
port: metroPortField,
|
|
139310
139526
|
device_id: external_exports.string().describe(
|
|
139311
139527
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -139338,7 +139554,7 @@ where tapTimestampMs is the timestampMs returned by the tap/swipe tool and start
|
|
|
139338
139554
|
is returned by react-profiler-start.
|
|
139339
139555
|
Use when the profiling session is complete and you need to interpret the collected data.
|
|
139340
139556
|
Fails if react-profiler-stop has not been called or no profiling data is stored.`,
|
|
139341
|
-
zodSchema:
|
|
139557
|
+
zodSchema: zodSchema47,
|
|
139342
139558
|
// RN-only: reads commit data captured via the React DevTools backend, which
|
|
139343
139559
|
// Chromium does not have.
|
|
139344
139560
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -139475,7 +139691,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
|
|
|
139475
139691
|
// ../tool-server/src/tools/profiler/react/react-profiler-component-source.ts
|
|
139476
139692
|
init_zod();
|
|
139477
139693
|
var import_fs6 = require("fs");
|
|
139478
|
-
var
|
|
139694
|
+
var zodSchema48 = external_exports.object({
|
|
139479
139695
|
component_name: external_exports.string().describe("Name of the React component to look up"),
|
|
139480
139696
|
project_root: external_exports.string().describe("Absolute path to the RN project root")
|
|
139481
139697
|
});
|
|
@@ -139493,7 +139709,7 @@ var reactProfilerComponentSourceTool = {
|
|
|
139493
139709
|
Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
|
|
139494
139710
|
Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
|
|
139495
139711
|
When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col) \u2014 check it before assuming the returned file is the one you meant.`,
|
|
139496
|
-
zodSchema:
|
|
139712
|
+
zodSchema: zodSchema48,
|
|
139497
139713
|
// Declared so the tool catalogue groups this with the other react-profiler-*
|
|
139498
139714
|
// tools; the HTTP gate itself is a no-op here, as there is no device arg to
|
|
139499
139715
|
// inspect.
|
|
@@ -139549,7 +139765,7 @@ When several files define a component with the same name (e.g. platform variants
|
|
|
139549
139765
|
// ../tool-server/src/tools/profiler/react/react-profiler-cpu-summary.ts
|
|
139550
139766
|
init_zod();
|
|
139551
139767
|
init_src2();
|
|
139552
|
-
var
|
|
139768
|
+
var zodSchema49 = external_exports.object({
|
|
139553
139769
|
port: metroPortField,
|
|
139554
139770
|
device_id: external_exports.string().describe(
|
|
139555
139771
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -139631,7 +139847,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
|
|
|
139631
139847
|
Call react-profiler-stop first. Reads directly from the stored cpuProfile.
|
|
139632
139848
|
Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
|
|
139633
139849
|
Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
|
|
139634
|
-
zodSchema:
|
|
139850
|
+
zodSchema: zodSchema49,
|
|
139635
139851
|
// RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
|
|
139636
139852
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
139637
139853
|
services: () => ({}),
|
|
@@ -139727,7 +139943,7 @@ function renderMarkdownTable2(entries) {
|
|
|
139727
139943
|
);
|
|
139728
139944
|
return [header, sep5, ...rows].join("\n");
|
|
139729
139945
|
}
|
|
139730
|
-
var
|
|
139946
|
+
var zodSchema50 = external_exports.object({
|
|
139731
139947
|
port: metroPortField,
|
|
139732
139948
|
device_id: external_exports.string().describe(
|
|
139733
139949
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -139745,7 +139961,7 @@ var reactProfilerRendersTool = {
|
|
|
139745
139961
|
Returns a markdown table of the top re-rendering components. No profiling session required \u2014 works on a live connected app.
|
|
139746
139962
|
Use when you want a quick snapshot of render counts without a full profiling session.
|
|
139747
139963
|
Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
|
|
139748
|
-
zodSchema:
|
|
139964
|
+
zodSchema: zodSchema50,
|
|
139749
139965
|
// RN-only: queries the React DevTools backend hook on the live runtime.
|
|
139750
139966
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
139751
139967
|
services: (params) => ({
|
|
@@ -139902,7 +140118,7 @@ function buildFiberTreeScript(maxDepth, filter) {
|
|
|
139902
140118
|
}
|
|
139903
140119
|
})()`;
|
|
139904
140120
|
}
|
|
139905
|
-
var
|
|
140121
|
+
var zodSchema51 = external_exports.object({
|
|
139906
140122
|
port: metroPortField,
|
|
139907
140123
|
device_id: external_exports.string().describe(
|
|
139908
140124
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -139921,7 +140137,7 @@ var reactProfilerFiberTreeTool = {
|
|
|
139921
140137
|
Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
|
|
139922
140138
|
Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
|
|
139923
140139
|
Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
|
|
139924
|
-
zodSchema:
|
|
140140
|
+
zodSchema: zodSchema51,
|
|
139925
140141
|
// RN-only: walks the fiber tree via the React DevTools backend hook.
|
|
139926
140142
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
139927
140143
|
services: (params) => ({
|
|
@@ -140343,8 +140559,8 @@ var import_util8 = require("util");
|
|
|
140343
140559
|
var DEFAULT_EXEC_TIMEOUT_MS = 6e4;
|
|
140344
140560
|
var DEFAULT_EXEC_MAX_BUFFER = 256 * 1024 * 1024;
|
|
140345
140561
|
async function execFileAsyncWithTimeout(file2, args, options = {}) {
|
|
140346
|
-
const
|
|
140347
|
-
const { stdout, stderr } = await
|
|
140562
|
+
const execFileAsync31 = (0, import_util8.promisify)(import_child_process2.execFile);
|
|
140563
|
+
const { stdout, stderr } = await execFileAsync31(file2, args, {
|
|
140348
140564
|
encoding: "utf-8",
|
|
140349
140565
|
...options,
|
|
140350
140566
|
// Applied after ...options so a caller cannot weaken the guards; maxBuffer
|
|
@@ -143719,7 +143935,7 @@ function metroDeviceIdParam(description) {
|
|
|
143719
143935
|
}
|
|
143720
143936
|
|
|
143721
143937
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-start.ts
|
|
143722
|
-
var
|
|
143938
|
+
var zodSchema52 = external_exports.object({
|
|
143723
143939
|
device_id: metroDeviceIdParam(
|
|
143724
143940
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
143725
143941
|
),
|
|
@@ -143733,7 +143949,7 @@ var zodSchema50 = external_exports.object({
|
|
|
143733
143949
|
"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."
|
|
143734
143950
|
)
|
|
143735
143951
|
});
|
|
143736
|
-
var
|
|
143952
|
+
var capability29 = {
|
|
143737
143953
|
apple: { simulator: true },
|
|
143738
143954
|
android: { emulator: true, device: true, unknown: true }
|
|
143739
143955
|
};
|
|
@@ -143744,21 +143960,21 @@ var nativeProfilerStartTool = {
|
|
|
143744
143960
|
completedMsg: () => "Started native profiler",
|
|
143745
143961
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start native profiler: ${failureSignal2.error_code}`
|
|
143746
143962
|
},
|
|
143747
|
-
capability:
|
|
143963
|
+
capability: capability29,
|
|
143748
143964
|
description: `Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal).
|
|
143749
143965
|
Auto-detects the running app process unless app_process is explicitly provided.
|
|
143750
143966
|
After starting, let the user interact with the app, then call native-profiler-stop.
|
|
143751
143967
|
Use when you want to capture native CPU, hang, and memory data for a running app.
|
|
143752
143968
|
Returns { status, pid, traceFile } confirming the recording has started.
|
|
143753
143969
|
Fails if no app is running on the device, or the profiler cannot attach to the process.`,
|
|
143754
|
-
zodSchema:
|
|
143970
|
+
zodSchema: zodSchema52,
|
|
143755
143971
|
services: (params) => ({
|
|
143756
143972
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
143757
143973
|
}),
|
|
143758
143974
|
async execute(services, params) {
|
|
143759
143975
|
const api = services.session;
|
|
143760
143976
|
const device = resolveDevice(params.device_id);
|
|
143761
|
-
assertSupported("native-profiler-start",
|
|
143977
|
+
assertSupported("native-profiler-start", capability29, device);
|
|
143762
143978
|
if (api.platform === "ios") {
|
|
143763
143979
|
await ensureDeps(["xcrun"]);
|
|
143764
143980
|
return startNativeProfilerIos(api, params);
|
|
@@ -143771,12 +143987,12 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
|
|
|
143771
143987
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-stop.ts
|
|
143772
143988
|
init_zod();
|
|
143773
143989
|
init_device_info();
|
|
143774
|
-
var
|
|
143990
|
+
var zodSchema53 = external_exports.object({
|
|
143775
143991
|
device_id: metroDeviceIdParam(
|
|
143776
143992
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
143777
143993
|
)
|
|
143778
143994
|
});
|
|
143779
|
-
var
|
|
143995
|
+
var capability30 = {
|
|
143780
143996
|
apple: { simulator: true },
|
|
143781
143997
|
android: { emulator: true, device: true, unknown: true }
|
|
143782
143998
|
};
|
|
@@ -143804,7 +144020,7 @@ var nativeProfilerStopTool = {
|
|
|
143804
144020
|
completedMsg: ({ result }) => `Saved native profile ${result.traceFile.filename}`,
|
|
143805
144021
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
|
|
143806
144022
|
},
|
|
143807
|
-
capability:
|
|
144023
|
+
capability: capability30,
|
|
143808
144024
|
// Packaging plus the export passes routinely exceed the 30s MCP fetch timeout.
|
|
143809
144025
|
longRunning: true,
|
|
143810
144026
|
description: `Stop native profiling and export trace data.
|
|
@@ -143814,14 +144030,14 @@ Call native-profiler-start first.
|
|
|
143814
144030
|
Use when the user has finished the interaction to profile and you need to export the trace.
|
|
143815
144031
|
Returns { traceFile, exportedFiles, exportDiagnostics? }; traceFile is the raw trace bundle and exportedFiles the exports, all downloadable artifacts materialized to local paths.
|
|
143816
144032
|
Fails if no active native-profiler-start session exists for the given device_id.`,
|
|
143817
|
-
zodSchema:
|
|
144033
|
+
zodSchema: zodSchema53,
|
|
143818
144034
|
services: (params) => ({
|
|
143819
144035
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
143820
144036
|
}),
|
|
143821
144037
|
async execute(services, params, ctx) {
|
|
143822
144038
|
const api = services.session;
|
|
143823
144039
|
const device = resolveDevice(params.device_id);
|
|
143824
|
-
assertSupported("native-profiler-stop",
|
|
144040
|
+
assertSupported("native-profiler-stop", capability30, device);
|
|
143825
144041
|
if (api.platform === "ios") {
|
|
143826
144042
|
await ensureDeps(["xcrun"]);
|
|
143827
144043
|
const ios = await stopNativeProfilerIos(api);
|
|
@@ -143849,12 +144065,12 @@ Fails if no active native-profiler-start session exists for the given device_id.
|
|
|
143849
144065
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-analyze.ts
|
|
143850
144066
|
init_zod();
|
|
143851
144067
|
init_device_info();
|
|
143852
|
-
var
|
|
144068
|
+
var zodSchema54 = external_exports.object({
|
|
143853
144069
|
device_id: metroDeviceIdParam(
|
|
143854
144070
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
143855
144071
|
)
|
|
143856
144072
|
});
|
|
143857
|
-
var
|
|
144073
|
+
var capability31 = {
|
|
143858
144074
|
apple: { simulator: true },
|
|
143859
144075
|
android: { emulator: true, device: true, unknown: true }
|
|
143860
144076
|
};
|
|
@@ -143865,7 +144081,7 @@ var nativeProfilerAnalyzeTool = {
|
|
|
143865
144081
|
completedMsg: () => "Analyzed native profile",
|
|
143866
144082
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to analyze native profile: ${failureSignal2.error_code}`
|
|
143867
144083
|
},
|
|
143868
|
-
capability:
|
|
144084
|
+
capability: capability31,
|
|
143869
144085
|
// Parsing a trace from a recording up to RECORDING_CAP_MS long routinely exceeds
|
|
143870
144086
|
// the 30s MCP fetch timeout, and an aborted call is replayed, not cancelled.
|
|
143871
144087
|
longRunning: true,
|
|
@@ -143878,14 +144094,14 @@ profiler-stack-query for hang stacks, CPU context, leak details) or implement fi
|
|
|
143878
144094
|
Call native-profiler-stop first to export the trace data.
|
|
143879
144095
|
Use when you need to interpret a completed native profiling recording.
|
|
143880
144096
|
Fails if native-profiler-stop has not been called first to export trace data.`,
|
|
143881
|
-
zodSchema:
|
|
144097
|
+
zodSchema: zodSchema54,
|
|
143882
144098
|
services: (params) => ({
|
|
143883
144099
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
143884
144100
|
}),
|
|
143885
144101
|
async execute(services, params, ctx) {
|
|
143886
144102
|
const api = services.session;
|
|
143887
144103
|
const device = resolveDevice(params.device_id);
|
|
143888
|
-
assertSupported("native-profiler-analyze",
|
|
144104
|
+
assertSupported("native-profiler-analyze", capability31, device);
|
|
143889
144105
|
let result;
|
|
143890
144106
|
if (api.platform === "ios") {
|
|
143891
144107
|
await ensureDeps(["xcrun"]);
|
|
@@ -144388,7 +144604,7 @@ var WATERMARK_PNG_HEIGHT = 277;
|
|
|
144388
144604
|
var WATERMARK_PNG_BASE64 = "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";
|
|
144389
144605
|
|
|
144390
144606
|
// ../tool-server/src/tools/screen-recording/watermark.ts
|
|
144391
|
-
var
|
|
144607
|
+
var execFileAsync27 = (0, import_util9.promisify)(import_child_process6.execFile);
|
|
144392
144608
|
var OUTPUT_FPS = 30;
|
|
144393
144609
|
var FFMPEG_FALLBACK_PATHS = [
|
|
144394
144610
|
"/opt/homebrew/bin/ffmpeg",
|
|
@@ -144405,7 +144621,7 @@ var MASK_DARK_MAX_LUMA = 90;
|
|
|
144405
144621
|
var MASK_LIGHT_MIN_LUMA = 165;
|
|
144406
144622
|
async function resolveBinary(name, fallbacks) {
|
|
144407
144623
|
try {
|
|
144408
|
-
await
|
|
144624
|
+
await execFileAsync27("/bin/sh", ["-c", `command -v ${name}`], { timeout: 2e3 });
|
|
144409
144625
|
return name;
|
|
144410
144626
|
} catch {
|
|
144411
144627
|
}
|
|
@@ -144948,7 +145164,7 @@ var DEFAULT_TIME_LIMIT_SECONDS = 180;
|
|
|
144948
145164
|
var MAX_TIME_LIMIT_SECONDS = 600;
|
|
144949
145165
|
var POINTER_TRAIL_LENGTH = 8;
|
|
144950
145166
|
var POINTER_REQUEST_TIMEOUT_MS = 2e3;
|
|
144951
|
-
var
|
|
145167
|
+
var zodSchema55 = external_exports.object({
|
|
144952
145168
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial)."),
|
|
144953
145169
|
timeLimitSeconds: external_exports.number().int().min(1).max(MAX_TIME_LIMIT_SECONDS).optional().describe(
|
|
144954
145170
|
`Auto-stop cap in seconds (default ${DEFAULT_TIME_LIMIT_SECONDS}, max ${MAX_TIME_LIMIT_SECONDS}). Set it to slightly more than the interaction you plan to capture.`
|
|
@@ -144960,7 +145176,7 @@ var zodSchema53 = external_exports.object({
|
|
|
144960
145176
|
"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."
|
|
144961
145177
|
)
|
|
144962
145178
|
});
|
|
144963
|
-
var
|
|
145179
|
+
var capability32 = {
|
|
144964
145180
|
apple: { simulator: true },
|
|
144965
145181
|
android: { emulator: true, device: true, unknown: true }
|
|
144966
145182
|
};
|
|
@@ -144972,7 +145188,7 @@ function createScreenRecordingStartTool(registry2) {
|
|
|
144972
145188
|
completedMsg: () => "Started screen recording",
|
|
144973
145189
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start screen recording: ${failureSignal2.error_code}`
|
|
144974
145190
|
},
|
|
144975
|
-
capability:
|
|
145191
|
+
capability: capability32,
|
|
144976
145192
|
description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
|
|
144977
145193
|
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.
|
|
144978
145194
|
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.
|
|
@@ -144981,7 +145197,7 @@ Use when the user wants a video of an interaction, animation, or app behavior \u
|
|
|
144981
145197
|
Returns { status: "recording", timeLimitSeconds, outputFile } \u2014 the video is retrieved later by \`screen-recording-stop\`, not by reading outputFile directly.
|
|
144982
145198
|
Fails if a recording is already running on the device, the device is not booted, ffmpeg is not installed, or the platform cannot be recorded (tvOS, Chromium, Vega and remote simulators are unsupported).`,
|
|
144983
145199
|
searchHint: "record video screen capture movie mp4 start filming screencast",
|
|
144984
|
-
zodSchema:
|
|
145200
|
+
zodSchema: zodSchema55,
|
|
144985
145201
|
// Resolved inside execute, not declared eagerly: a tvOS udid classifies as
|
|
144986
145202
|
// iOS by shape, so an eager service would spawn simulator-server for a
|
|
144987
145203
|
// device it cannot drive and hang on its ready timeout (as in `screenshot`).
|
|
@@ -144991,7 +145207,7 @@ Fails if a recording is already running on the device, the device is not booted,
|
|
|
144991
145207
|
async execute(services, params) {
|
|
144992
145208
|
const api = services.session;
|
|
144993
145209
|
const device = resolveDevice(params.udid);
|
|
144994
|
-
assertSupported("screen-recording-start",
|
|
145210
|
+
assertSupported("screen-recording-start", capability32, device);
|
|
144995
145211
|
if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
|
|
144996
145212
|
throw new FailureError(
|
|
144997
145213
|
`Screen recording is not supported on tvOS simulators (device ${params.udid}).`,
|
|
@@ -145080,11 +145296,11 @@ function makePointerControl(simulator) {
|
|
|
145080
145296
|
var import_node_path22 = require("node:path");
|
|
145081
145297
|
init_zod();
|
|
145082
145298
|
init_device_info();
|
|
145083
|
-
var
|
|
145299
|
+
var zodSchema56 = external_exports.object({
|
|
145084
145300
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial).")
|
|
145085
145301
|
});
|
|
145086
145302
|
var RECORDINGS_DIR = ".argent/recordings";
|
|
145087
|
-
var
|
|
145303
|
+
var capability33 = {
|
|
145088
145304
|
apple: { simulator: true },
|
|
145089
145305
|
android: { emulator: true, device: true, unknown: true }
|
|
145090
145306
|
};
|
|
@@ -145095,21 +145311,21 @@ var screenRecordingStopTool = {
|
|
|
145095
145311
|
completedMsg: ({ result }) => `Saved screen recording ${result.video.filename}`,
|
|
145096
145312
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop screen recording: ${failureSignal2.error_code}`
|
|
145097
145313
|
},
|
|
145098
|
-
capability:
|
|
145314
|
+
capability: capability33,
|
|
145099
145315
|
description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
|
|
145100
145316
|
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.
|
|
145101
145317
|
Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
|
|
145102
145318
|
Returns { video, durationMs, wallClockMs?, trimmedMs?, panelSwitches?, warning? }; video is a downloadable artifact materialized to a local path. When static-frame trimming removed dead air, durationMs is the trimmed video length and wallClockMs/trimmedMs report the real duration and how much was cut. On a foldable simulator, the recording follows the panel that shows the UI. panelSwitches gives the number of panel changes. The video keeps the size of the first panel. warning is set when argent could not find that panel during the recording.
|
|
145103
145319
|
Fails if no recording (running or finished-but-unretrieved) exists for the given udid.`,
|
|
145104
145320
|
searchHint: "stop end finish screen recording video capture save retrieve",
|
|
145105
|
-
zodSchema:
|
|
145321
|
+
zodSchema: zodSchema56,
|
|
145106
145322
|
services: (params) => ({
|
|
145107
145323
|
session: screenRecordingSessionRef(resolveDevice(params.udid))
|
|
145108
145324
|
}),
|
|
145109
145325
|
async execute(services, params, ctx) {
|
|
145110
145326
|
const api = services.session;
|
|
145111
145327
|
const device = resolveDevice(params.udid);
|
|
145112
|
-
assertSupported("screen-recording-stop",
|
|
145328
|
+
assertSupported("screen-recording-stop", capability33, device);
|
|
145113
145329
|
const stopped = await stopCapture(api);
|
|
145114
145330
|
const artifacts = requireArtifacts(ctx);
|
|
145115
145331
|
const video = await artifacts.register({
|
|
@@ -145141,7 +145357,7 @@ var timeWindowSchema = external_exports.object({
|
|
|
145141
145357
|
"End of window in ms since profiling started \u2014 the same clock profiler-commit-query prints"
|
|
145142
145358
|
)
|
|
145143
145359
|
});
|
|
145144
|
-
var
|
|
145360
|
+
var zodSchema57 = external_exports.object({
|
|
145145
145361
|
port: metroPortField,
|
|
145146
145362
|
device_id: metroDeviceIdParam(
|
|
145147
145363
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -145430,7 +145646,7 @@ Every table states how many samples it covers and how much of that was idle.
|
|
|
145430
145646
|
Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
|
|
145431
145647
|
Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
|
|
145432
145648
|
Fails if no CPU profile is stored \u2014 run react-profiler-stop first.`,
|
|
145433
|
-
zodSchema:
|
|
145649
|
+
zodSchema: zodSchema57,
|
|
145434
145650
|
// RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
|
|
145435
145651
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
145436
145652
|
services: () => ({}),
|
|
@@ -145516,7 +145732,7 @@ var timeRangeSchema = external_exports.object({
|
|
|
145516
145732
|
"End of range in ms since profiling started \u2014 the same clock profiler-commit-query prints"
|
|
145517
145733
|
)
|
|
145518
145734
|
});
|
|
145519
|
-
var
|
|
145735
|
+
var zodSchema58 = external_exports.object({
|
|
145520
145736
|
port: metroPortField,
|
|
145521
145737
|
device_id: metroDeviceIdParam(
|
|
145522
145738
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -145789,7 +146005,7 @@ Modes:
|
|
|
145789
146005
|
Use when drilling into specific components or time windows after react-profiler-analyze.
|
|
145790
146006
|
Returns a markdown table or tree of commit data matching the requested mode.
|
|
145791
146007
|
Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
145792
|
-
zodSchema:
|
|
146008
|
+
zodSchema: zodSchema58,
|
|
145793
146009
|
// Reads React commit data captured via the React DevTools backend.
|
|
145794
146010
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
145795
146011
|
services: () => ({}),
|
|
@@ -145860,7 +146076,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
|
145860
146076
|
init_zod();
|
|
145861
146077
|
init_src2();
|
|
145862
146078
|
init_device_info();
|
|
145863
|
-
var
|
|
146079
|
+
var zodSchema59 = external_exports.object({
|
|
145864
146080
|
device_id: metroDeviceIdParam("iOS Simulator UDID or Android serial."),
|
|
145865
146081
|
mode: external_exports.enum(["hang_stacks", "function_callers", "thread_breakdown", "leak_stacks"]).describe(
|
|
145866
146082
|
"Query mode: hang_stacks (full CPU context during a hang), function_callers (who calls a native function), thread_breakdown (CPU split by thread), leak_stacks (leak details by object type)"
|
|
@@ -146178,7 +146394,7 @@ Modes:
|
|
|
146178
146394
|
Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
|
|
146179
146395
|
Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
|
|
146180
146396
|
Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
|
|
146181
|
-
zodSchema:
|
|
146397
|
+
zodSchema: zodSchema59,
|
|
146182
146398
|
// No chromium entry: it has no native trace capture.
|
|
146183
146399
|
capability: {
|
|
146184
146400
|
apple: { simulator: true },
|
|
@@ -146248,7 +146464,7 @@ function buildPerfettoAnchor(wallClockStartMs) {
|
|
|
146248
146464
|
}
|
|
146249
146465
|
|
|
146250
146466
|
// ../tool-server/src/tools/profiler/combined/profiler-combined-report.ts
|
|
146251
|
-
var
|
|
146467
|
+
var zodSchema60 = external_exports.object({
|
|
146252
146468
|
port: metroPortField,
|
|
146253
146469
|
device_id: metroDeviceIdParam("iOS Simulator/device UDID or Android serial")
|
|
146254
146470
|
});
|
|
@@ -146265,7 +146481,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
|
|
|
146265
146481
|
Call this tool when both profilers were run in parallel on the same session.
|
|
146266
146482
|
Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
|
|
146267
146483
|
Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
|
|
146268
|
-
zodSchema:
|
|
146484
|
+
zodSchema: zodSchema60,
|
|
146269
146485
|
// iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
|
|
146270
146486
|
// loadAndroidCombinedData. Chromium has no native trace capture.
|
|
146271
146487
|
capability: {
|
|
@@ -146589,7 +146805,7 @@ function assertSafeSessionId(sessionId) {
|
|
|
146589
146805
|
);
|
|
146590
146806
|
}
|
|
146591
146807
|
}
|
|
146592
|
-
var
|
|
146808
|
+
var zodSchema61 = external_exports.object({
|
|
146593
146809
|
mode: external_exports.enum(["list", "load_react", "load_native"]).describe(
|
|
146594
146810
|
"list: show available sessions on disk. load_react: load a React profiler session into memory for query tools. load_native: re-parse native profiler XML files (xctrace on iOS) into memory for query tools."
|
|
146595
146811
|
),
|
|
@@ -146950,7 +147166,7 @@ Modes:
|
|
|
146950
147166
|
For Android .pftrace restores, pass app_process for older sessions that do not have a metadata sidecar.
|
|
146951
147167
|
Returns a summary of the loaded session or a session list for the list mode.
|
|
146952
147168
|
Fails if the session_id is not found or required XML files are missing from disk.`,
|
|
146953
|
-
zodSchema:
|
|
147169
|
+
zodSchema: zodSchema61,
|
|
146954
147170
|
// The Hermes, xctrace and perfetto formats this loads have no Chromium
|
|
146955
147171
|
// equivalent; the gate fails at the call site, not inside the trace parser.
|
|
146956
147172
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -147079,7 +147295,7 @@ function unnameableSessionUrns(urns) {
|
|
|
147079
147295
|
}
|
|
147080
147296
|
|
|
147081
147297
|
// ../tool-server/src/tools/simulator/stop-simulator-server.ts
|
|
147082
|
-
var
|
|
147298
|
+
var zodSchema62 = external_exports.object({
|
|
147083
147299
|
udid: external_exports.string().describe(
|
|
147084
147300
|
"Target device id (iOS UDID, Android serial, or Chromium id) whose transport session to stop"
|
|
147085
147301
|
)
|
|
@@ -147093,7 +147309,7 @@ function createStopSimulatorServerTool(registry2) {
|
|
|
147093
147309
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop simulator server for ${params.udid}: ${failureSignal2.error_code}`
|
|
147094
147310
|
},
|
|
147095
147311
|
description: `Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use when you are done interacting with one device but want to keep others running, or to restart a wedged transport. On iOS / Android / TV it deliberately leaves this device's native-devtools, accessibility, profiler and debugger services running - to drain those as well, use stop-all-simulator-servers with \`devices\`. On CHROMIUM that does not hold: the JS-runtime debugger declares the CDP session as a dependency, so stopping the transport cascades to it and its captured console history goes with it - reconnect with debugger-connect afterwards. Returns { stopped, udid }. Fails silently if no session is open for the given id.`,
|
|
147096
|
-
zodSchema:
|
|
147312
|
+
zodSchema: zodSchema62,
|
|
147097
147313
|
services: () => ({}),
|
|
147098
147314
|
async execute(_services, params) {
|
|
147099
147315
|
const udid = params.udid;
|
|
@@ -147124,7 +147340,7 @@ function createStopSimulatorServerTool(registry2) {
|
|
|
147124
147340
|
init_zod();
|
|
147125
147341
|
init_src2();
|
|
147126
147342
|
init_external_devices();
|
|
147127
|
-
var
|
|
147343
|
+
var zodSchema63 = external_exports.object({
|
|
147128
147344
|
devices: external_exports.array(external_exports.string()).optional().describe(
|
|
147129
147345
|
"Device ids (iOS UDID / Android serial / Chromium id) to scope the teardown to \u2014 pass the devices THIS session actually used. Omit only for a deliberate machine-wide cleanup: one tool-server serves every agent using this argent install, so an unscoped stop also kills devices another agent is mid-session on."
|
|
147130
147346
|
)
|
|
@@ -147163,7 +147379,7 @@ function createStopAllSimulatorServersTool(registry2) {
|
|
|
147163
147379
|
PASS \`devices\` with the device ids this session used \u2014 one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's flow to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit \`devices\` only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
|
|
147164
147380
|
A JS-runtime debugger session is keyed by the id you called \`debugger-connect\` with. On a Metro serving two or more devices that id is not a udid or serial - connect refuses those and tells you to re-target with the \`logicalDeviceId\` it returns - so a scope built from \`list-devices\` ids cannot reach that session. Pass any such \`logicalDeviceId\` in \`devices\` ALONGSIDE the device id; { left_running } names the ones you missed.
|
|
147165
147381
|
Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty \`stopped\` only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here \u2014 as does a real device of any platform this session never started anything on. Present ONLY when \`devices\` was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with that id to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the \`udids\` slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.`,
|
|
147166
|
-
zodSchema:
|
|
147382
|
+
zodSchema: zodSchema63,
|
|
147167
147383
|
services: () => ({}),
|
|
147168
147384
|
async execute(_services, params, ctx) {
|
|
147169
147385
|
const devices = params.devices;
|
|
@@ -147211,7 +147427,7 @@ Returns { stopped } - the URNs of the services that were actually live and got s
|
|
|
147211
147427
|
|
|
147212
147428
|
// ../tool-server/src/tools/simulator/stop-metro.ts
|
|
147213
147429
|
init_zod();
|
|
147214
|
-
var
|
|
147430
|
+
var import_node_child_process35 = require("node:child_process");
|
|
147215
147431
|
function parseNetstatListeningPids(netstatOutput, port) {
|
|
147216
147432
|
const pids = /* @__PURE__ */ new Set();
|
|
147217
147433
|
for (const line of netstatOutput.split(/\r?\n/)) {
|
|
@@ -147227,7 +147443,7 @@ function parseNetstatListeningPids(netstatOutput, port) {
|
|
|
147227
147443
|
}
|
|
147228
147444
|
function listeningPids(port) {
|
|
147229
147445
|
if (process.platform === "win32") {
|
|
147230
|
-
const output2 = (0,
|
|
147446
|
+
const output2 = (0, import_node_child_process35.execFileSync)("netstat", ["-ano"], {
|
|
147231
147447
|
encoding: "utf-8",
|
|
147232
147448
|
timeout: 5e3,
|
|
147233
147449
|
// `netstat -ano` dumps every socket on the host; overflowing Node's
|
|
@@ -147236,14 +147452,14 @@ function listeningPids(port) {
|
|
|
147236
147452
|
});
|
|
147237
147453
|
return parseNetstatListeningPids(output2, port);
|
|
147238
147454
|
}
|
|
147239
|
-
const output = (0,
|
|
147455
|
+
const output = (0, import_node_child_process35.execFileSync)("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"], {
|
|
147240
147456
|
encoding: "utf-8",
|
|
147241
147457
|
timeout: 5e3
|
|
147242
147458
|
}).trim();
|
|
147243
147459
|
if (!output) return [];
|
|
147244
147460
|
return output.split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => !Number.isNaN(n));
|
|
147245
147461
|
}
|
|
147246
|
-
var
|
|
147462
|
+
var zodSchema64 = external_exports.object({
|
|
147247
147463
|
port: external_exports.number().int().min(1).max(65535).default(8081).describe("TCP port Metro is listening on (default 8081)")
|
|
147248
147464
|
});
|
|
147249
147465
|
var stopMetroTool = {
|
|
@@ -147254,7 +147470,7 @@ var stopMetroTool = {
|
|
|
147254
147470
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
|
|
147255
147471
|
},
|
|
147256
147472
|
description: `Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE \u2014 always ask the user for confirmation before calling this tool.`,
|
|
147257
|
-
zodSchema:
|
|
147473
|
+
zodSchema: zodSchema64,
|
|
147258
147474
|
services: () => ({}),
|
|
147259
147475
|
async execute(_services, params) {
|
|
147260
147476
|
const port = params.port;
|
|
@@ -149598,7 +149814,7 @@ async function appendStepToFlow(session, step) {
|
|
|
149598
149814
|
}
|
|
149599
149815
|
|
|
149600
149816
|
// ../tool-server/src/tools/flows/flow-start-recording.ts
|
|
149601
|
-
var
|
|
149817
|
+
var zodSchema65 = external_exports.object({
|
|
149602
149818
|
name: external_exports.string().describe(
|
|
149603
149819
|
'Name for this flow (e.g. "settings-explore") \u2014 letters, digits, underscore and hyphen only.'
|
|
149604
149820
|
),
|
|
@@ -149655,7 +149871,7 @@ recording. Over a link, the next recorded step writes over your edit.
|
|
|
149655
149871
|
Without a link, the recorder reads the file again before each step, but an
|
|
149656
149872
|
edit that renumbers the steps drops the warnings that flow-finish-recording
|
|
149657
149873
|
reports for those steps.`,
|
|
149658
|
-
zodSchema:
|
|
149874
|
+
zodSchema: zodSchema65,
|
|
149659
149875
|
fileInputs: fileInputs2,
|
|
149660
149876
|
services: () => ({}),
|
|
149661
149877
|
async execute(_services, params, ctx) {
|
|
@@ -152155,7 +152371,7 @@ function stepAnchor(step) {
|
|
|
152155
152371
|
|
|
152156
152372
|
// ../tool-server/src/tools/flows/flow-add-step.ts
|
|
152157
152373
|
init_device_info();
|
|
152158
|
-
var
|
|
152374
|
+
var zodSchema66 = external_exports.object({
|
|
152159
152375
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
152160
152376
|
project_root: external_exports.string().describe(
|
|
152161
152377
|
"Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to."
|
|
@@ -152614,7 +152830,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
|
|
|
152614
152830
|
// more times — and every retry re-runs the action and appends another step,
|
|
152615
152831
|
// because an aborted request still appends its first.
|
|
152616
152832
|
longRunning: true,
|
|
152617
|
-
zodSchema:
|
|
152833
|
+
zodSchema: zodSchema66,
|
|
152618
152834
|
fileInputs: fileInputs3,
|
|
152619
152835
|
services: () => ({}),
|
|
152620
152836
|
async execute(_services, params, ctx) {
|
|
@@ -152803,7 +153019,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
|
|
|
152803
153019
|
|
|
152804
153020
|
// ../tool-server/src/tools/flows/flow-insert-echo.ts
|
|
152805
153021
|
init_zod();
|
|
152806
|
-
var
|
|
153022
|
+
var zodSchema67 = external_exports.object({
|
|
152807
153023
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
152808
153024
|
project_root: external_exports.string().describe(
|
|
152809
153025
|
"Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording this echo belongs to."
|
|
@@ -152821,7 +153037,7 @@ var flowInsertEchoTool = {
|
|
|
152821
153037
|
description: `Record an echo step in the flow named by \`name\` + \`project_root\`. Echo steps print a message when the flow is replayed \u2014 useful as labels between tool calls.
|
|
152822
153038
|
Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.
|
|
152823
153039
|
Returns { message, stepCount, savedTo }. Fails if that flow has no recording in progress.`,
|
|
152824
|
-
zodSchema:
|
|
153040
|
+
zodSchema: zodSchema67,
|
|
152825
153041
|
services: () => ({}),
|
|
152826
153042
|
async execute(_services, params) {
|
|
152827
153043
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
@@ -152849,7 +153065,7 @@ var import_node_url4 = require("node:url");
|
|
|
152849
153065
|
init_src2();
|
|
152850
153066
|
|
|
152851
153067
|
// ../tool-server/src/tools/flows/script/flow-script-executor.ts
|
|
152852
|
-
var
|
|
153068
|
+
var import_node_child_process36 = require("node:child_process");
|
|
152853
153069
|
var fs58 = __toESM(require("node:fs"));
|
|
152854
153070
|
var os17 = __toESM(require("node:os"));
|
|
152855
153071
|
var path44 = __toESM(require("node:path"));
|
|
@@ -153234,14 +153450,14 @@ var FlowScriptExecutor = class {
|
|
|
153234
153450
|
detached: process.platform !== "win32",
|
|
153235
153451
|
windowsHide: process.platform === "win32"
|
|
153236
153452
|
};
|
|
153237
|
-
child = (0,
|
|
153453
|
+
child = (0, import_node_child_process36.fork)(scriptPath, [], forkOptions);
|
|
153238
153454
|
} catch (err) {
|
|
153239
153455
|
return emptyResult(
|
|
153240
153456
|
{ kind: "spawn", message: `Could not start the script process: ${errorMessage(err)}` },
|
|
153241
153457
|
{ notes, durationMs: Date.now() - startedAt }
|
|
153242
153458
|
);
|
|
153243
153459
|
}
|
|
153244
|
-
const lifeline = child.stdio[4];
|
|
153460
|
+
const lifeline = child.stdio?.[4];
|
|
153245
153461
|
lifeline?.unref?.();
|
|
153246
153462
|
let startedSeen = false;
|
|
153247
153463
|
let terminal = null;
|
|
@@ -153675,7 +153891,7 @@ async function stopProcessTree(child, graceMs) {
|
|
|
153675
153891
|
if (process.platform === "win32") {
|
|
153676
153892
|
if (hasExited(child)) return;
|
|
153677
153893
|
tryKill(() => {
|
|
153678
|
-
const killer = (0,
|
|
153894
|
+
const killer = (0, import_node_child_process36.spawn)("taskkill", ["/pid", String(pid), "/t", "/f"], {
|
|
153679
153895
|
windowsHide: true,
|
|
153680
153896
|
stdio: "ignore"
|
|
153681
153897
|
});
|
|
@@ -154124,7 +154340,7 @@ function errMsg3(err) {
|
|
|
154124
154340
|
|
|
154125
154341
|
// ../tool-server/src/tools/flows/flow-add-script.ts
|
|
154126
154342
|
var OUTPUT_RENDER_LIMIT_BYTES = 64 * 1024;
|
|
154127
|
-
var
|
|
154343
|
+
var zodSchema68 = external_exports.object({
|
|
154128
154344
|
name: external_exports.string().describe("Flow name passed to flow-start-recording."),
|
|
154129
154345
|
project_root: external_exports.string().describe("Absolute project root passed to flow-start-recording."),
|
|
154130
154346
|
path: external_exports.string().describe(
|
|
@@ -154181,7 +154397,7 @@ var flowAddScriptTool = {
|
|
|
154181
154397
|
// The flag only skips the adapter's own abort timer; its retry loop is
|
|
154182
154398
|
// untouched, so a call that fails some other way is still re-POSTed.
|
|
154183
154399
|
longRunning: true,
|
|
154184
|
-
zodSchema:
|
|
154400
|
+
zodSchema: zodSchema68,
|
|
154185
154401
|
services: () => ({}),
|
|
154186
154402
|
async execute(_services, params, ctx) {
|
|
154187
154403
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
@@ -154271,7 +154487,7 @@ var flowAddScriptTool = {
|
|
|
154271
154487
|
// ../tool-server/src/tools/flows/flow-finish-recording.ts
|
|
154272
154488
|
init_zod();
|
|
154273
154489
|
var fs60 = __toESM(require("node:fs/promises"));
|
|
154274
|
-
var
|
|
154490
|
+
var zodSchema69 = external_exports.object({
|
|
154275
154491
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
154276
154492
|
project_root: external_exports.string().describe(
|
|
154277
154493
|
"Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording to finish."
|
|
@@ -154330,7 +154546,7 @@ var flowFinishRecordingTool = {
|
|
|
154330
154546
|
description: `Finish recording the flow named by \`name\` + \`project_root\`, leaving recordings under any other key untouched. Returns { message, path, executionPrerequisite, steps, summary, flowFile, savedTo } - a summary of all recorded steps plus the final YAML. Use when you have added all desired steps and want to finalize the flow file. Fails if that flow has no recording in progress.
|
|
154331
154547
|
A warning flow-add-step raised on a recorded \`await-ui-element\` is repeated in \`summary\` as a \`warning:\` line of its own, right below the step it judges, and \`message\` counts them by kind. A warning is repeated only while the step it judges is still identifiable by its number: hand-editing the .yaml during the recording moves the steps, so those warnings are DROPPED rather than pinned on whichever step inherited the number, and \`message\` says how many were dropped. A step that carries a cross-tree warning was re-probed against the runner's tree: read it before converting that wait to \`await:\`/\`assert:\`, which is what the verdict is about and what this moment is for. A step that recorded a wait which did not pass was never probed at all, and its own warning names the CAUSE, because only one of them judges the condition: an unmet wait was read and found false, and it stops the run at replay; a wait whose tree source could not be read, or one that was cancelled, observed nothing and leaves the condition UNKNOWN rather than known-bad. Read those before replaying.
|
|
154332
154548
|
You can still edit the .yaml file directly afterwards to remove or reorder steps.`,
|
|
154333
|
-
zodSchema:
|
|
154549
|
+
zodSchema: zodSchema69,
|
|
154334
154550
|
services: () => ({}),
|
|
154335
154551
|
async execute(_services, params) {
|
|
154336
154552
|
const { filePath, flowFile, savedTo, flow, summary, headline } = await withFlowFileLock(
|
|
@@ -154395,7 +154611,7 @@ init_src2();
|
|
|
154395
154611
|
// ../tool-server/src/tools/screenshot-diff/screenshot-diff-ocr.ts
|
|
154396
154612
|
var import_child_process8 = require("child_process");
|
|
154397
154613
|
var import_util10 = require("util");
|
|
154398
|
-
var
|
|
154614
|
+
var execFileAsync28 = (0, import_util10.promisify)(import_child_process8.execFile);
|
|
154399
154615
|
var OCR_TIMEOUT_MS = 1e4;
|
|
154400
154616
|
var OCR_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
154401
154617
|
var TESSERACT_BINARY = "tesseract";
|
|
@@ -154440,7 +154656,7 @@ async function extractOcrTextBlocks(imagePath) {
|
|
|
154440
154656
|
}
|
|
154441
154657
|
}
|
|
154442
154658
|
async function recognizeTsv(imagePath) {
|
|
154443
|
-
const { stdout } = await
|
|
154659
|
+
const { stdout } = await execFileAsync28(
|
|
154444
154660
|
TESSERACT_BINARY,
|
|
154445
154661
|
[
|
|
154446
154662
|
imagePath,
|
|
@@ -155665,7 +155881,7 @@ function formatScreenshotDiffSummary(result) {
|
|
|
155665
155881
|
const shownRegions = result.regions.slice(0, MAX_SUMMARY_REGIONS);
|
|
155666
155882
|
const coordinateSpace = coordinateSpaceForSummary(result.imageSize);
|
|
155667
155883
|
const lines = ["Screenshot diff summary", "", "Overall:"];
|
|
155668
|
-
lines.push(
|
|
155884
|
+
lines.push(statusLine(status));
|
|
155669
155885
|
if (result.sizeNormalization) {
|
|
155670
155886
|
const { baseline, current, comparedAt } = result.sizeNormalization;
|
|
155671
155887
|
lines.push(
|
|
@@ -155726,6 +155942,12 @@ function formatScreenshotDiffSummary(result) {
|
|
|
155726
155942
|
}
|
|
155727
155943
|
return lines.join("\n");
|
|
155728
155944
|
}
|
|
155945
|
+
function statusLine(status) {
|
|
155946
|
+
return `- status: ${status}`;
|
|
155947
|
+
}
|
|
155948
|
+
function summaryReportsDimensionMismatch(summary) {
|
|
155949
|
+
return summary.split("\n").includes(statusLine("dimension_mismatch"));
|
|
155950
|
+
}
|
|
155729
155951
|
function screenshotDiffStatus(result) {
|
|
155730
155952
|
if (result.dimensionMismatch) return "dimension_mismatch";
|
|
155731
155953
|
if (!Number.isFinite(result.totalPixels) || !Number.isFinite(result.differentPixels) || !Number.isFinite(result.mismatchPercentage)) {
|
|
@@ -156716,11 +156938,11 @@ async function runSnapshot(env, opts) {
|
|
|
156716
156938
|
}
|
|
156717
156939
|
|
|
156718
156940
|
// ../tool-server/src/utils/status-bar.ts
|
|
156719
|
-
var
|
|
156720
|
-
var
|
|
156941
|
+
var import_node_child_process37 = require("node:child_process");
|
|
156942
|
+
var import_node_util27 = require("node:util");
|
|
156721
156943
|
init_adb();
|
|
156722
156944
|
init_device_info();
|
|
156723
|
-
var
|
|
156945
|
+
var execFileAsync29 = (0, import_node_util27.promisify)(import_node_child_process37.execFile);
|
|
156724
156946
|
var DEMO_BROADCAST = "am broadcast -a com.android.systemui.demo";
|
|
156725
156947
|
var IOS_STATUS_BAR_OVERRIDE = [
|
|
156726
156948
|
"override",
|
|
@@ -156744,7 +156966,7 @@ async function pinStatusBar(device, signal) {
|
|
|
156744
156966
|
if (isIosPhysicalDevice(device)) return false;
|
|
156745
156967
|
try {
|
|
156746
156968
|
if (device.platform === "ios") {
|
|
156747
|
-
await
|
|
156969
|
+
await execFileAsync29(
|
|
156748
156970
|
"xcrun",
|
|
156749
156971
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, ...IOS_STATUS_BAR_OVERRIDE])
|
|
156750
156972
|
);
|
|
@@ -156780,7 +157002,7 @@ async function pinStatusBar(device, signal) {
|
|
|
156780
157002
|
async function restoreStatusBar(device) {
|
|
156781
157003
|
try {
|
|
156782
157004
|
if (device.platform === "ios") {
|
|
156783
|
-
await
|
|
157005
|
+
await execFileAsync29(
|
|
156784
157006
|
"xcrun",
|
|
156785
157007
|
await simctlArgsForUdid(device.id, ["status_bar", device.id, "clear"])
|
|
156786
157008
|
);
|
|
@@ -156802,7 +157024,7 @@ async function restoreStatusBar(device) {
|
|
|
156802
157024
|
}
|
|
156803
157025
|
|
|
156804
157026
|
// ../tool-server/src/tools/flows/flow-run.ts
|
|
156805
|
-
var
|
|
157027
|
+
var zodSchema70 = external_exports.object({
|
|
156806
157028
|
name: external_exports.string().optional().describe(
|
|
156807
157029
|
'Name of a saved flow to run from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
|
|
156808
157030
|
),
|
|
@@ -157309,7 +157531,7 @@ one-off interaction use the gesture tools instead, and to author a flow use flow
|
|
|
157309
157531
|
exactly one flow source: name (under project_root) or flow_path.
|
|
157310
157532
|
Returns a per-step report: the first failure stops the run and the rest report as skipped.`,
|
|
157311
157533
|
longRunning: true,
|
|
157312
|
-
zodSchema:
|
|
157534
|
+
zodSchema: zodSchema70,
|
|
157313
157535
|
fileInputs: fileInputs4,
|
|
157314
157536
|
services: () => ({}),
|
|
157315
157537
|
async execute(_services, params, ctx) {
|
|
@@ -158286,7 +158508,7 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
|
|
|
158286
158508
|
// ../tool-server/src/tools/flows/flow-read-prerequisite.ts
|
|
158287
158509
|
init_zod();
|
|
158288
158510
|
var fs64 = __toESM(require("node:fs/promises"));
|
|
158289
|
-
var
|
|
158511
|
+
var zodSchema71 = external_exports.object({
|
|
158290
158512
|
name: external_exports.string().optional().describe(
|
|
158291
158513
|
'Name of a saved flow to inspect from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
|
|
158292
158514
|
),
|
|
@@ -158342,7 +158564,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
|
|
|
158342
158564
|
needs booting, so calling this costs nothing but a file read.
|
|
158343
158565
|
Fails if the flow file does not exist.
|
|
158344
158566
|
Address the flow exactly as you will address it in flow-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/flows/<name>.yaml.`,
|
|
158345
|
-
zodSchema:
|
|
158567
|
+
zodSchema: zodSchema71,
|
|
158346
158568
|
fileInputs: fileInputs5,
|
|
158347
158569
|
services: () => ({}),
|
|
158348
158570
|
async execute(_services, params, ctx) {
|
|
@@ -158365,7 +158587,7 @@ init_zod();
|
|
|
158365
158587
|
// ../tool-server/src/utils/workspace-reader.ts
|
|
158366
158588
|
var import_promises12 = require("node:fs/promises");
|
|
158367
158589
|
var import_node_path23 = require("node:path");
|
|
158368
|
-
var
|
|
158590
|
+
var import_node_child_process38 = require("node:child_process");
|
|
158369
158591
|
var import_dotenv2 = __toESM(require_main());
|
|
158370
158592
|
async function exists(path53) {
|
|
158371
158593
|
try {
|
|
@@ -158409,7 +158631,7 @@ async function listDir(path53) {
|
|
|
158409
158631
|
var COMMAND_TIMEOUT_MS = 3e3;
|
|
158410
158632
|
function runVersionCommand(cmd, args, cwd) {
|
|
158411
158633
|
return new Promise((resolve14) => {
|
|
158412
|
-
const child = (0,
|
|
158634
|
+
const child = (0, import_node_child_process38.execFile)(cmd, args, { cwd, timeout: COMMAND_TIMEOUT_MS }, (err, stdout) => {
|
|
158413
158635
|
if (err) {
|
|
158414
158636
|
resolve14(null);
|
|
158415
158637
|
return;
|
|
@@ -158658,7 +158880,7 @@ async function readWorkspaceSnapshot(workspacePath) {
|
|
|
158658
158880
|
}
|
|
158659
158881
|
|
|
158660
158882
|
// ../tool-server/src/tools/workspace/gather-workspace-data.ts
|
|
158661
|
-
var
|
|
158883
|
+
var zodSchema72 = external_exports.object({
|
|
158662
158884
|
workspacePath: external_exports.string().describe("Absolute path to the project root directory to inspect (e.g. /Users/dev/MyApp)")
|
|
158663
158885
|
});
|
|
158664
158886
|
var fileInputs6 = [
|
|
@@ -158689,7 +158911,7 @@ exploration of anything the snapshot surfaces.
|
|
|
158689
158911
|
Use when you need to inspect project configuration without manually reading multiple files.
|
|
158690
158912
|
Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
|
|
158691
158913
|
Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
|
|
158692
|
-
zodSchema:
|
|
158914
|
+
zodSchema: zodSchema72,
|
|
158693
158915
|
fileInputs: fileInputs6,
|
|
158694
158916
|
services: () => ({}),
|
|
158695
158917
|
async execute(_services, params) {
|
|
@@ -158698,7 +158920,7 @@ Fails if the workspacePath is not an absolute path or the directory cannot be ac
|
|
|
158698
158920
|
};
|
|
158699
158921
|
|
|
158700
158922
|
// ../tool-server/src/tools/system/update-argent.ts
|
|
158701
|
-
var
|
|
158923
|
+
var import_node_child_process39 = require("node:child_process");
|
|
158702
158924
|
var fs65 = __toESM(require("node:fs"));
|
|
158703
158925
|
var path49 = __toESM(require("node:path"));
|
|
158704
158926
|
init_zod();
|
|
@@ -158763,7 +158985,7 @@ function targetFlagsFor(target) {
|
|
|
158763
158985
|
if (target === "both") return ["--global", "--local"];
|
|
158764
158986
|
return [`--${target}`];
|
|
158765
158987
|
}
|
|
158766
|
-
var
|
|
158988
|
+
var zodSchema73 = external_exports.object({
|
|
158767
158989
|
target: external_exports.enum(["auto", "global", "local", "both"]).optional().describe(
|
|
158768
158990
|
"Which install to update. 'auto' (default) updates the install serving this session \u2014 the global PATH install or this project's local devDependency, whichever this server runs from. Pass 'global' / 'local' to force one, or 'both' when the user has both and wants each updated."
|
|
158769
158991
|
)
|
|
@@ -158777,7 +158999,7 @@ var updateArgentTool = {
|
|
|
158777
158999
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to update Argent: ${failureSignal2.error_code}`
|
|
158778
159000
|
},
|
|
158779
159001
|
description: "Apply a pending Argent update. Only call this tool when the user has explicitly consented to updating Argent in this conversation. Use when an update notification indicates a new version is available and the user agrees to update. By default updates the install serving this session; pass `target` to choose global/local/both. Returns { message } with the update status and version info. The tool server will restart automatically after the update. Fails if no update is available or an update is already in progress.",
|
|
158780
|
-
zodSchema:
|
|
159002
|
+
zodSchema: zodSchema73,
|
|
158781
159003
|
services: () => ({}),
|
|
158782
159004
|
async execute(_services, params, _options) {
|
|
158783
159005
|
const { updateAvailable, updateInstallable, currentVersion, installableVersion } = getUpdateState();
|
|
@@ -158833,7 +159055,7 @@ var updateArgentTool = {
|
|
|
158833
159055
|
if (spawnRoot) updateArgs.push("--project-root", spawnRoot);
|
|
158834
159056
|
const cmd = cliEntry ? process.execPath : "argent";
|
|
158835
159057
|
const args = cliEntry ? [cliEntry, ...updateArgs] : updateArgs;
|
|
158836
|
-
const child = (0,
|
|
159058
|
+
const child = (0, import_node_child_process39.spawn)(cmd, args, {
|
|
158837
159059
|
detached: true,
|
|
158838
159060
|
stdio: "ignore",
|
|
158839
159061
|
env: { ...process.env, ARGENT_UPDATE_TRIGGER: "mcp_update" }
|
|
@@ -158862,7 +159084,7 @@ var updateArgentTool = {
|
|
|
158862
159084
|
|
|
158863
159085
|
// ../tool-server/src/tools/system/dismiss-update.ts
|
|
158864
159086
|
init_zod();
|
|
158865
|
-
var
|
|
159087
|
+
var zodSchema74 = external_exports.object({
|
|
158866
159088
|
hours: external_exports.number().min(0).describe("Number of hours to suppress the update notification")
|
|
158867
159089
|
});
|
|
158868
159090
|
var dismissUpdateTool = {
|
|
@@ -158873,7 +159095,7 @@ var dismissUpdateTool = {
|
|
|
158873
159095
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to dismiss Argent update: ${failureSignal2.error_code}`
|
|
158874
159096
|
},
|
|
158875
159097
|
description: "Clear the Argent update notification for the given number of hours. Use when the user asks to postpone or silence update reminders. Returns { message } confirming the suppression duration. Fails if the hours value is negative or the suppression state cannot be persisted.",
|
|
158876
|
-
zodSchema:
|
|
159098
|
+
zodSchema: zodSchema74,
|
|
158877
159099
|
services: () => ({}),
|
|
158878
159100
|
async execute(_services, params, _options) {
|
|
158879
159101
|
const durationMs = params.hours * 60 * 60 * 1e3;
|
|
@@ -158892,7 +159114,7 @@ var import_path8 = __toESM(require("path"));
|
|
|
158892
159114
|
init_zod();
|
|
158893
159115
|
init_src2();
|
|
158894
159116
|
init_device_info();
|
|
158895
|
-
var
|
|
159117
|
+
var zodSchema75 = external_exports.object({
|
|
158896
159118
|
baselinePath: external_exports.string().min(1).optional().describe("Path to the baseline PNG file. Required unless captureBaseline is true."),
|
|
158897
159119
|
currentPath: external_exports.string().min(1).optional().describe("Path to the current PNG file. Required unless captureCurrent is true."),
|
|
158898
159120
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
@@ -158909,7 +159131,7 @@ var zodSchema73 = external_exports.object({
|
|
|
158909
159131
|
"Directory where diff artifacts should be written. Optional \u2014 defaults to a temp directory; the diff images are returned in the result either way."
|
|
158910
159132
|
)
|
|
158911
159133
|
}).strict();
|
|
158912
|
-
var
|
|
159134
|
+
var capability34 = {
|
|
158913
159135
|
apple: { simulator: true, device: true },
|
|
158914
159136
|
android: { emulator: true, device: true, unknown: true }
|
|
158915
159137
|
};
|
|
@@ -158922,7 +159144,7 @@ var screenshotDiffTool = {
|
|
|
158922
159144
|
id: "screenshot-diff",
|
|
158923
159145
|
interaction: {
|
|
158924
159146
|
startedMsg: () => "Comparing screenshots",
|
|
158925
|
-
completedMsg: () => "Compared screenshots",
|
|
159147
|
+
completedMsg: ({ result }) => summaryReportsDimensionMismatch(result.summary) ? "Skipped comparison - screenshot dimensions differ" : "Compared screenshots",
|
|
158926
159148
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to compare screenshots: ${failureSignal2.error_code}`
|
|
158927
159149
|
},
|
|
158928
159150
|
description: `Compare two PNG screenshots and return a compact visual-diff summary.
|
|
@@ -158934,8 +159156,8 @@ Returns { summary, diffPath, contextDiffPath }. The summary uses normalized [0,1
|
|
|
158934
159156
|
Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
|
|
158935
159157
|
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.`,
|
|
158936
159158
|
searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
|
|
158937
|
-
zodSchema:
|
|
158938
|
-
capability:
|
|
159159
|
+
zodSchema: zodSchema75,
|
|
159160
|
+
capability: capability34,
|
|
158939
159161
|
fileInputs: fileInputs7,
|
|
158940
159162
|
services: (params) => {
|
|
158941
159163
|
if (params.captureBaseline || params.captureCurrent) {
|
|
@@ -159248,7 +159470,7 @@ async function captureElementFrame(registry2, udid, match, opts = {}) {
|
|
|
159248
159470
|
}
|
|
159249
159471
|
|
|
159250
159472
|
// ../tool-server/src/tools/variants/propose-variant.ts
|
|
159251
|
-
var
|
|
159473
|
+
var zodSchema76 = external_exports.object({
|
|
159252
159474
|
element: external_exports.string().min(1).max(200).describe(
|
|
159253
159475
|
'Human name of the on-screen element this variant targets, e.g. "Foo button" or "profile header". Repeated calls with the same element accumulate multiple variants on it. Used as the default screen matcher when `match` is omitted.'
|
|
159254
159476
|
),
|
|
@@ -159308,7 +159530,7 @@ arrives as a follow-up message (this is the case in an \`argent lens\` CLI sessi
|
|
|
159308
159530
|
Returns { round, elementId, variantId, element, variantCount, totalElements } \u2014 confirmation only;
|
|
159309
159531
|
it does not wait for the user.`,
|
|
159310
159532
|
searchHint: "propose design variant alternative option for element non-blocking ab choice",
|
|
159311
|
-
zodSchema:
|
|
159533
|
+
zodSchema: zodSchema76,
|
|
159312
159534
|
services: () => ({}),
|
|
159313
159535
|
async execute(_services, params) {
|
|
159314
159536
|
let frame = params.variant.frame;
|
|
@@ -159332,7 +159554,7 @@ it does not wait for the user.`,
|
|
|
159332
159554
|
|
|
159333
159555
|
// ../tool-server/src/tools/variants/await-user-selection.ts
|
|
159334
159556
|
init_zod();
|
|
159335
|
-
var
|
|
159557
|
+
var zodSchema77 = external_exports.object({
|
|
159336
159558
|
timeoutSeconds: external_exports.number().int().min(5).max(86400).optional().describe(
|
|
159337
159559
|
"Max seconds to block this call before returning a re-awaitable { status: 'pending' } result (default 1800). The user's proposals stay live across timeouts \u2014 on 'pending' just call await_user_selection again. Lower this if your MCP client enforces a short request timeout."
|
|
159338
159560
|
)
|
|
@@ -159373,7 +159595,7 @@ This tool is long-running; it intentionally holds the request open. It honors cl
|
|
|
159373
159595
|
disconnects (aborts cleanly).`,
|
|
159374
159596
|
searchHint: "await wait user selection choice variant blocking confirm picks complete",
|
|
159375
159597
|
longRunning: true,
|
|
159376
|
-
zodSchema:
|
|
159598
|
+
zodSchema: zodSchema77,
|
|
159377
159599
|
services: () => ({}),
|
|
159378
159600
|
async execute(_services, params, options) {
|
|
159379
159601
|
const timeoutMs = (params.timeoutSeconds ?? 1800) * 1e3;
|
|
@@ -159388,7 +159610,7 @@ disconnects (aborts cleanly).`,
|
|
|
159388
159610
|
init_zod();
|
|
159389
159611
|
init_src2();
|
|
159390
159612
|
init_device_info();
|
|
159391
|
-
var
|
|
159613
|
+
var zodSchema78 = external_exports.object({
|
|
159392
159614
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
159393
159615
|
action: external_exports.enum(["list", "select", "new", "close"]).describe(
|
|
159394
159616
|
"list: enumerate tabs/windows. select: make a tab active (every other tool then acts on it). new: open a tab. close: close a tab."
|
|
@@ -159421,7 +159643,7 @@ var tabAction = {
|
|
|
159421
159643
|
failure: "close"
|
|
159422
159644
|
}
|
|
159423
159645
|
};
|
|
159424
|
-
var
|
|
159646
|
+
var capability35 = {
|
|
159425
159647
|
chromium: { app: true }
|
|
159426
159648
|
};
|
|
159427
159649
|
var chromiumTabsTool = {
|
|
@@ -159439,8 +159661,8 @@ var chromiumTabsTool = {
|
|
|
159439
159661
|
Use when an app exposes multiple windows or tabs and you need to inspect or drive one other than the current page, or to open/close a page during a flow. tabIds are stable for the session and never reused.
|
|
159440
159662
|
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.`,
|
|
159441
159663
|
searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
|
|
159442
|
-
zodSchema:
|
|
159443
|
-
capability:
|
|
159664
|
+
zodSchema: zodSchema78,
|
|
159665
|
+
capability: capability35,
|
|
159444
159666
|
services: (params) => {
|
|
159445
159667
|
const device = resolveDevice(params.udid);
|
|
159446
159668
|
if (device.platform === "chromium") {
|
|
@@ -159541,7 +159763,7 @@ async function clearStorage(cdp, type) {
|
|
|
159541
159763
|
}
|
|
159542
159764
|
|
|
159543
159765
|
// ../tool-server/src/tools/chromium-cookies/index.ts
|
|
159544
|
-
var
|
|
159766
|
+
var zodSchema79 = external_exports.object({
|
|
159545
159767
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
159546
159768
|
action: external_exports.enum(["get", "set", "delete", "clear"]).describe(
|
|
159547
159769
|
"get: read cookies. set: create/update a cookie. delete: remove a named cookie. clear: remove all browser cookies."
|
|
@@ -159564,7 +159786,7 @@ var cookieAction = {
|
|
|
159564
159786
|
delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
|
|
159565
159787
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
159566
159788
|
};
|
|
159567
|
-
var
|
|
159789
|
+
var capability36 = {
|
|
159568
159790
|
chromium: { app: true }
|
|
159569
159791
|
};
|
|
159570
159792
|
var chromiumCookiesTool = {
|
|
@@ -159582,8 +159804,8 @@ var chromiumCookiesTool = {
|
|
|
159582
159804
|
Use when seeding an authenticated session before a flow (set the session cookie, then navigate) or asserting cookie state after one.
|
|
159583
159805
|
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.`,
|
|
159584
159806
|
searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
|
|
159585
|
-
zodSchema:
|
|
159586
|
-
capability:
|
|
159807
|
+
zodSchema: zodSchema79,
|
|
159808
|
+
capability: capability36,
|
|
159587
159809
|
services: (params) => {
|
|
159588
159810
|
const device = resolveDevice(params.udid);
|
|
159589
159811
|
if (device.platform === "chromium") {
|
|
@@ -159648,7 +159870,7 @@ Returns { cookies, count } for get, or a small status object ({ set } / { delete
|
|
|
159648
159870
|
init_zod();
|
|
159649
159871
|
init_src2();
|
|
159650
159872
|
init_device_info();
|
|
159651
|
-
var
|
|
159873
|
+
var zodSchema80 = external_exports.object({
|
|
159652
159874
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
159653
159875
|
store: external_exports.enum(["local", "session"]).describe("Which Web Storage area: `local` (localStorage) or `session` (sessionStorage)."),
|
|
159654
159876
|
action: external_exports.enum(["get", "set", "remove", "clear"]).describe(
|
|
@@ -159663,7 +159885,7 @@ var storageAction = {
|
|
|
159663
159885
|
remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
|
|
159664
159886
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
159665
159887
|
};
|
|
159666
|
-
var
|
|
159888
|
+
var capability37 = {
|
|
159667
159889
|
chromium: { app: true }
|
|
159668
159890
|
};
|
|
159669
159891
|
var chromiumStorageTool = {
|
|
@@ -159682,8 +159904,8 @@ Set \`store\` to "local" or "session". Storage is per-origin, so it reflects the
|
|
|
159682
159904
|
Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one.
|
|
159683
159905
|
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.`,
|
|
159684
159906
|
searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
|
|
159685
|
-
zodSchema:
|
|
159686
|
-
capability:
|
|
159907
|
+
zodSchema: zodSchema80,
|
|
159908
|
+
capability: capability37,
|
|
159687
159909
|
services: (params) => {
|
|
159688
159910
|
const device = resolveDevice(params.udid);
|
|
159689
159911
|
if (device.platform === "chromium") {
|
|
@@ -159758,6 +159980,7 @@ function createRegistry() {
|
|
|
159758
159980
|
registry2.registerTool(createBootDeviceTool(registry2));
|
|
159759
159981
|
registry2.registerTool(createLaunchAppTool(registry2));
|
|
159760
159982
|
registry2.registerTool(createRestartAppTool(registry2));
|
|
159983
|
+
registry2.registerTool(terminateAppTool);
|
|
159761
159984
|
registry2.registerTool(reinstallAppTool);
|
|
159762
159985
|
registry2.registerTool(settingsPermissionsTool);
|
|
159763
159986
|
registry2.registerTool(openUrlTool);
|
|
@@ -159794,6 +160017,7 @@ function createRegistry() {
|
|
|
159794
160017
|
registry2.registerTool(networkRequestTool);
|
|
159795
160018
|
registry2.registerTool(createDescribeTool(registry2));
|
|
159796
160019
|
registry2.registerTool(createUiTreeTool(registry2));
|
|
160020
|
+
registry2.registerTool(createForegroundAppTool(registry2));
|
|
159797
160021
|
registry2.registerTool(createAwaitUiElementTool(registry2));
|
|
159798
160022
|
registry2.registerTool(createAwaitScreenIdleTool(registry2));
|
|
159799
160023
|
registry2.registerTool(createReactProfilerStartTool(registry2));
|
|
@@ -159864,13 +160088,13 @@ function probeArgentToolServer(host, port, timeoutMs = 500) {
|
|
|
159864
160088
|
|
|
159865
160089
|
// ../tool-server/src/utils/simulator-watcher.ts
|
|
159866
160090
|
var fs67 = __toESM(require("node:fs"));
|
|
159867
|
-
var
|
|
159868
|
-
var
|
|
160091
|
+
var import_node_child_process40 = require("node:child_process");
|
|
160092
|
+
var import_node_util28 = require("node:util");
|
|
159869
160093
|
init_external_devices();
|
|
159870
|
-
var
|
|
160094
|
+
var execFileAsync30 = (0, import_node_util28.promisify)(import_node_child_process40.execFile);
|
|
159871
160095
|
var POLL_INTERVAL_MS2 = 1e4;
|
|
159872
160096
|
async function getBootedUdidsInSet(deviceSet) {
|
|
159873
|
-
const { stdout } = await
|
|
160097
|
+
const { stdout } = await execFileAsync30("xcrun", [
|
|
159874
160098
|
...simctlPrefix(deviceSet),
|
|
159875
160099
|
"list",
|
|
159876
160100
|
"devices",
|
|
@@ -159989,7 +160213,7 @@ function startSimulatorWatcher(registry2) {
|
|
|
159989
160213
|
}
|
|
159990
160214
|
|
|
159991
160215
|
// ../tool-server/src/utils/preview-window.ts
|
|
159992
|
-
var
|
|
160216
|
+
var import_node_child_process41 = require("node:child_process");
|
|
159993
160217
|
var fs68 = __toESM(require("node:fs"));
|
|
159994
160218
|
var os20 = __toESM(require("node:os"));
|
|
159995
160219
|
var path51 = __toESM(require("node:path"));
|
|
@@ -160021,10 +160245,10 @@ function ensureLensAppBundle(electronBin) {
|
|
|
160021
160245
|
fs68.copyFileSync(path51.join(realContents, "Info.plist"), plist);
|
|
160022
160246
|
const setPlist = (entry, value) => {
|
|
160023
160247
|
try {
|
|
160024
|
-
(0,
|
|
160248
|
+
(0, import_node_child_process41.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Set :${entry} ${value}`, plist]);
|
|
160025
160249
|
} catch {
|
|
160026
160250
|
try {
|
|
160027
|
-
(0,
|
|
160251
|
+
(0, import_node_child_process41.execFileSync)("/usr/libexec/PlistBuddy", ["-c", `Add :${entry} string ${value}`, plist]);
|
|
160028
160252
|
} catch {
|
|
160029
160253
|
}
|
|
160030
160254
|
}
|
|
@@ -160063,9 +160287,9 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
160063
160287
|
if (fs68.existsSync(bundled)) return bundled;
|
|
160064
160288
|
return require.resolve("@argent/preview-window/dist/main.js");
|
|
160065
160289
|
};
|
|
160066
|
-
const
|
|
160290
|
+
const isAlive2 = (c) => c !== null && c.exitCode === null && !c.killed;
|
|
160067
160291
|
const ensureOpen = (url2) => {
|
|
160068
|
-
if (
|
|
160292
|
+
if (isAlive2(child) && !closing) {
|
|
160069
160293
|
send({ cmd: "foreground", url: url2 });
|
|
160070
160294
|
return;
|
|
160071
160295
|
}
|
|
@@ -160083,7 +160307,7 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
160083
160307
|
const wrapperBin = ensureLensAppBundle(electronBin);
|
|
160084
160308
|
const launchBin = wrapperBin ?? electronBin;
|
|
160085
160309
|
const launchArgs = wrapperBin ? ["--no-sandbox", mainScript] : [mainScript];
|
|
160086
|
-
const next = (0,
|
|
160310
|
+
const next = (0, import_node_child_process41.spawn)(launchBin, launchArgs, {
|
|
160087
160311
|
// Strips ELECTRON_RUN_AS_NODE, which an Electron-based MCP host leaves in
|
|
160088
160312
|
// our env, so the child boots as a GUI app instead of bare Node.
|
|
160089
160313
|
env: electronGuiChildEnv({ ARGENT_PREVIEW_URL: url2 }),
|
|
@@ -160110,12 +160334,12 @@ function createPreviewWindowManager(opts = {}) {
|
|
|
160110
160334
|
closing = false;
|
|
160111
160335
|
};
|
|
160112
160336
|
const requestClose = () => {
|
|
160113
|
-
if (!
|
|
160337
|
+
if (!isAlive2(child)) return;
|
|
160114
160338
|
closing = true;
|
|
160115
160339
|
send({ cmd: "close" });
|
|
160116
160340
|
};
|
|
160117
160341
|
const dispose = () => {
|
|
160118
|
-
if (
|
|
160342
|
+
if (isAlive2(child)) child.kill();
|
|
160119
160343
|
child = null;
|
|
160120
160344
|
closing = false;
|
|
160121
160345
|
};
|