@swmansion/argent 0.27.1-next.7 → 0.27.1-next.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-cmds.mjs +1 -1
- package/dist/client.d.ts +51 -0
- package/dist/installer.mjs +1 -1
- package/dist/tool-args.generated.d.ts +8 -0
- package/dist/tool-server.cjs +537 -319
- package/package.json +1 -1
package/dist/tool-server.cjs
CHANGED
|
@@ -13118,8 +13118,8 @@ function finalize(ctx, schema) {
|
|
|
13118
13118
|
const root = ctx.seen.get(schema);
|
|
13119
13119
|
if (!root)
|
|
13120
13120
|
throw new Error("Unprocessed schema. This is a bug in Zod.");
|
|
13121
|
-
const flattenRef = (
|
|
13122
|
-
const seen = ctx.seen.get(
|
|
13121
|
+
const flattenRef = (zodSchema79) => {
|
|
13122
|
+
const seen = ctx.seen.get(zodSchema79);
|
|
13123
13123
|
if (seen.ref === null)
|
|
13124
13124
|
return;
|
|
13125
13125
|
const schema2 = seen.def ?? seen.schema;
|
|
@@ -13137,7 +13137,7 @@ function finalize(ctx, schema) {
|
|
|
13137
13137
|
Object.assign(schema2, refSchema);
|
|
13138
13138
|
}
|
|
13139
13139
|
Object.assign(schema2, _cached);
|
|
13140
|
-
const isParentRef =
|
|
13140
|
+
const isParentRef = zodSchema79._zod.parent === ref;
|
|
13141
13141
|
if (isParentRef) {
|
|
13142
13142
|
for (const key2 in schema2) {
|
|
13143
13143
|
if (key2 === "$ref" || key2 === "allOf")
|
|
@@ -13157,7 +13157,7 @@ function finalize(ctx, schema) {
|
|
|
13157
13157
|
}
|
|
13158
13158
|
}
|
|
13159
13159
|
}
|
|
13160
|
-
const parent =
|
|
13160
|
+
const parent = zodSchema79._zod.parent;
|
|
13161
13161
|
if (parent && parent !== ref) {
|
|
13162
13162
|
flattenRef(parent);
|
|
13163
13163
|
const parentSeen = ctx.seen.get(parent);
|
|
@@ -13175,7 +13175,7 @@ function finalize(ctx, schema) {
|
|
|
13175
13175
|
}
|
|
13176
13176
|
}
|
|
13177
13177
|
ctx.override({
|
|
13178
|
-
zodSchema:
|
|
13178
|
+
zodSchema: zodSchema79,
|
|
13179
13179
|
jsonSchema: schema2,
|
|
13180
13180
|
path: seen.path ?? []
|
|
13181
13181
|
});
|
|
@@ -15976,10 +15976,10 @@ function convertBaseSchema(schema, ctx) {
|
|
|
15976
15976
|
}
|
|
15977
15977
|
ctx.processing.add(refPath);
|
|
15978
15978
|
const resolved = resolveRef(refPath, ctx);
|
|
15979
|
-
const
|
|
15980
|
-
ctx.refs.set(refPath,
|
|
15979
|
+
const zodSchema80 = convertSchema(resolved, ctx);
|
|
15980
|
+
ctx.refs.set(refPath, zodSchema80);
|
|
15981
15981
|
ctx.processing.delete(refPath);
|
|
15982
|
-
return
|
|
15982
|
+
return zodSchema80;
|
|
15983
15983
|
}
|
|
15984
15984
|
if (schema.enum !== void 0) {
|
|
15985
15985
|
const enumValues = schema.enum;
|
|
@@ -16021,7 +16021,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16021
16021
|
if (!type) {
|
|
16022
16022
|
return z.any();
|
|
16023
16023
|
}
|
|
16024
|
-
let
|
|
16024
|
+
let zodSchema79;
|
|
16025
16025
|
switch (type) {
|
|
16026
16026
|
case "string": {
|
|
16027
16027
|
let stringSchema = z.string();
|
|
@@ -16084,7 +16084,7 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16084
16084
|
if (schema.pattern) {
|
|
16085
16085
|
stringSchema = stringSchema.regex(new RegExp(schema.pattern));
|
|
16086
16086
|
}
|
|
16087
|
-
|
|
16087
|
+
zodSchema79 = stringSchema;
|
|
16088
16088
|
break;
|
|
16089
16089
|
}
|
|
16090
16090
|
case "number":
|
|
@@ -16109,15 +16109,15 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16109
16109
|
if (typeof schema.multipleOf === "number") {
|
|
16110
16110
|
numberSchema = numberSchema.multipleOf(schema.multipleOf);
|
|
16111
16111
|
}
|
|
16112
|
-
|
|
16112
|
+
zodSchema79 = numberSchema;
|
|
16113
16113
|
break;
|
|
16114
16114
|
}
|
|
16115
16115
|
case "boolean": {
|
|
16116
|
-
|
|
16116
|
+
zodSchema79 = z.boolean();
|
|
16117
16117
|
break;
|
|
16118
16118
|
}
|
|
16119
16119
|
case "null": {
|
|
16120
|
-
|
|
16120
|
+
zodSchema79 = z.null();
|
|
16121
16121
|
break;
|
|
16122
16122
|
}
|
|
16123
16123
|
case "object": {
|
|
@@ -16132,12 +16132,12 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16132
16132
|
const keySchema = convertSchema(schema.propertyNames, ctx);
|
|
16133
16133
|
const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) : z.any();
|
|
16134
16134
|
if (Object.keys(shape).length === 0) {
|
|
16135
|
-
|
|
16135
|
+
zodSchema79 = z.record(keySchema, valueSchema);
|
|
16136
16136
|
break;
|
|
16137
16137
|
}
|
|
16138
16138
|
const objectSchema2 = z.object(shape).passthrough();
|
|
16139
16139
|
const recordSchema = z.looseRecord(keySchema, valueSchema);
|
|
16140
|
-
|
|
16140
|
+
zodSchema79 = z.intersection(objectSchema2, recordSchema);
|
|
16141
16141
|
break;
|
|
16142
16142
|
}
|
|
16143
16143
|
if (schema.patternProperties) {
|
|
@@ -16155,25 +16155,25 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16155
16155
|
}
|
|
16156
16156
|
schemasToIntersect.push(...looseRecords);
|
|
16157
16157
|
if (schemasToIntersect.length === 0) {
|
|
16158
|
-
|
|
16158
|
+
zodSchema79 = z.object({}).passthrough();
|
|
16159
16159
|
} else if (schemasToIntersect.length === 1) {
|
|
16160
|
-
|
|
16160
|
+
zodSchema79 = schemasToIntersect[0];
|
|
16161
16161
|
} else {
|
|
16162
16162
|
let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);
|
|
16163
16163
|
for (let i = 2; i < schemasToIntersect.length; i++) {
|
|
16164
16164
|
result = z.intersection(result, schemasToIntersect[i]);
|
|
16165
16165
|
}
|
|
16166
|
-
|
|
16166
|
+
zodSchema79 = result;
|
|
16167
16167
|
}
|
|
16168
16168
|
break;
|
|
16169
16169
|
}
|
|
16170
16170
|
const objectSchema = z.object(shape);
|
|
16171
16171
|
if (schema.additionalProperties === false) {
|
|
16172
|
-
|
|
16172
|
+
zodSchema79 = objectSchema.strict();
|
|
16173
16173
|
} else if (typeof schema.additionalProperties === "object") {
|
|
16174
|
-
|
|
16174
|
+
zodSchema79 = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));
|
|
16175
16175
|
} else {
|
|
16176
|
-
|
|
16176
|
+
zodSchema79 = objectSchema.passthrough();
|
|
16177
16177
|
}
|
|
16178
16178
|
break;
|
|
16179
16179
|
}
|
|
@@ -16184,29 +16184,29 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16184
16184
|
const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
|
|
16185
16185
|
const rest = items && typeof items === "object" && !Array.isArray(items) ? convertSchema(items, ctx) : void 0;
|
|
16186
16186
|
if (rest) {
|
|
16187
|
-
|
|
16187
|
+
zodSchema79 = z.tuple(tupleItems).rest(rest);
|
|
16188
16188
|
} else {
|
|
16189
|
-
|
|
16189
|
+
zodSchema79 = z.tuple(tupleItems);
|
|
16190
16190
|
}
|
|
16191
16191
|
if (typeof schema.minItems === "number") {
|
|
16192
|
-
|
|
16192
|
+
zodSchema79 = zodSchema79.check(z.minLength(schema.minItems));
|
|
16193
16193
|
}
|
|
16194
16194
|
if (typeof schema.maxItems === "number") {
|
|
16195
|
-
|
|
16195
|
+
zodSchema79 = zodSchema79.check(z.maxLength(schema.maxItems));
|
|
16196
16196
|
}
|
|
16197
16197
|
} else if (Array.isArray(items)) {
|
|
16198
16198
|
const tupleItems = items.map((item) => convertSchema(item, ctx));
|
|
16199
16199
|
const rest = schema.additionalItems && typeof schema.additionalItems === "object" ? convertSchema(schema.additionalItems, ctx) : void 0;
|
|
16200
16200
|
if (rest) {
|
|
16201
|
-
|
|
16201
|
+
zodSchema79 = z.tuple(tupleItems).rest(rest);
|
|
16202
16202
|
} else {
|
|
16203
|
-
|
|
16203
|
+
zodSchema79 = z.tuple(tupleItems);
|
|
16204
16204
|
}
|
|
16205
16205
|
if (typeof schema.minItems === "number") {
|
|
16206
|
-
|
|
16206
|
+
zodSchema79 = zodSchema79.check(z.minLength(schema.minItems));
|
|
16207
16207
|
}
|
|
16208
16208
|
if (typeof schema.maxItems === "number") {
|
|
16209
|
-
|
|
16209
|
+
zodSchema79 = zodSchema79.check(z.maxLength(schema.maxItems));
|
|
16210
16210
|
}
|
|
16211
16211
|
} else if (items !== void 0) {
|
|
16212
16212
|
const element = convertSchema(items, ctx);
|
|
@@ -16217,16 +16217,16 @@ function convertBaseSchema(schema, ctx) {
|
|
|
16217
16217
|
if (typeof schema.maxItems === "number") {
|
|
16218
16218
|
arraySchema = arraySchema.max(schema.maxItems);
|
|
16219
16219
|
}
|
|
16220
|
-
|
|
16220
|
+
zodSchema79 = arraySchema;
|
|
16221
16221
|
} else {
|
|
16222
|
-
|
|
16222
|
+
zodSchema79 = z.array(z.any());
|
|
16223
16223
|
}
|
|
16224
16224
|
break;
|
|
16225
16225
|
}
|
|
16226
16226
|
default:
|
|
16227
16227
|
throw new Error(`Unsupported type: ${type}`);
|
|
16228
16228
|
}
|
|
16229
|
-
return
|
|
16229
|
+
return zodSchema79;
|
|
16230
16230
|
}
|
|
16231
16231
|
function convertSchema(schema, ctx) {
|
|
16232
16232
|
if (typeof schema === "boolean") {
|
|
@@ -73549,16 +73549,16 @@ function lookupExternalDeviceNow(id) {
|
|
|
73549
73549
|
}
|
|
73550
73550
|
return device;
|
|
73551
73551
|
}
|
|
73552
|
-
async function assertExternalCapability(namespace, device,
|
|
73553
|
-
assertExternalCapabilitySync(namespace, device,
|
|
73552
|
+
async function assertExternalCapability(namespace, device, capability36) {
|
|
73553
|
+
assertExternalCapabilitySync(namespace, device, capability36);
|
|
73554
73554
|
}
|
|
73555
|
-
function assertExternalCapabilitySync(namespace, device,
|
|
73555
|
+
function assertExternalCapabilitySync(namespace, device, capability36) {
|
|
73556
73556
|
const id = typeof device === "string" ? device : device.id;
|
|
73557
73557
|
const externalDevice = isExternalId(id) ? lookupExternalDeviceNow(id) : externalClaimForNativeId(id);
|
|
73558
73558
|
if (!externalDevice) return;
|
|
73559
|
-
if (externalDevice.capabilities.has(
|
|
73559
|
+
if (externalDevice.capabilities.has(capability36)) return;
|
|
73560
73560
|
throw new FailureError(
|
|
73561
|
-
`${namespace} is not available on '${externalDevice.name}': ${externalDevice.provider.name} did not grant the '${
|
|
73561
|
+
`${namespace} is not available on '${externalDevice.name}': ${externalDevice.provider.name} did not grant the '${capability36}' capability for this device.`,
|
|
73562
73562
|
{
|
|
73563
73563
|
error_code: FAILURE_CODES.EXTERNAL_DEVICE_CAPABILITY_DENIED,
|
|
73564
73564
|
error_kind: "unsupported",
|
|
@@ -94814,7 +94814,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
94814
94814
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
94815
94815
|
function readCliVersion() {
|
|
94816
94816
|
if (true) {
|
|
94817
|
-
return "0.27.1-next.
|
|
94817
|
+
return "0.27.1-next.8";
|
|
94818
94818
|
}
|
|
94819
94819
|
return "0.0.0";
|
|
94820
94820
|
}
|
|
@@ -96588,8 +96588,8 @@ async function simctlArgsForUdid(udid, args, options) {
|
|
|
96588
96588
|
return [...simctlPrefix(await deviceSetForUdid(udid)), ...nativeArgs(udid, args)];
|
|
96589
96589
|
}
|
|
96590
96590
|
function assertSimctlEntitlement(udid, options) {
|
|
96591
|
-
const
|
|
96592
|
-
assertExternalCapabilitySync(
|
|
96591
|
+
const capability36 = options?.granted ?? "simctl";
|
|
96592
|
+
assertExternalCapabilitySync(capability36, udid, capability36);
|
|
96593
96593
|
}
|
|
96594
96594
|
async function simctlTargetForUdid(udid, options) {
|
|
96595
96595
|
assertSimctlEntitlement(udid, options);
|
|
@@ -97632,6 +97632,26 @@ var axServiceBlueprint = {
|
|
|
97632
97632
|
elements: result.elements ?? []
|
|
97633
97633
|
};
|
|
97634
97634
|
},
|
|
97635
|
+
async tree() {
|
|
97636
|
+
let result;
|
|
97637
|
+
try {
|
|
97638
|
+
result = await query("tree", 1e4);
|
|
97639
|
+
} catch (err) {
|
|
97640
|
+
if (!(err instanceof Error) || err.message !== "unknown_command") throw err;
|
|
97641
|
+
throw new FailureError("ax-service predates `tree`; update argent", {
|
|
97642
|
+
error_code: FAILURE_CODES.AX_QUERY_FAILED,
|
|
97643
|
+
failure_stage: "ax_service_tree",
|
|
97644
|
+
failure_area: "tool_server",
|
|
97645
|
+
error_kind: "unknown"
|
|
97646
|
+
});
|
|
97647
|
+
}
|
|
97648
|
+
return {
|
|
97649
|
+
alertVisible: result.alertVisible ?? false,
|
|
97650
|
+
screenFrame: result.screenFrame,
|
|
97651
|
+
nodes: result.nodes ?? [],
|
|
97652
|
+
truncated: result.truncated === true
|
|
97653
|
+
};
|
|
97654
|
+
},
|
|
97635
97655
|
async livePanel() {
|
|
97636
97656
|
const result = await query("live_panel", LIVE_PANEL_TIMEOUT_MS);
|
|
97637
97657
|
if (result.error) {
|
|
@@ -97741,23 +97761,23 @@ var InvalidToolInputError = class extends Error {
|
|
|
97741
97761
|
});
|
|
97742
97762
|
}
|
|
97743
97763
|
};
|
|
97744
|
-
function platformMatrix(platform,
|
|
97764
|
+
function platformMatrix(platform, capability36) {
|
|
97745
97765
|
switch (platform) {
|
|
97746
97766
|
case "ios":
|
|
97747
|
-
return
|
|
97767
|
+
return capability36.apple;
|
|
97748
97768
|
case "ios-remote":
|
|
97749
|
-
return
|
|
97769
|
+
return capability36.appleRemote;
|
|
97750
97770
|
case "android":
|
|
97751
|
-
return
|
|
97771
|
+
return capability36.android;
|
|
97752
97772
|
case "chromium":
|
|
97753
|
-
return
|
|
97773
|
+
return capability36.chromium;
|
|
97754
97774
|
case "vega":
|
|
97755
|
-
return
|
|
97775
|
+
return capability36.vega;
|
|
97756
97776
|
}
|
|
97757
97777
|
}
|
|
97758
|
-
function assertSupported(toolId,
|
|
97759
|
-
if (!
|
|
97760
|
-
const matrix = platformMatrix(device.platform,
|
|
97778
|
+
function assertSupported(toolId, capability36, device) {
|
|
97779
|
+
if (!capability36) return;
|
|
97780
|
+
const matrix = platformMatrix(device.platform, capability36);
|
|
97761
97781
|
if (!matrix) {
|
|
97762
97782
|
throw new UnsupportedOperationError(toolId, device, `no ${device.platform} support declared`);
|
|
97763
97783
|
}
|
|
@@ -97765,7 +97785,7 @@ function assertSupported(toolId, capability35, device) {
|
|
|
97765
97785
|
if (!supported) {
|
|
97766
97786
|
throw new UnsupportedOperationError(toolId, device, `kind '${device.kind}' not supported`);
|
|
97767
97787
|
}
|
|
97768
|
-
if (
|
|
97788
|
+
if (capability36.supports && !capability36.supports(device)) {
|
|
97769
97789
|
throw new UnsupportedOperationError(toolId, device, "supports() refiner rejected device");
|
|
97770
97790
|
}
|
|
97771
97791
|
}
|
|
@@ -122170,10 +122190,24 @@ function makeIosImpl(registry2) {
|
|
|
122170
122190
|
const blocked = await precheckNativeDevtools(nativeDevtools, params.udid);
|
|
122171
122191
|
if (blocked) return blocked;
|
|
122172
122192
|
}
|
|
122193
|
+
if (params.launchArgs?.length) {
|
|
122194
|
+
try {
|
|
122195
|
+
await execFileAsync19(
|
|
122196
|
+
"xcrun",
|
|
122197
|
+
await simctlArgsForUdid(params.udid, ["terminate", params.udid, params.bundleId])
|
|
122198
|
+
);
|
|
122199
|
+
} catch {
|
|
122200
|
+
}
|
|
122201
|
+
}
|
|
122173
122202
|
try {
|
|
122174
122203
|
await execFileAsync19(
|
|
122175
122204
|
"xcrun",
|
|
122176
|
-
await simctlArgsForUdid(params.udid, [
|
|
122205
|
+
await simctlArgsForUdid(params.udid, [
|
|
122206
|
+
"launch",
|
|
122207
|
+
params.udid,
|
|
122208
|
+
params.bundleId,
|
|
122209
|
+
...params.launchArgs ?? []
|
|
122210
|
+
])
|
|
122177
122211
|
);
|
|
122178
122212
|
} catch (err) {
|
|
122179
122213
|
throw new FailureError(
|
|
@@ -122272,8 +122306,14 @@ function buildIosLaunchHandler(backend) {
|
|
|
122272
122306
|
return async (services, params) => {
|
|
122273
122307
|
const blocked = await precheckNativeDevtools(services.nativeDevtools, params.udid);
|
|
122274
122308
|
if (blocked) return blocked;
|
|
122309
|
+
if (params.launchArgs?.length) {
|
|
122310
|
+
try {
|
|
122311
|
+
await backend.terminate(params.udid, params.bundleId);
|
|
122312
|
+
} catch {
|
|
122313
|
+
}
|
|
122314
|
+
}
|
|
122275
122315
|
try {
|
|
122276
|
-
await backend.launch(params.udid, params.bundleId);
|
|
122316
|
+
await backend.launch(params.udid, params.bundleId, params.launchArgs);
|
|
122277
122317
|
} catch (err) {
|
|
122278
122318
|
throw new FailureError(
|
|
122279
122319
|
`Failed to launch iOS app ${params.bundleId} on ${params.udid}.`,
|
|
@@ -122408,6 +122448,9 @@ var zodSchema10 = external_exports.object({
|
|
|
122408
122448
|
),
|
|
122409
122449
|
activity: external_exports.string().regex(ACTIVITY_PATTERN, "activity may only contain letters, digits, '.', '_', '-' and '/'").optional().describe(
|
|
122410
122450
|
"Android-only: fully-qualified Activity name (e.g. `.MainActivity` or `com.example/com.example.MainActivity`). If omitted on Android, the app's default launcher activity is used. Ignored on iOS / Chromium."
|
|
122451
|
+
),
|
|
122452
|
+
launchArgs: external_exports.array(external_exports.string()).optional().describe(
|
|
122453
|
+
'Apple simulators only: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. A running app is relaunched to apply them. Ignored on other targets, including a physical iPhone.'
|
|
122411
122454
|
)
|
|
122412
122455
|
});
|
|
122413
122456
|
var capability2 = {
|
|
@@ -122487,7 +122530,10 @@ function makeIosImpl2(registry2) {
|
|
|
122487
122530
|
} catch {
|
|
122488
122531
|
}
|
|
122489
122532
|
try {
|
|
122490
|
-
await execFileAsync20(
|
|
122533
|
+
await execFileAsync20(
|
|
122534
|
+
"xcrun",
|
|
122535
|
+
await simctlArgsForUdid(udid, ["launch", udid, bundleId, ...params.launchArgs ?? []])
|
|
122536
|
+
);
|
|
122491
122537
|
} catch (err) {
|
|
122492
122538
|
throw new FailureError(
|
|
122493
122539
|
`Failed to restart iOS app ${bundleId} on ${udid}.`,
|
|
@@ -122537,7 +122583,7 @@ function buildIosRestartHandler(backend) {
|
|
|
122537
122583
|
} catch {
|
|
122538
122584
|
}
|
|
122539
122585
|
try {
|
|
122540
|
-
await backend.launch(udid, bundleId);
|
|
122586
|
+
await backend.launch(udid, bundleId, params.launchArgs);
|
|
122541
122587
|
} catch (err) {
|
|
122542
122588
|
throw new FailureError(
|
|
122543
122589
|
`Failed to restart iOS app ${bundleId} on ${udid}.`,
|
|
@@ -122619,6 +122665,9 @@ var zodSchema11 = external_exports.object({
|
|
|
122619
122665
|
bundleId: external_exports.string().min(1).regex(BUNDLE_ID_PATTERN, BUNDLE_ID_MESSAGE).describe("App identifier. iOS: bundle id. Android: package name."),
|
|
122620
122666
|
activity: external_exports.string().regex(ACTIVITY_PATTERN2, "activity may only contain letters, digits, '.', '_', '-' and '/'").optional().describe(
|
|
122621
122667
|
"Android-only: relaunch a non-launcher Activity (e.g. `.SettingsActivity` or `com.example/com.example.SettingsActivity`). If omitted, the app's default launcher activity is used. Ignored on iOS."
|
|
122668
|
+
),
|
|
122669
|
+
launchArgs: external_exports.array(external_exports.string()).optional().describe(
|
|
122670
|
+
'Apple simulators only: arguments passed to the app process at launch, e.g. `["-FeatureFlag", "YES"]` to override UserDefaults. Ignored on other targets, including a physical iPhone.'
|
|
122622
122671
|
)
|
|
122623
122672
|
});
|
|
122624
122673
|
var capability3 = {
|
|
@@ -126800,9 +126849,9 @@ async function invokeSubTool(registry2, ctx, toolId, args) {
|
|
|
126800
126849
|
}
|
|
126801
126850
|
function describeNestedParamError(registry2, err, toolId, dispatchedArgs, authoredArgs) {
|
|
126802
126851
|
if (getFailureSignal(err)?.error_code !== FAILURE_CODES.TOOL_INPUT_INVALID) return void 0;
|
|
126803
|
-
const
|
|
126804
|
-
if (!
|
|
126805
|
-
const parsed =
|
|
126852
|
+
const zodSchema79 = registry2.getTool(toolId)?.zodSchema;
|
|
126853
|
+
if (!zodSchema79) return void 0;
|
|
126854
|
+
const parsed = zodSchema79.safeParse(dispatchedArgs ?? {});
|
|
126806
126855
|
if (parsed.success) return void 0;
|
|
126807
126856
|
return `Invalid params for tool "${toolId}": ${describeParamIssues(parsed.error, authoredArgs)}`;
|
|
126808
126857
|
}
|
|
@@ -136060,6 +136109,334 @@ back/menu/home), then call describe again to confirm where focus landed.`,
|
|
|
136060
136109
|
};
|
|
136061
136110
|
}
|
|
136062
136111
|
|
|
136112
|
+
// ../tool-server/src/tools/ui-tree/index.ts
|
|
136113
|
+
init_zod();
|
|
136114
|
+
|
|
136115
|
+
// ../tool-server/src/tools/ui-tree/ios.ts
|
|
136116
|
+
var UNSUPPORTED_FIELDS = [
|
|
136117
|
+
"type",
|
|
136118
|
+
"password",
|
|
136119
|
+
"placeholder",
|
|
136120
|
+
"hintShowing",
|
|
136121
|
+
"hidden",
|
|
136122
|
+
"foregroundApp"
|
|
136123
|
+
];
|
|
136124
|
+
function adaptAxTree(response) {
|
|
136125
|
+
const byIndex = /* @__PURE__ */ new Map();
|
|
136126
|
+
const roots = [];
|
|
136127
|
+
let keyboardVisible = false;
|
|
136128
|
+
for (const raw of response.nodes) {
|
|
136129
|
+
const traits = raw.traits ?? [];
|
|
136130
|
+
const has = (name) => traits.includes(name);
|
|
136131
|
+
if (has("keyboardKey")) keyboardVisible = true;
|
|
136132
|
+
const node = {
|
|
136133
|
+
role: mapNativeTraitsToDescribeRole(traits),
|
|
136134
|
+
label: raw.label,
|
|
136135
|
+
value: raw.value,
|
|
136136
|
+
identifier: raw.identifier,
|
|
136137
|
+
roleDescription: raw.roleDescription,
|
|
136138
|
+
frame: raw.frame,
|
|
136139
|
+
children: []
|
|
136140
|
+
};
|
|
136141
|
+
if (traits.length > 0) node.traits = traits;
|
|
136142
|
+
if (has("header")) node.heading = true;
|
|
136143
|
+
if (has("notEnabled")) node.disabled = true;
|
|
136144
|
+
if (has("selected")) node.selected = true;
|
|
136145
|
+
if (has("isEditing")) node.focused = true;
|
|
136146
|
+
if (has("textEntry") || has("searchField")) node.editable = true;
|
|
136147
|
+
if (has("toggleButton") && (raw.value === "1" || raw.value === "0")) {
|
|
136148
|
+
node.checked = raw.value === "1";
|
|
136149
|
+
}
|
|
136150
|
+
if (raw.covered) node.covered = true;
|
|
136151
|
+
const parent = raw.parentIndex === void 0 ? void 0 : byIndex.get(raw.parentIndex);
|
|
136152
|
+
byIndex.set(raw.index, node);
|
|
136153
|
+
(parent ? parent.children : roots).push(node);
|
|
136154
|
+
}
|
|
136155
|
+
return {
|
|
136156
|
+
schemaVersion: 1,
|
|
136157
|
+
source: "ax-service",
|
|
136158
|
+
screen: response.screenFrame,
|
|
136159
|
+
roots,
|
|
136160
|
+
truncated: response.truncated,
|
|
136161
|
+
alertVisible: response.alertVisible,
|
|
136162
|
+
// A truncated walk may have cut the keyboard, so absence is unknown there.
|
|
136163
|
+
keyboardVisible: keyboardVisible || (response.truncated ? void 0 : false),
|
|
136164
|
+
unsupportedFields: UNSUPPORTED_FIELDS
|
|
136165
|
+
};
|
|
136166
|
+
}
|
|
136167
|
+
async function readIosUiTree(registry2, device) {
|
|
136168
|
+
const ref = axServiceRef(device);
|
|
136169
|
+
const ax = await registry2.resolveService(ref.urn, ref.options);
|
|
136170
|
+
return adaptAxTree(await ax.tree());
|
|
136171
|
+
}
|
|
136172
|
+
|
|
136173
|
+
// ../tool-server/src/tools/flows/flow-tree-flatten.ts
|
|
136174
|
+
function intersectClip(rect, clip3) {
|
|
136175
|
+
if (!clip3) return rect;
|
|
136176
|
+
const x1 = Math.max(rect.x, clip3.x);
|
|
136177
|
+
const y1 = Math.max(rect.y, clip3.y);
|
|
136178
|
+
const x2 = Math.min(rect.x + rect.w, clip3.x + clip3.w);
|
|
136179
|
+
const y2 = Math.min(rect.y + rect.h, clip3.y + clip3.h);
|
|
136180
|
+
return { x: x1, y: y1, w: Math.max(0, x2 - x1), h: Math.max(0, y2 - y1) };
|
|
136181
|
+
}
|
|
136182
|
+
function includesWordsCI(haystack, needle) {
|
|
136183
|
+
const h = haystack.toLowerCase();
|
|
136184
|
+
const n = needle.toLowerCase();
|
|
136185
|
+
if (!n) return false;
|
|
136186
|
+
const isWordChar = (c) => c !== void 0 && /[\p{L}\p{N}]/u.test(c);
|
|
136187
|
+
for (let at = h.indexOf(n); at !== -1; at = h.indexOf(n, at + 1)) {
|
|
136188
|
+
if (!isWordChar(h[at - 1]) && !isWordChar(h[at + n.length])) return true;
|
|
136189
|
+
}
|
|
136190
|
+
return false;
|
|
136191
|
+
}
|
|
136192
|
+
function flattenHoisting(node, project, out, scrollClip = null) {
|
|
136193
|
+
const view = project(node);
|
|
136194
|
+
if (view.skip) return "";
|
|
136195
|
+
if (scrollClip && view.rect && rectFullyOutside(view.rect, scrollClip)) return "";
|
|
136196
|
+
const childClip = view.scrolls && view.rect ? intersectClip(view.rect, scrollClip) : scrollClip;
|
|
136197
|
+
const childText = [];
|
|
136198
|
+
for (const child of view.children) {
|
|
136199
|
+
const t = flattenHoisting(child, project, out, childClip);
|
|
136200
|
+
if (t) childText.push(t);
|
|
136201
|
+
}
|
|
136202
|
+
const descendantText2 = childText.join(" ");
|
|
136203
|
+
const subtree = view.ownText && !includesWordsCI(descendantText2, view.ownText) ? [view.ownText, descendantText2].filter(Boolean).join(" ") : descendantText2 || view.ownText;
|
|
136204
|
+
if (view.leaf) {
|
|
136205
|
+
if (subtree && subtree !== view.ownText) view.leaf.subtreeText = subtree;
|
|
136206
|
+
out.push(view.leaf);
|
|
136207
|
+
}
|
|
136208
|
+
return view.shield ? "" : subtree;
|
|
136209
|
+
}
|
|
136210
|
+
|
|
136211
|
+
// ../tool-server/src/tools/flows/flow-android-tree.ts
|
|
136212
|
+
var FLOW_MAX_NODES = 12e3;
|
|
136213
|
+
var SYSTEM_PACKAGES2 = /* @__PURE__ */ new Set(["com.android.systemui"]);
|
|
136214
|
+
var SYSTEM_RID_PREFIXES2 = [
|
|
136215
|
+
"android:id/navigationBarBackground",
|
|
136216
|
+
"android:id/statusBarBackground",
|
|
136217
|
+
"com.android.systemui:id/"
|
|
136218
|
+
];
|
|
136219
|
+
function isSystemChrome2(attrs) {
|
|
136220
|
+
if (SYSTEM_PACKAGES2.has(attrs.package ?? "")) return true;
|
|
136221
|
+
const rid = attrs["resource-id"] ?? "";
|
|
136222
|
+
return SYSTEM_RID_PREFIXES2.some((p) => rid.startsWith(p));
|
|
136223
|
+
}
|
|
136224
|
+
function labelOf2(attrs) {
|
|
136225
|
+
const cd = (attrs["content-desc"] ?? "").trim();
|
|
136226
|
+
if (cd) return cd;
|
|
136227
|
+
return (attrs.text ?? "").trim();
|
|
136228
|
+
}
|
|
136229
|
+
function normalizeRect(rect, screenW, screenH) {
|
|
136230
|
+
const clipped = clipBoundsToScreen(rect, screenW, screenH);
|
|
136231
|
+
if (clipped.w <= 0 || clipped.h <= 0) return null;
|
|
136232
|
+
return {
|
|
136233
|
+
x: clipped.x / screenW,
|
|
136234
|
+
y: clipped.y / screenH,
|
|
136235
|
+
width: clipped.w / screenW,
|
|
136236
|
+
height: clipped.h / screenH
|
|
136237
|
+
};
|
|
136238
|
+
}
|
|
136239
|
+
function childNodes(node) {
|
|
136240
|
+
return node.children.filter((c) => c.tag === "node");
|
|
136241
|
+
}
|
|
136242
|
+
function projectAndroidNode(node, screenW, screenH) {
|
|
136243
|
+
const attrs = node.attrs;
|
|
136244
|
+
const skip2 = isSystemChrome2(attrs) || isNoisyUiAutomatorClass(attrs.class ?? "");
|
|
136245
|
+
const identifier = (attrs["resource-id"] ?? "").trim();
|
|
136246
|
+
const isPassword = attrs.password === "true";
|
|
136247
|
+
const isFocused = attrs.focused === "true";
|
|
136248
|
+
const label = isPassword ? "[password]" : labelOf2(attrs);
|
|
136249
|
+
const rawText = (attrs.text ?? "").trim();
|
|
136250
|
+
const hasValue = !isPassword && Boolean(rawText) && rawText !== label;
|
|
136251
|
+
const className = attrs.class ?? "";
|
|
136252
|
+
const role = deriveUiAutomatorRole(className);
|
|
136253
|
+
const hasSemanticRole = !isUiAutomatorLayoutContainer(className);
|
|
136254
|
+
const ownText2 = [label, hasValue ? rawText : ""].filter(Boolean).join(" ");
|
|
136255
|
+
const rect = parseUiAutomatorBounds(attrs.bounds ?? "");
|
|
136256
|
+
let leaf = null;
|
|
136257
|
+
let frame = null;
|
|
136258
|
+
if (!skip2 && (identifier || label || hasSemanticRole || isFocused)) {
|
|
136259
|
+
frame = rect ? normalizeRect(rect, screenW, screenH) : null;
|
|
136260
|
+
if (frame) {
|
|
136261
|
+
leaf = { role, frame, children: [] };
|
|
136262
|
+
if (label) leaf.label = label;
|
|
136263
|
+
if (identifier) leaf.identifier = identifier;
|
|
136264
|
+
if (hasValue) leaf.value = rawText;
|
|
136265
|
+
if (attrs.clickable === "true") leaf.clickable = true;
|
|
136266
|
+
if (attrs["long-clickable"] === "true") leaf.longClickable = true;
|
|
136267
|
+
if (attrs.scrollable === "true") leaf.scrollable = true;
|
|
136268
|
+
if (attrs.checkable === "true") leaf.checkable = true;
|
|
136269
|
+
if (attrs.checked === "true") leaf.checked = true;
|
|
136270
|
+
if (attrs.enabled === "false") leaf.disabled = true;
|
|
136271
|
+
if (isPassword) leaf.password = true;
|
|
136272
|
+
if (isFocused) leaf.focused = true;
|
|
136273
|
+
}
|
|
136274
|
+
}
|
|
136275
|
+
return {
|
|
136276
|
+
skip: skip2,
|
|
136277
|
+
children: childNodes(node),
|
|
136278
|
+
// Off-screen text must not hoist, or an ancestor text assert would pass on
|
|
136279
|
+
// content the screen doesn't show. Any node with text is leaf-eligible (its
|
|
136280
|
+
// label is non-empty), so `frame` was computed for it.
|
|
136281
|
+
ownText: frame ? ownText2 : "",
|
|
136282
|
+
leaf,
|
|
136283
|
+
// A password field shields even when it carries no id, so nothing from it
|
|
136284
|
+
// bubbles into an ancestor's hoisted text.
|
|
136285
|
+
shield: Boolean(identifier) || isPassword,
|
|
136286
|
+
// Scroll-clip inputs (see `flattenHoisting`): a scroller's raw bounds clip
|
|
136287
|
+
// its subtree, so a row scrolled out of view — but still on the device
|
|
136288
|
+
// screen — is dropped, matching the describe path's prune.
|
|
136289
|
+
rect,
|
|
136290
|
+
scrolls: isUiAutomatorScrollable(attrs)
|
|
136291
|
+
};
|
|
136292
|
+
}
|
|
136293
|
+
function adaptFullAndroidHierarchyToDescribeResult(xml, screenW, screenH) {
|
|
136294
|
+
const children = [];
|
|
136295
|
+
if (screenW > 0 && screenH > 0) {
|
|
136296
|
+
const root = parseUiAutomatorXml(xml);
|
|
136297
|
+
if (root) {
|
|
136298
|
+
for (const c of childNodes(root)) {
|
|
136299
|
+
flattenHoisting(c, (n) => projectAndroidNode(n, screenW, screenH), children);
|
|
136300
|
+
}
|
|
136301
|
+
}
|
|
136302
|
+
}
|
|
136303
|
+
return parseDescribeResult({
|
|
136304
|
+
role: "Screen",
|
|
136305
|
+
frame: { x: 0, y: 0, width: 1, height: 1 },
|
|
136306
|
+
children
|
|
136307
|
+
});
|
|
136308
|
+
}
|
|
136309
|
+
async function queryAndroidFullHierarchy(registry2, device) {
|
|
136310
|
+
let devtools;
|
|
136311
|
+
try {
|
|
136312
|
+
const ref = androidDevtoolsRef(device);
|
|
136313
|
+
devtools = await registry2.resolveService(ref.urn, ref.options);
|
|
136314
|
+
} catch (err) {
|
|
136315
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
136316
|
+
throw new Error(`the argent android helper is unavailable: ${msg}`, { cause: err });
|
|
136317
|
+
}
|
|
136318
|
+
const [{ xml }, size] = await Promise.all([
|
|
136319
|
+
// clearCache: await/assert polls must see text changes, not cached reads.
|
|
136320
|
+
devtools.getHierarchy({ maxNodes: FLOW_MAX_NODES, clearCache: true }),
|
|
136321
|
+
devtools.getScreenSize()
|
|
136322
|
+
]);
|
|
136323
|
+
const tree = adaptFullAndroidHierarchyToDescribeResult(xml, size.width, size.height);
|
|
136324
|
+
return {
|
|
136325
|
+
tree,
|
|
136326
|
+
source: "android-devtools",
|
|
136327
|
+
...size.width > 0 && size.height > 0 ? { screen: { width: size.width, height: size.height } } : {}
|
|
136328
|
+
};
|
|
136329
|
+
}
|
|
136330
|
+
|
|
136331
|
+
// ../tool-server/src/tools/ui-tree/android.ts
|
|
136332
|
+
var UNSUPPORTED_FIELDS2 = [
|
|
136333
|
+
"placeholder",
|
|
136334
|
+
"hintShowing",
|
|
136335
|
+
"hidden",
|
|
136336
|
+
"heading",
|
|
136337
|
+
"keyboardVisible",
|
|
136338
|
+
"foregroundApp"
|
|
136339
|
+
];
|
|
136340
|
+
function mapNode(xml, screenW, screenH, isRoot) {
|
|
136341
|
+
const a = xml.attrs;
|
|
136342
|
+
const type = a.class ?? "";
|
|
136343
|
+
const password = attrIsTrue(a, "password");
|
|
136344
|
+
const text = password ? "" : a.text ?? "";
|
|
136345
|
+
const desc = a["content-desc"] ?? "";
|
|
136346
|
+
const rect = parseUiAutomatorBounds(a.bounds ?? "");
|
|
136347
|
+
const editable = type.endsWith("EditText") || type.endsWith("AutoCompleteTextView");
|
|
136348
|
+
const node = { role: deriveUiAutomatorRole(type), children: [] };
|
|
136349
|
+
if (type) node.type = type;
|
|
136350
|
+
if (text || desc) node.label = text || desc;
|
|
136351
|
+
if (editable && text) node.value = text;
|
|
136352
|
+
if (desc) node.contentDescription = desc;
|
|
136353
|
+
if (a["resource-id"]) node.identifier = a["resource-id"];
|
|
136354
|
+
if (isRoot && a.package) node.bundleId = a.package;
|
|
136355
|
+
if (rect && screenW > 0 && screenH > 0) {
|
|
136356
|
+
node.frame = {
|
|
136357
|
+
x: rect.x / screenW,
|
|
136358
|
+
y: rect.y / screenH,
|
|
136359
|
+
width: rect.w / screenW,
|
|
136360
|
+
height: rect.h / screenH
|
|
136361
|
+
};
|
|
136362
|
+
}
|
|
136363
|
+
if (a.enabled === "false") node.disabled = true;
|
|
136364
|
+
if (attrIsTrue(a, "selected")) node.selected = true;
|
|
136365
|
+
if (attrIsTrue(a, "focused")) node.focused = true;
|
|
136366
|
+
if (attrIsTrue(a, "checkable")) node.checked = attrIsTrue(a, "checked");
|
|
136367
|
+
if (password) node.password = true;
|
|
136368
|
+
if (editable) node.editable = true;
|
|
136369
|
+
for (const child of xml.children) {
|
|
136370
|
+
if (child.tag === "node") node.children.push(mapNode(child, screenW, screenH, false));
|
|
136371
|
+
}
|
|
136372
|
+
return node;
|
|
136373
|
+
}
|
|
136374
|
+
function adaptAndroidTree(xml, truncated, screen) {
|
|
136375
|
+
const root = parseUiAutomatorXml(xml);
|
|
136376
|
+
const roots = (root?.children ?? []).filter((c) => c.tag === "node").map((c) => mapNode(c, screen.width, screen.height, true));
|
|
136377
|
+
return {
|
|
136378
|
+
schemaVersion: 1,
|
|
136379
|
+
source: "android-devtools",
|
|
136380
|
+
screen: { width: screen.width, height: screen.height },
|
|
136381
|
+
roots,
|
|
136382
|
+
truncated,
|
|
136383
|
+
unsupportedFields: UNSUPPORTED_FIELDS2
|
|
136384
|
+
};
|
|
136385
|
+
}
|
|
136386
|
+
async function readAndroidUiTree(registry2, device) {
|
|
136387
|
+
const ref = androidDevtoolsRef(device);
|
|
136388
|
+
const devtools = await registry2.resolveService(ref.urn, ref.options);
|
|
136389
|
+
const [{ xml, truncated }, size] = await Promise.all([
|
|
136390
|
+
devtools.getHierarchy({ maxNodes: FLOW_MAX_NODES, clearCache: true }),
|
|
136391
|
+
devtools.getScreenSize()
|
|
136392
|
+
]);
|
|
136393
|
+
return adaptAndroidTree(xml, truncated, size);
|
|
136394
|
+
}
|
|
136395
|
+
|
|
136396
|
+
// ../tool-server/src/tools/ui-tree/index.ts
|
|
136397
|
+
var zodSchema40 = external_exports.object({
|
|
136398
|
+
udid: external_exports.string().min(1).describe("Target device id from `list-devices`.")
|
|
136399
|
+
});
|
|
136400
|
+
var capability25 = {
|
|
136401
|
+
apple: { simulator: true },
|
|
136402
|
+
android: { emulator: true, device: true, unknown: true }
|
|
136403
|
+
};
|
|
136404
|
+
function createUiTreeTool(registry2) {
|
|
136405
|
+
return {
|
|
136406
|
+
id: "ui-tree",
|
|
136407
|
+
interaction: {
|
|
136408
|
+
startedMsg: () => "Reading UI tree",
|
|
136409
|
+
completedMsg: () => "Read UI tree",
|
|
136410
|
+
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read UI tree: ${failureSignal2.error_code}`
|
|
136411
|
+
},
|
|
136412
|
+
description: `Read the raw accessibility tree of the screen as nested JSON, for SDK callers.
|
|
136413
|
+
Use when a program needs element ancestry, such as an e2e engine's scoped selectors; agents use describe.
|
|
136414
|
+
Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, unsupportedFields }.
|
|
136415
|
+
Fails if the iOS ax-service predates the tree command; update argent.`,
|
|
136416
|
+
hideFromMcp: true,
|
|
136417
|
+
zodSchema: zodSchema40,
|
|
136418
|
+
capability: capability25,
|
|
136419
|
+
services: () => ({}),
|
|
136420
|
+
execute: dispatchByPlatform({
|
|
136421
|
+
toolId: "ui-tree",
|
|
136422
|
+
capability: capability25,
|
|
136423
|
+
ios: {
|
|
136424
|
+
requires: iosRequires,
|
|
136425
|
+
handler: async (_services, _params, device) => {
|
|
136426
|
+
if (await isTvOsSimulator(device.id)) {
|
|
136427
|
+
throw new UnsupportedOperationError("ui-tree", device, "tvOS");
|
|
136428
|
+
}
|
|
136429
|
+
return readIosUiTree(registry2, device);
|
|
136430
|
+
}
|
|
136431
|
+
},
|
|
136432
|
+
android: {
|
|
136433
|
+
requires: androidRequires,
|
|
136434
|
+
handler: async (_services, _params, device) => readAndroidUiTree(registry2, device)
|
|
136435
|
+
}
|
|
136436
|
+
})
|
|
136437
|
+
};
|
|
136438
|
+
}
|
|
136439
|
+
|
|
136063
136440
|
// ../tool-server/src/tools/await-screen-idle/index.ts
|
|
136064
136441
|
init_zod();
|
|
136065
136442
|
init_device_info();
|
|
@@ -136068,7 +136445,7 @@ var AWAIT_SCREEN_IDLE_TOOL_ID = "await-screen-idle";
|
|
|
136068
136445
|
var DEFAULT_TIMEOUT_MS4 = 3e3;
|
|
136069
136446
|
var DEFAULT_POLL_INTERVAL_MS2 = 200;
|
|
136070
136447
|
var DEFAULT_MIN_STABLE_MS = 250;
|
|
136071
|
-
var
|
|
136448
|
+
var zodSchema41 = external_exports.object({
|
|
136072
136449
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
|
|
136073
136450
|
timeoutMs: external_exports.number().int().positive().max(12e4).optional().describe(
|
|
136074
136451
|
`Max time to wait for the screen to settle before giving up (default ${DEFAULT_TIMEOUT_MS4}).`
|
|
@@ -136078,7 +136455,7 @@ var zodSchema40 = external_exports.object({
|
|
|
136078
136455
|
`The screen must hold the same content for at least this long to count as settled (default ${DEFAULT_MIN_STABLE_MS}).`
|
|
136079
136456
|
)
|
|
136080
136457
|
});
|
|
136081
|
-
var
|
|
136458
|
+
var capability26 = {
|
|
136082
136459
|
apple: { simulator: true, device: true },
|
|
136083
136460
|
appleRemote: { simulator: true },
|
|
136084
136461
|
android: { emulator: true, device: true, unknown: true },
|
|
@@ -136125,8 +136502,8 @@ ${DEFAULT_TIMEOUT_MS4}ms) is reached. Returns { settled, waitedMs, polls } \u201
|
|
|
136125
136502
|
still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
|
|
136126
136503
|
searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
|
|
136127
136504
|
longRunning: true,
|
|
136128
|
-
zodSchema:
|
|
136129
|
-
capability:
|
|
136505
|
+
zodSchema: zodSchema41,
|
|
136506
|
+
capability: capability26,
|
|
136130
136507
|
services: (params) => {
|
|
136131
136508
|
const device = resolveDevice(params.udid);
|
|
136132
136509
|
if (device.platform === "chromium") {
|
|
@@ -136136,7 +136513,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
|
|
|
136136
136513
|
},
|
|
136137
136514
|
async execute(services, params, ctx) {
|
|
136138
136515
|
const device = resolveDevice(params.udid);
|
|
136139
|
-
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID,
|
|
136516
|
+
assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability26, device);
|
|
136140
136517
|
if (device.platform === "ios") await ensureDeps(iosRequires);
|
|
136141
136518
|
else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
|
|
136142
136519
|
else if (device.platform === "android") await ensureDeps(androidRequires);
|
|
@@ -136223,7 +136600,7 @@ function bootstrapFailureMessage(bootstrap) {
|
|
|
136223
136600
|
// ../tool-server/src/tools/profiler/react/react-profiler-start.ts
|
|
136224
136601
|
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.";
|
|
136225
136602
|
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.";
|
|
136226
|
-
var
|
|
136603
|
+
var zodSchema42 = external_exports.object({
|
|
136227
136604
|
port: metroPortField,
|
|
136228
136605
|
device_id: external_exports.string().describe(
|
|
136229
136606
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -136255,7 +136632,7 @@ Before calling this, ask the user if they also want native profiling (native-pro
|
|
|
136255
136632
|
After starting, ask the user to perform the interaction to profile, then call react-profiler-stop.
|
|
136256
136633
|
Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above.
|
|
136257
136634
|
Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.`,
|
|
136258
|
-
zodSchema:
|
|
136635
|
+
zodSchema: zodSchema42,
|
|
136259
136636
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
136260
136637
|
services: () => ({}),
|
|
136261
136638
|
async execute(_services, params) {
|
|
@@ -136526,7 +136903,7 @@ async function readCommitTree(path51) {
|
|
|
136526
136903
|
}
|
|
136527
136904
|
|
|
136528
136905
|
// ../tool-server/src/tools/profiler/react/react-profiler-stop.ts
|
|
136529
|
-
var
|
|
136906
|
+
var zodSchema43 = external_exports.object({
|
|
136530
136907
|
port: metroPortField,
|
|
136531
136908
|
device_id: external_exports.string().describe(
|
|
136532
136909
|
"Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
|
|
@@ -136615,7 +136992,7 @@ Call react-profiler-start first, then exercise the app, then call this.
|
|
|
136615
136992
|
Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session.
|
|
136616
136993
|
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).
|
|
136617
136994
|
Fails if no active profiling session exists or the CDP connection was lost during recording.`,
|
|
136618
|
-
zodSchema:
|
|
136995
|
+
zodSchema: zodSchema43,
|
|
136619
136996
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
136620
136997
|
services: () => ({}),
|
|
136621
136998
|
async execute(_services, params) {
|
|
@@ -136840,7 +137217,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
|
|
|
136840
137217
|
|
|
136841
137218
|
// ../tool-server/src/tools/profiler/react/react-profiler-status.ts
|
|
136842
137219
|
init_zod();
|
|
136843
|
-
var
|
|
137220
|
+
var zodSchema44 = external_exports.object({
|
|
136844
137221
|
port: metroPortField,
|
|
136845
137222
|
device_id: external_exports.string().describe(
|
|
136846
137223
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -136855,7 +137232,7 @@ function createReactProfilerStatusTool(registry2) {
|
|
|
136855
137232
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
|
|
136856
137233
|
},
|
|
136857
137234
|
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.`,
|
|
136858
|
-
zodSchema:
|
|
137235
|
+
zodSchema: zodSchema44,
|
|
136859
137236
|
// RN-only: companion to react-profiler-start.
|
|
136860
137237
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
136861
137238
|
services: () => ({}),
|
|
@@ -138469,7 +138846,7 @@ var annotationSchema = external_exports.object({
|
|
|
138469
138846
|
),
|
|
138470
138847
|
label: external_exports.string().describe("Description of the action performed")
|
|
138471
138848
|
});
|
|
138472
|
-
var
|
|
138849
|
+
var zodSchema45 = external_exports.object({
|
|
138473
138850
|
port: metroPortField,
|
|
138474
138851
|
device_id: external_exports.string().describe(
|
|
138475
138852
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -138502,7 +138879,7 @@ where tapTimestampMs is the timestampMs returned by the tap/swipe tool and start
|
|
|
138502
138879
|
is returned by react-profiler-start.
|
|
138503
138880
|
Use when the profiling session is complete and you need to interpret the collected data.
|
|
138504
138881
|
Fails if react-profiler-stop has not been called or no profiling data is stored.`,
|
|
138505
|
-
zodSchema:
|
|
138882
|
+
zodSchema: zodSchema45,
|
|
138506
138883
|
// RN-only: reads commit data captured via the React DevTools backend, which
|
|
138507
138884
|
// Chromium does not have.
|
|
138508
138885
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -138639,7 +139016,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
|
|
|
138639
139016
|
// ../tool-server/src/tools/profiler/react/react-profiler-component-source.ts
|
|
138640
139017
|
init_zod();
|
|
138641
139018
|
var import_fs6 = require("fs");
|
|
138642
|
-
var
|
|
139019
|
+
var zodSchema46 = external_exports.object({
|
|
138643
139020
|
component_name: external_exports.string().describe("Name of the React component to look up"),
|
|
138644
139021
|
project_root: external_exports.string().describe("Absolute path to the RN project root")
|
|
138645
139022
|
});
|
|
@@ -138657,7 +139034,7 @@ var reactProfilerComponentSourceTool = {
|
|
|
138657
139034
|
Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
|
|
138658
139035
|
Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
|
|
138659
139036
|
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.`,
|
|
138660
|
-
zodSchema:
|
|
139037
|
+
zodSchema: zodSchema46,
|
|
138661
139038
|
// Declared so the tool catalogue groups this with the other react-profiler-*
|
|
138662
139039
|
// tools; the HTTP gate itself is a no-op here, as there is no device arg to
|
|
138663
139040
|
// inspect.
|
|
@@ -138713,7 +139090,7 @@ When several files define a component with the same name (e.g. platform variants
|
|
|
138713
139090
|
// ../tool-server/src/tools/profiler/react/react-profiler-cpu-summary.ts
|
|
138714
139091
|
init_zod();
|
|
138715
139092
|
init_src2();
|
|
138716
|
-
var
|
|
139093
|
+
var zodSchema47 = external_exports.object({
|
|
138717
139094
|
port: metroPortField,
|
|
138718
139095
|
device_id: external_exports.string().describe(
|
|
138719
139096
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -138795,7 +139172,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
|
|
|
138795
139172
|
Call react-profiler-stop first. Reads directly from the stored cpuProfile.
|
|
138796
139173
|
Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
|
|
138797
139174
|
Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
|
|
138798
|
-
zodSchema:
|
|
139175
|
+
zodSchema: zodSchema47,
|
|
138799
139176
|
// RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
|
|
138800
139177
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
138801
139178
|
services: () => ({}),
|
|
@@ -138891,7 +139268,7 @@ function renderMarkdownTable2(entries) {
|
|
|
138891
139268
|
);
|
|
138892
139269
|
return [header, sep5, ...rows].join("\n");
|
|
138893
139270
|
}
|
|
138894
|
-
var
|
|
139271
|
+
var zodSchema48 = external_exports.object({
|
|
138895
139272
|
port: metroPortField,
|
|
138896
139273
|
device_id: external_exports.string().describe(
|
|
138897
139274
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -138909,7 +139286,7 @@ var reactProfilerRendersTool = {
|
|
|
138909
139286
|
Returns a markdown table of the top re-rendering components. No profiling session required \u2014 works on a live connected app.
|
|
138910
139287
|
Use when you want a quick snapshot of render counts without a full profiling session.
|
|
138911
139288
|
Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
|
|
138912
|
-
zodSchema:
|
|
139289
|
+
zodSchema: zodSchema48,
|
|
138913
139290
|
// RN-only: queries the React DevTools backend hook on the live runtime.
|
|
138914
139291
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
138915
139292
|
services: (params) => ({
|
|
@@ -139066,7 +139443,7 @@ function buildFiberTreeScript(maxDepth, filter) {
|
|
|
139066
139443
|
}
|
|
139067
139444
|
})()`;
|
|
139068
139445
|
}
|
|
139069
|
-
var
|
|
139446
|
+
var zodSchema49 = external_exports.object({
|
|
139070
139447
|
port: metroPortField,
|
|
139071
139448
|
device_id: external_exports.string().describe(
|
|
139072
139449
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -139085,7 +139462,7 @@ var reactProfilerFiberTreeTool = {
|
|
|
139085
139462
|
Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
|
|
139086
139463
|
Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
|
|
139087
139464
|
Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
|
|
139088
|
-
zodSchema:
|
|
139465
|
+
zodSchema: zodSchema49,
|
|
139089
139466
|
// RN-only: walks the fiber tree via the React DevTools backend hook.
|
|
139090
139467
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
139091
139468
|
services: (params) => ({
|
|
@@ -142883,7 +143260,7 @@ function metroDeviceIdParam(description) {
|
|
|
142883
143260
|
}
|
|
142884
143261
|
|
|
142885
143262
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-start.ts
|
|
142886
|
-
var
|
|
143263
|
+
var zodSchema50 = external_exports.object({
|
|
142887
143264
|
device_id: metroDeviceIdParam(
|
|
142888
143265
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
142889
143266
|
),
|
|
@@ -142897,7 +143274,7 @@ var zodSchema49 = external_exports.object({
|
|
|
142897
143274
|
"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."
|
|
142898
143275
|
)
|
|
142899
143276
|
});
|
|
142900
|
-
var
|
|
143277
|
+
var capability27 = {
|
|
142901
143278
|
apple: { simulator: true },
|
|
142902
143279
|
android: { emulator: true, device: true, unknown: true }
|
|
142903
143280
|
};
|
|
@@ -142908,21 +143285,21 @@ var nativeProfilerStartTool = {
|
|
|
142908
143285
|
completedMsg: () => "Started native profiler",
|
|
142909
143286
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start native profiler: ${failureSignal2.error_code}`
|
|
142910
143287
|
},
|
|
142911
|
-
capability:
|
|
143288
|
+
capability: capability27,
|
|
142912
143289
|
description: `Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal).
|
|
142913
143290
|
Auto-detects the running app process unless app_process is explicitly provided.
|
|
142914
143291
|
After starting, let the user interact with the app, then call native-profiler-stop.
|
|
142915
143292
|
Use when you want to capture native CPU, hang, and memory data for a running app.
|
|
142916
143293
|
Returns { status, pid, traceFile } confirming the recording has started.
|
|
142917
143294
|
Fails if no app is running on the device, or the profiler cannot attach to the process.`,
|
|
142918
|
-
zodSchema:
|
|
143295
|
+
zodSchema: zodSchema50,
|
|
142919
143296
|
services: (params) => ({
|
|
142920
143297
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
142921
143298
|
}),
|
|
142922
143299
|
async execute(services, params) {
|
|
142923
143300
|
const api = services.session;
|
|
142924
143301
|
const device = resolveDevice(params.device_id);
|
|
142925
|
-
assertSupported("native-profiler-start",
|
|
143302
|
+
assertSupported("native-profiler-start", capability27, device);
|
|
142926
143303
|
if (api.platform === "ios") {
|
|
142927
143304
|
await ensureDeps(["xcrun"]);
|
|
142928
143305
|
return startNativeProfilerIos(api, params);
|
|
@@ -142935,12 +143312,12 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
|
|
|
142935
143312
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-stop.ts
|
|
142936
143313
|
init_zod();
|
|
142937
143314
|
init_device_info();
|
|
142938
|
-
var
|
|
143315
|
+
var zodSchema51 = external_exports.object({
|
|
142939
143316
|
device_id: metroDeviceIdParam(
|
|
142940
143317
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
142941
143318
|
)
|
|
142942
143319
|
});
|
|
142943
|
-
var
|
|
143320
|
+
var capability28 = {
|
|
142944
143321
|
apple: { simulator: true },
|
|
142945
143322
|
android: { emulator: true, device: true, unknown: true }
|
|
142946
143323
|
};
|
|
@@ -142968,7 +143345,7 @@ var nativeProfilerStopTool = {
|
|
|
142968
143345
|
completedMsg: ({ result }) => `Saved native profile ${result.traceFile.filename}`,
|
|
142969
143346
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
|
|
142970
143347
|
},
|
|
142971
|
-
capability:
|
|
143348
|
+
capability: capability28,
|
|
142972
143349
|
// Packaging plus the export passes routinely exceed the 30s MCP fetch timeout.
|
|
142973
143350
|
longRunning: true,
|
|
142974
143351
|
description: `Stop native profiling and export trace data.
|
|
@@ -142978,14 +143355,14 @@ Call native-profiler-start first.
|
|
|
142978
143355
|
Use when the user has finished the interaction to profile and you need to export the trace.
|
|
142979
143356
|
Returns { traceFile, exportedFiles, exportDiagnostics? }; traceFile is the raw trace bundle and exportedFiles the exports, all downloadable artifacts materialized to local paths.
|
|
142980
143357
|
Fails if no active native-profiler-start session exists for the given device_id.`,
|
|
142981
|
-
zodSchema:
|
|
143358
|
+
zodSchema: zodSchema51,
|
|
142982
143359
|
services: (params) => ({
|
|
142983
143360
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
142984
143361
|
}),
|
|
142985
143362
|
async execute(services, params, ctx) {
|
|
142986
143363
|
const api = services.session;
|
|
142987
143364
|
const device = resolveDevice(params.device_id);
|
|
142988
|
-
assertSupported("native-profiler-stop",
|
|
143365
|
+
assertSupported("native-profiler-stop", capability28, device);
|
|
142989
143366
|
if (api.platform === "ios") {
|
|
142990
143367
|
await ensureDeps(["xcrun"]);
|
|
142991
143368
|
const ios = await stopNativeProfilerIos(api);
|
|
@@ -143013,12 +143390,12 @@ Fails if no active native-profiler-start session exists for the given device_id.
|
|
|
143013
143390
|
// ../tool-server/src/tools/profiler/native-profiler/native-profiler-analyze.ts
|
|
143014
143391
|
init_zod();
|
|
143015
143392
|
init_device_info();
|
|
143016
|
-
var
|
|
143393
|
+
var zodSchema52 = external_exports.object({
|
|
143017
143394
|
device_id: metroDeviceIdParam(
|
|
143018
143395
|
"Target device id from `list-devices` (iOS UDID or Android serial)."
|
|
143019
143396
|
)
|
|
143020
143397
|
});
|
|
143021
|
-
var
|
|
143398
|
+
var capability29 = {
|
|
143022
143399
|
apple: { simulator: true },
|
|
143023
143400
|
android: { emulator: true, device: true, unknown: true }
|
|
143024
143401
|
};
|
|
@@ -143029,7 +143406,7 @@ var nativeProfilerAnalyzeTool = {
|
|
|
143029
143406
|
completedMsg: () => "Analyzed native profile",
|
|
143030
143407
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to analyze native profile: ${failureSignal2.error_code}`
|
|
143031
143408
|
},
|
|
143032
|
-
capability:
|
|
143409
|
+
capability: capability29,
|
|
143033
143410
|
// Parsing a trace from a recording up to RECORDING_CAP_MS long routinely exceeds
|
|
143034
143411
|
// the 30s MCP fetch timeout, and an aborted call is replayed, not cancelled.
|
|
143035
143412
|
longRunning: true,
|
|
@@ -143042,14 +143419,14 @@ profiler-stack-query for hang stacks, CPU context, leak details) or implement fi
|
|
|
143042
143419
|
Call native-profiler-stop first to export the trace data.
|
|
143043
143420
|
Use when you need to interpret a completed native profiling recording.
|
|
143044
143421
|
Fails if native-profiler-stop has not been called first to export trace data.`,
|
|
143045
|
-
zodSchema:
|
|
143422
|
+
zodSchema: zodSchema52,
|
|
143046
143423
|
services: (params) => ({
|
|
143047
143424
|
session: nativeProfilerSessionRef(resolveDevice(params.device_id))
|
|
143048
143425
|
}),
|
|
143049
143426
|
async execute(services, params, ctx) {
|
|
143050
143427
|
const api = services.session;
|
|
143051
143428
|
const device = resolveDevice(params.device_id);
|
|
143052
|
-
assertSupported("native-profiler-analyze",
|
|
143429
|
+
assertSupported("native-profiler-analyze", capability29, device);
|
|
143053
143430
|
let result;
|
|
143054
143431
|
if (api.platform === "ios") {
|
|
143055
143432
|
await ensureDeps(["xcrun"]);
|
|
@@ -144112,7 +144489,7 @@ var DEFAULT_TIME_LIMIT_SECONDS = 180;
|
|
|
144112
144489
|
var MAX_TIME_LIMIT_SECONDS = 600;
|
|
144113
144490
|
var POINTER_TRAIL_LENGTH = 8;
|
|
144114
144491
|
var POINTER_REQUEST_TIMEOUT_MS = 2e3;
|
|
144115
|
-
var
|
|
144492
|
+
var zodSchema53 = external_exports.object({
|
|
144116
144493
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial)."),
|
|
144117
144494
|
timeLimitSeconds: external_exports.number().int().min(1).max(MAX_TIME_LIMIT_SECONDS).optional().describe(
|
|
144118
144495
|
`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.`
|
|
@@ -144124,7 +144501,7 @@ var zodSchema52 = external_exports.object({
|
|
|
144124
144501
|
"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."
|
|
144125
144502
|
)
|
|
144126
144503
|
});
|
|
144127
|
-
var
|
|
144504
|
+
var capability30 = {
|
|
144128
144505
|
apple: { simulator: true },
|
|
144129
144506
|
android: { emulator: true, device: true, unknown: true }
|
|
144130
144507
|
};
|
|
@@ -144136,7 +144513,7 @@ function createScreenRecordingStartTool(registry2) {
|
|
|
144136
144513
|
completedMsg: () => "Started screen recording",
|
|
144137
144514
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start screen recording: ${failureSignal2.error_code}`
|
|
144138
144515
|
},
|
|
144139
|
-
capability:
|
|
144516
|
+
capability: capability30,
|
|
144140
144517
|
description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
|
|
144141
144518
|
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.
|
|
144142
144519
|
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.
|
|
@@ -144145,7 +144522,7 @@ Use when the user wants a video of an interaction, animation, or app behavior \u
|
|
|
144145
144522
|
Returns { status: "recording", timeLimitSeconds, outputFile } \u2014 the video is retrieved later by \`screen-recording-stop\`, not by reading outputFile directly.
|
|
144146
144523
|
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).`,
|
|
144147
144524
|
searchHint: "record video screen capture movie mp4 start filming screencast",
|
|
144148
|
-
zodSchema:
|
|
144525
|
+
zodSchema: zodSchema53,
|
|
144149
144526
|
// Resolved inside execute, not declared eagerly: a tvOS udid classifies as
|
|
144150
144527
|
// iOS by shape, so an eager service would spawn simulator-server for a
|
|
144151
144528
|
// device it cannot drive and hang on its ready timeout (as in `screenshot`).
|
|
@@ -144155,7 +144532,7 @@ Fails if a recording is already running on the device, the device is not booted,
|
|
|
144155
144532
|
async execute(services, params) {
|
|
144156
144533
|
const api = services.session;
|
|
144157
144534
|
const device = resolveDevice(params.udid);
|
|
144158
|
-
assertSupported("screen-recording-start",
|
|
144535
|
+
assertSupported("screen-recording-start", capability30, device);
|
|
144159
144536
|
if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
|
|
144160
144537
|
throw new FailureError(
|
|
144161
144538
|
`Screen recording is not supported on tvOS simulators (device ${params.udid}).`,
|
|
@@ -144244,11 +144621,11 @@ function makePointerControl(simulator) {
|
|
|
144244
144621
|
var import_node_path22 = require("node:path");
|
|
144245
144622
|
init_zod();
|
|
144246
144623
|
init_device_info();
|
|
144247
|
-
var
|
|
144624
|
+
var zodSchema54 = external_exports.object({
|
|
144248
144625
|
udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial).")
|
|
144249
144626
|
});
|
|
144250
144627
|
var RECORDINGS_DIR = ".argent/recordings";
|
|
144251
|
-
var
|
|
144628
|
+
var capability31 = {
|
|
144252
144629
|
apple: { simulator: true },
|
|
144253
144630
|
android: { emulator: true, device: true, unknown: true }
|
|
144254
144631
|
};
|
|
@@ -144259,21 +144636,21 @@ var screenRecordingStopTool = {
|
|
|
144259
144636
|
completedMsg: ({ result }) => `Saved screen recording ${result.video.filename}`,
|
|
144260
144637
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop screen recording: ${failureSignal2.error_code}`
|
|
144261
144638
|
},
|
|
144262
|
-
capability:
|
|
144639
|
+
capability: capability31,
|
|
144263
144640
|
description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
|
|
144264
144641
|
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.
|
|
144265
144642
|
Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
|
|
144266
144643
|
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.
|
|
144267
144644
|
Fails if no recording (running or finished-but-unretrieved) exists for the given udid.`,
|
|
144268
144645
|
searchHint: "stop end finish screen recording video capture save retrieve",
|
|
144269
|
-
zodSchema:
|
|
144646
|
+
zodSchema: zodSchema54,
|
|
144270
144647
|
services: (params) => ({
|
|
144271
144648
|
session: screenRecordingSessionRef(resolveDevice(params.udid))
|
|
144272
144649
|
}),
|
|
144273
144650
|
async execute(services, params, ctx) {
|
|
144274
144651
|
const api = services.session;
|
|
144275
144652
|
const device = resolveDevice(params.udid);
|
|
144276
|
-
assertSupported("screen-recording-stop",
|
|
144653
|
+
assertSupported("screen-recording-stop", capability31, device);
|
|
144277
144654
|
const stopped = await stopCapture(api);
|
|
144278
144655
|
const artifacts = requireArtifacts(ctx);
|
|
144279
144656
|
const video = await artifacts.register({
|
|
@@ -144305,7 +144682,7 @@ var timeWindowSchema = external_exports.object({
|
|
|
144305
144682
|
"End of window in ms since profiling started \u2014 the same clock profiler-commit-query prints"
|
|
144306
144683
|
)
|
|
144307
144684
|
});
|
|
144308
|
-
var
|
|
144685
|
+
var zodSchema55 = external_exports.object({
|
|
144309
144686
|
port: metroPortField,
|
|
144310
144687
|
device_id: metroDeviceIdParam(
|
|
144311
144688
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -144594,7 +144971,7 @@ Every table states how many samples it covers and how much of that was idle.
|
|
|
144594
144971
|
Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
|
|
144595
144972
|
Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
|
|
144596
144973
|
Fails if no CPU profile is stored \u2014 run react-profiler-stop first.`,
|
|
144597
|
-
zodSchema:
|
|
144974
|
+
zodSchema: zodSchema55,
|
|
144598
144975
|
// RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
|
|
144599
144976
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
144600
144977
|
services: () => ({}),
|
|
@@ -144680,7 +145057,7 @@ var timeRangeSchema = external_exports.object({
|
|
|
144680
145057
|
"End of range in ms since profiling started \u2014 the same clock profiler-commit-query prints"
|
|
144681
145058
|
)
|
|
144682
145059
|
});
|
|
144683
|
-
var
|
|
145060
|
+
var zodSchema56 = external_exports.object({
|
|
144684
145061
|
port: metroPortField,
|
|
144685
145062
|
device_id: metroDeviceIdParam(
|
|
144686
145063
|
"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
|
|
@@ -144953,7 +145330,7 @@ Modes:
|
|
|
144953
145330
|
Use when drilling into specific components or time windows after react-profiler-analyze.
|
|
144954
145331
|
Returns a markdown table or tree of commit data matching the requested mode.
|
|
144955
145332
|
Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
144956
|
-
zodSchema:
|
|
145333
|
+
zodSchema: zodSchema56,
|
|
144957
145334
|
// Reads React commit data captured via the React DevTools backend.
|
|
144958
145335
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
144959
145336
|
services: () => ({}),
|
|
@@ -145024,7 +145401,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
|
|
|
145024
145401
|
init_zod();
|
|
145025
145402
|
init_src2();
|
|
145026
145403
|
init_device_info();
|
|
145027
|
-
var
|
|
145404
|
+
var zodSchema57 = external_exports.object({
|
|
145028
145405
|
device_id: metroDeviceIdParam("iOS Simulator UDID or Android serial."),
|
|
145029
145406
|
mode: external_exports.enum(["hang_stacks", "function_callers", "thread_breakdown", "leak_stacks"]).describe(
|
|
145030
145407
|
"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)"
|
|
@@ -145342,7 +145719,7 @@ Modes:
|
|
|
145342
145719
|
Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
|
|
145343
145720
|
Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
|
|
145344
145721
|
Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
|
|
145345
|
-
zodSchema:
|
|
145722
|
+
zodSchema: zodSchema57,
|
|
145346
145723
|
// No chromium entry: it has no native trace capture.
|
|
145347
145724
|
capability: {
|
|
145348
145725
|
apple: { simulator: true },
|
|
@@ -145412,7 +145789,7 @@ function buildPerfettoAnchor(wallClockStartMs) {
|
|
|
145412
145789
|
}
|
|
145413
145790
|
|
|
145414
145791
|
// ../tool-server/src/tools/profiler/combined/profiler-combined-report.ts
|
|
145415
|
-
var
|
|
145792
|
+
var zodSchema58 = external_exports.object({
|
|
145416
145793
|
port: metroPortField,
|
|
145417
145794
|
device_id: metroDeviceIdParam("iOS Simulator/device UDID or Android serial")
|
|
145418
145795
|
});
|
|
@@ -145429,7 +145806,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
|
|
|
145429
145806
|
Call this tool when both profilers were run in parallel on the same session.
|
|
145430
145807
|
Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
|
|
145431
145808
|
Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
|
|
145432
|
-
zodSchema:
|
|
145809
|
+
zodSchema: zodSchema58,
|
|
145433
145810
|
// iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
|
|
145434
145811
|
// loadAndroidCombinedData. Chromium has no native trace capture.
|
|
145435
145812
|
capability: {
|
|
@@ -145753,7 +146130,7 @@ function assertSafeSessionId(sessionId) {
|
|
|
145753
146130
|
);
|
|
145754
146131
|
}
|
|
145755
146132
|
}
|
|
145756
|
-
var
|
|
146133
|
+
var zodSchema59 = external_exports.object({
|
|
145757
146134
|
mode: external_exports.enum(["list", "load_react", "load_native"]).describe(
|
|
145758
146135
|
"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."
|
|
145759
146136
|
),
|
|
@@ -146114,7 +146491,7 @@ Modes:
|
|
|
146114
146491
|
For Android .pftrace restores, pass app_process for older sessions that do not have a metadata sidecar.
|
|
146115
146492
|
Returns a summary of the loaded session or a session list for the list mode.
|
|
146116
146493
|
Fails if the session_id is not found or required XML files are missing from disk.`,
|
|
146117
|
-
zodSchema:
|
|
146494
|
+
zodSchema: zodSchema59,
|
|
146118
146495
|
// The Hermes, xctrace and perfetto formats this loads have no Chromium
|
|
146119
146496
|
// equivalent; the gate fails at the call site, not inside the trace parser.
|
|
146120
146497
|
capability: RN_ONLY_TOOL_CAPABILITY,
|
|
@@ -146243,7 +146620,7 @@ function unnameableSessionUrns(urns) {
|
|
|
146243
146620
|
}
|
|
146244
146621
|
|
|
146245
146622
|
// ../tool-server/src/tools/simulator/stop-simulator-server.ts
|
|
146246
|
-
var
|
|
146623
|
+
var zodSchema60 = external_exports.object({
|
|
146247
146624
|
udid: external_exports.string().describe(
|
|
146248
146625
|
"Target device id (iOS UDID, Android serial, or Chromium id) whose transport session to stop"
|
|
146249
146626
|
)
|
|
@@ -146257,7 +146634,7 @@ function createStopSimulatorServerTool(registry2) {
|
|
|
146257
146634
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop simulator server for ${params.udid}: ${failureSignal2.error_code}`
|
|
146258
146635
|
},
|
|
146259
146636
|
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.`,
|
|
146260
|
-
zodSchema:
|
|
146637
|
+
zodSchema: zodSchema60,
|
|
146261
146638
|
services: () => ({}),
|
|
146262
146639
|
async execute(_services, params) {
|
|
146263
146640
|
const udid = params.udid;
|
|
@@ -146288,7 +146665,7 @@ function createStopSimulatorServerTool(registry2) {
|
|
|
146288
146665
|
init_zod();
|
|
146289
146666
|
init_src2();
|
|
146290
146667
|
init_external_devices();
|
|
146291
|
-
var
|
|
146668
|
+
var zodSchema61 = external_exports.object({
|
|
146292
146669
|
devices: external_exports.array(external_exports.string()).optional().describe(
|
|
146293
146670
|
"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."
|
|
146294
146671
|
)
|
|
@@ -146327,7 +146704,7 @@ function createStopAllSimulatorServersTool(registry2) {
|
|
|
146327
146704
|
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.
|
|
146328
146705
|
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.
|
|
146329
146706
|
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.`,
|
|
146330
|
-
zodSchema:
|
|
146707
|
+
zodSchema: zodSchema61,
|
|
146331
146708
|
services: () => ({}),
|
|
146332
146709
|
async execute(_services, params, ctx) {
|
|
146333
146710
|
const devices = params.devices;
|
|
@@ -146407,7 +146784,7 @@ function listeningPids(port) {
|
|
|
146407
146784
|
if (!output) return [];
|
|
146408
146785
|
return output.split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => !Number.isNaN(n));
|
|
146409
146786
|
}
|
|
146410
|
-
var
|
|
146787
|
+
var zodSchema62 = external_exports.object({
|
|
146411
146788
|
port: external_exports.number().int().min(1).max(65535).default(8081).describe("TCP port Metro is listening on (default 8081)")
|
|
146412
146789
|
});
|
|
146413
146790
|
var stopMetroTool = {
|
|
@@ -146418,7 +146795,7 @@ var stopMetroTool = {
|
|
|
146418
146795
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
|
|
146419
146796
|
},
|
|
146420
146797
|
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.`,
|
|
146421
|
-
zodSchema:
|
|
146798
|
+
zodSchema: zodSchema62,
|
|
146422
146799
|
services: () => ({}),
|
|
146423
146800
|
async execute(_services, params) {
|
|
146424
146801
|
const port = params.port;
|
|
@@ -148701,7 +149078,7 @@ async function appendStepToFlow(session, step) {
|
|
|
148701
149078
|
}
|
|
148702
149079
|
|
|
148703
149080
|
// ../tool-server/src/tools/flows/flow-start-recording.ts
|
|
148704
|
-
var
|
|
149081
|
+
var zodSchema63 = external_exports.object({
|
|
148705
149082
|
name: external_exports.string().describe(
|
|
148706
149083
|
'Name for this flow (e.g. "settings-explore") \u2014 letters, digits, underscore and hyphen only.'
|
|
148707
149084
|
),
|
|
@@ -148758,7 +149135,7 @@ recording. Against a remote client the in-memory copy is authoritative and
|
|
|
148758
149135
|
every write serializes it over your edit; in host mode the recorder re-reads
|
|
148759
149136
|
the file before each append, so a mid-recording edit renumbers the steps and
|
|
148760
149137
|
costs the finish the cross-tree verdicts anchored to them.`,
|
|
148761
|
-
zodSchema:
|
|
149138
|
+
zodSchema: zodSchema63,
|
|
148762
149139
|
fileInputs: fileInputs2,
|
|
148763
149140
|
services: () => ({}),
|
|
148764
149141
|
async execute(_services, params, ctx) {
|
|
@@ -148970,46 +149347,6 @@ function bindDeviceArgs(registry2, toolName, deviceId, args, deviceIsExplicit =
|
|
|
148970
149347
|
// ../tool-server/src/tools/flows/flow-ios-tree.ts
|
|
148971
149348
|
init_src2();
|
|
148972
149349
|
init_device_info();
|
|
148973
|
-
|
|
148974
|
-
// ../tool-server/src/tools/flows/flow-tree-flatten.ts
|
|
148975
|
-
function intersectClip(rect, clip3) {
|
|
148976
|
-
if (!clip3) return rect;
|
|
148977
|
-
const x1 = Math.max(rect.x, clip3.x);
|
|
148978
|
-
const y1 = Math.max(rect.y, clip3.y);
|
|
148979
|
-
const x2 = Math.min(rect.x + rect.w, clip3.x + clip3.w);
|
|
148980
|
-
const y2 = Math.min(rect.y + rect.h, clip3.y + clip3.h);
|
|
148981
|
-
return { x: x1, y: y1, w: Math.max(0, x2 - x1), h: Math.max(0, y2 - y1) };
|
|
148982
|
-
}
|
|
148983
|
-
function includesWordsCI(haystack, needle) {
|
|
148984
|
-
const h = haystack.toLowerCase();
|
|
148985
|
-
const n = needle.toLowerCase();
|
|
148986
|
-
if (!n) return false;
|
|
148987
|
-
const isWordChar = (c) => c !== void 0 && /[\p{L}\p{N}]/u.test(c);
|
|
148988
|
-
for (let at = h.indexOf(n); at !== -1; at = h.indexOf(n, at + 1)) {
|
|
148989
|
-
if (!isWordChar(h[at - 1]) && !isWordChar(h[at + n.length])) return true;
|
|
148990
|
-
}
|
|
148991
|
-
return false;
|
|
148992
|
-
}
|
|
148993
|
-
function flattenHoisting(node, project, out, scrollClip = null) {
|
|
148994
|
-
const view = project(node);
|
|
148995
|
-
if (view.skip) return "";
|
|
148996
|
-
if (scrollClip && view.rect && rectFullyOutside(view.rect, scrollClip)) return "";
|
|
148997
|
-
const childClip = view.scrolls && view.rect ? intersectClip(view.rect, scrollClip) : scrollClip;
|
|
148998
|
-
const childText = [];
|
|
148999
|
-
for (const child of view.children) {
|
|
149000
|
-
const t = flattenHoisting(child, project, out, childClip);
|
|
149001
|
-
if (t) childText.push(t);
|
|
149002
|
-
}
|
|
149003
|
-
const descendantText2 = childText.join(" ");
|
|
149004
|
-
const subtree = view.ownText && !includesWordsCI(descendantText2, view.ownText) ? [view.ownText, descendantText2].filter(Boolean).join(" ") : descendantText2 || view.ownText;
|
|
149005
|
-
if (view.leaf) {
|
|
149006
|
-
if (subtree && subtree !== view.ownText) view.leaf.subtreeText = subtree;
|
|
149007
|
-
out.push(view.leaf);
|
|
149008
|
-
}
|
|
149009
|
-
return view.shield ? "" : subtree;
|
|
149010
|
-
}
|
|
149011
|
-
|
|
149012
|
-
// ../tool-server/src/tools/flows/flow-ios-tree.ts
|
|
149013
149350
|
function clamp013(value) {
|
|
149014
149351
|
return Math.min(1, Math.max(0, value));
|
|
149015
149352
|
}
|
|
@@ -149449,126 +149786,6 @@ async function queryIosDeviceFlowTree(registry2, device) {
|
|
|
149449
149786
|
return { ...data, tree: adaptIosDeviceTreeForFlows(data.tree) };
|
|
149450
149787
|
}
|
|
149451
149788
|
|
|
149452
|
-
// ../tool-server/src/tools/flows/flow-android-tree.ts
|
|
149453
|
-
var FLOW_MAX_NODES = 12e3;
|
|
149454
|
-
var SYSTEM_PACKAGES2 = /* @__PURE__ */ new Set(["com.android.systemui"]);
|
|
149455
|
-
var SYSTEM_RID_PREFIXES2 = [
|
|
149456
|
-
"android:id/navigationBarBackground",
|
|
149457
|
-
"android:id/statusBarBackground",
|
|
149458
|
-
"com.android.systemui:id/"
|
|
149459
|
-
];
|
|
149460
|
-
function isSystemChrome2(attrs) {
|
|
149461
|
-
if (SYSTEM_PACKAGES2.has(attrs.package ?? "")) return true;
|
|
149462
|
-
const rid = attrs["resource-id"] ?? "";
|
|
149463
|
-
return SYSTEM_RID_PREFIXES2.some((p) => rid.startsWith(p));
|
|
149464
|
-
}
|
|
149465
|
-
function labelOf2(attrs) {
|
|
149466
|
-
const cd = (attrs["content-desc"] ?? "").trim();
|
|
149467
|
-
if (cd) return cd;
|
|
149468
|
-
return (attrs.text ?? "").trim();
|
|
149469
|
-
}
|
|
149470
|
-
function normalizeRect(rect, screenW, screenH) {
|
|
149471
|
-
const clipped = clipBoundsToScreen(rect, screenW, screenH);
|
|
149472
|
-
if (clipped.w <= 0 || clipped.h <= 0) return null;
|
|
149473
|
-
return {
|
|
149474
|
-
x: clipped.x / screenW,
|
|
149475
|
-
y: clipped.y / screenH,
|
|
149476
|
-
width: clipped.w / screenW,
|
|
149477
|
-
height: clipped.h / screenH
|
|
149478
|
-
};
|
|
149479
|
-
}
|
|
149480
|
-
function childNodes(node) {
|
|
149481
|
-
return node.children.filter((c) => c.tag === "node");
|
|
149482
|
-
}
|
|
149483
|
-
function projectAndroidNode(node, screenW, screenH) {
|
|
149484
|
-
const attrs = node.attrs;
|
|
149485
|
-
const skip2 = isSystemChrome2(attrs) || isNoisyUiAutomatorClass(attrs.class ?? "");
|
|
149486
|
-
const identifier = (attrs["resource-id"] ?? "").trim();
|
|
149487
|
-
const isPassword = attrs.password === "true";
|
|
149488
|
-
const isFocused = attrs.focused === "true";
|
|
149489
|
-
const label = isPassword ? "[password]" : labelOf2(attrs);
|
|
149490
|
-
const rawText = (attrs.text ?? "").trim();
|
|
149491
|
-
const hasValue = !isPassword && Boolean(rawText) && rawText !== label;
|
|
149492
|
-
const className = attrs.class ?? "";
|
|
149493
|
-
const role = deriveUiAutomatorRole(className);
|
|
149494
|
-
const hasSemanticRole = !isUiAutomatorLayoutContainer(className);
|
|
149495
|
-
const ownText2 = [label, hasValue ? rawText : ""].filter(Boolean).join(" ");
|
|
149496
|
-
const rect = parseUiAutomatorBounds(attrs.bounds ?? "");
|
|
149497
|
-
let leaf = null;
|
|
149498
|
-
let frame = null;
|
|
149499
|
-
if (!skip2 && (identifier || label || hasSemanticRole || isFocused)) {
|
|
149500
|
-
frame = rect ? normalizeRect(rect, screenW, screenH) : null;
|
|
149501
|
-
if (frame) {
|
|
149502
|
-
leaf = { role, frame, children: [] };
|
|
149503
|
-
if (label) leaf.label = label;
|
|
149504
|
-
if (identifier) leaf.identifier = identifier;
|
|
149505
|
-
if (hasValue) leaf.value = rawText;
|
|
149506
|
-
if (attrs.clickable === "true") leaf.clickable = true;
|
|
149507
|
-
if (attrs["long-clickable"] === "true") leaf.longClickable = true;
|
|
149508
|
-
if (attrs.scrollable === "true") leaf.scrollable = true;
|
|
149509
|
-
if (attrs.checkable === "true") leaf.checkable = true;
|
|
149510
|
-
if (attrs.checked === "true") leaf.checked = true;
|
|
149511
|
-
if (attrs.enabled === "false") leaf.disabled = true;
|
|
149512
|
-
if (isPassword) leaf.password = true;
|
|
149513
|
-
if (isFocused) leaf.focused = true;
|
|
149514
|
-
}
|
|
149515
|
-
}
|
|
149516
|
-
return {
|
|
149517
|
-
skip: skip2,
|
|
149518
|
-
children: childNodes(node),
|
|
149519
|
-
// Off-screen text must not hoist, or an ancestor text assert would pass on
|
|
149520
|
-
// content the screen doesn't show. Any node with text is leaf-eligible (its
|
|
149521
|
-
// label is non-empty), so `frame` was computed for it.
|
|
149522
|
-
ownText: frame ? ownText2 : "",
|
|
149523
|
-
leaf,
|
|
149524
|
-
// A password field shields even when it carries no id, so nothing from it
|
|
149525
|
-
// bubbles into an ancestor's hoisted text.
|
|
149526
|
-
shield: Boolean(identifier) || isPassword,
|
|
149527
|
-
// Scroll-clip inputs (see `flattenHoisting`): a scroller's raw bounds clip
|
|
149528
|
-
// its subtree, so a row scrolled out of view — but still on the device
|
|
149529
|
-
// screen — is dropped, matching the describe path's prune.
|
|
149530
|
-
rect,
|
|
149531
|
-
scrolls: isUiAutomatorScrollable(attrs)
|
|
149532
|
-
};
|
|
149533
|
-
}
|
|
149534
|
-
function adaptFullAndroidHierarchyToDescribeResult(xml, screenW, screenH) {
|
|
149535
|
-
const children = [];
|
|
149536
|
-
if (screenW > 0 && screenH > 0) {
|
|
149537
|
-
const root = parseUiAutomatorXml(xml);
|
|
149538
|
-
if (root) {
|
|
149539
|
-
for (const c of childNodes(root)) {
|
|
149540
|
-
flattenHoisting(c, (n) => projectAndroidNode(n, screenW, screenH), children);
|
|
149541
|
-
}
|
|
149542
|
-
}
|
|
149543
|
-
}
|
|
149544
|
-
return parseDescribeResult({
|
|
149545
|
-
role: "Screen",
|
|
149546
|
-
frame: { x: 0, y: 0, width: 1, height: 1 },
|
|
149547
|
-
children
|
|
149548
|
-
});
|
|
149549
|
-
}
|
|
149550
|
-
async function queryAndroidFullHierarchy(registry2, device) {
|
|
149551
|
-
let devtools;
|
|
149552
|
-
try {
|
|
149553
|
-
const ref = androidDevtoolsRef(device);
|
|
149554
|
-
devtools = await registry2.resolveService(ref.urn, ref.options);
|
|
149555
|
-
} catch (err) {
|
|
149556
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
149557
|
-
throw new Error(`the argent android helper is unavailable: ${msg}`, { cause: err });
|
|
149558
|
-
}
|
|
149559
|
-
const [{ xml }, size] = await Promise.all([
|
|
149560
|
-
// clearCache: await/assert polls must see text changes, not cached reads.
|
|
149561
|
-
devtools.getHierarchy({ maxNodes: FLOW_MAX_NODES, clearCache: true }),
|
|
149562
|
-
devtools.getScreenSize()
|
|
149563
|
-
]);
|
|
149564
|
-
const tree = adaptFullAndroidHierarchyToDescribeResult(xml, size.width, size.height);
|
|
149565
|
-
return {
|
|
149566
|
-
tree,
|
|
149567
|
-
source: "android-devtools",
|
|
149568
|
-
...size.width > 0 && size.height > 0 ? { screen: { width: size.width, height: size.height } } : {}
|
|
149569
|
-
};
|
|
149570
|
-
}
|
|
149571
|
-
|
|
149572
149789
|
// ../tool-server/src/tools/flows/flow-chromium-tree.ts
|
|
149573
149790
|
function projectChromiumNode(node) {
|
|
149574
149791
|
const onScreen = node.frame.width > 0 && node.frame.height > 0;
|
|
@@ -151042,7 +151259,7 @@ function stepAnchor(step) {
|
|
|
151042
151259
|
|
|
151043
151260
|
// ../tool-server/src/tools/flows/flow-add-step.ts
|
|
151044
151261
|
init_device_info();
|
|
151045
|
-
var
|
|
151262
|
+
var zodSchema64 = external_exports.object({
|
|
151046
151263
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
151047
151264
|
project_root: external_exports.string().describe(
|
|
151048
151265
|
"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."
|
|
@@ -151474,7 +151691,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
|
|
|
151474
151691
|
// more times — and every retry re-runs the action and appends another step,
|
|
151475
151692
|
// because an aborted request still appends its first.
|
|
151476
151693
|
longRunning: true,
|
|
151477
|
-
zodSchema:
|
|
151694
|
+
zodSchema: zodSchema64,
|
|
151478
151695
|
services: () => ({}),
|
|
151479
151696
|
async execute(_services, params, ctx) {
|
|
151480
151697
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
@@ -151610,7 +151827,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
|
|
|
151610
151827
|
|
|
151611
151828
|
// ../tool-server/src/tools/flows/flow-insert-echo.ts
|
|
151612
151829
|
init_zod();
|
|
151613
|
-
var
|
|
151830
|
+
var zodSchema65 = external_exports.object({
|
|
151614
151831
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
151615
151832
|
project_root: external_exports.string().describe(
|
|
151616
151833
|
"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."
|
|
@@ -151628,7 +151845,7 @@ var flowInsertEchoTool = {
|
|
|
151628
151845
|
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.
|
|
151629
151846
|
Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.
|
|
151630
151847
|
Returns { message, stepCount, savedTo }. Fails if that flow has no recording in progress.`,
|
|
151631
|
-
zodSchema:
|
|
151848
|
+
zodSchema: zodSchema65,
|
|
151632
151849
|
services: () => ({}),
|
|
151633
151850
|
async execute(_services, params) {
|
|
151634
151851
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
@@ -152956,7 +153173,7 @@ function errMsg3(err) {
|
|
|
152956
153173
|
|
|
152957
153174
|
// ../tool-server/src/tools/flows/flow-add-script.ts
|
|
152958
153175
|
var OUTPUT_RENDER_LIMIT_BYTES = 64 * 1024;
|
|
152959
|
-
var
|
|
153176
|
+
var zodSchema66 = external_exports.object({
|
|
152960
153177
|
name: external_exports.string().describe("Flow name passed to flow-start-recording."),
|
|
152961
153178
|
project_root: external_exports.string().describe("Absolute project root passed to flow-start-recording."),
|
|
152962
153179
|
path: external_exports.string().describe(
|
|
@@ -153013,7 +153230,7 @@ var flowAddScriptTool = {
|
|
|
153013
153230
|
// The flag only skips the adapter's own abort timer; its retry loop is
|
|
153014
153231
|
// untouched, so a call that fails some other way is still re-POSTed.
|
|
153015
153232
|
longRunning: true,
|
|
153016
|
-
zodSchema:
|
|
153233
|
+
zodSchema: zodSchema66,
|
|
153017
153234
|
services: () => ({}),
|
|
153018
153235
|
async execute(_services, params, ctx) {
|
|
153019
153236
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
@@ -153103,7 +153320,7 @@ var flowAddScriptTool = {
|
|
|
153103
153320
|
// ../tool-server/src/tools/flows/flow-finish-recording.ts
|
|
153104
153321
|
init_zod();
|
|
153105
153322
|
var fs59 = __toESM(require("node:fs/promises"));
|
|
153106
|
-
var
|
|
153323
|
+
var zodSchema67 = external_exports.object({
|
|
153107
153324
|
name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
|
|
153108
153325
|
project_root: external_exports.string().describe(
|
|
153109
153326
|
"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."
|
|
@@ -153162,7 +153379,7 @@ var flowFinishRecordingTool = {
|
|
|
153162
153379
|
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.
|
|
153163
153380
|
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.
|
|
153164
153381
|
You can still edit the .yaml file directly afterwards to remove or reorder steps.`,
|
|
153165
|
-
zodSchema:
|
|
153382
|
+
zodSchema: zodSchema67,
|
|
153166
153383
|
services: () => ({}),
|
|
153167
153384
|
async execute(_services, params) {
|
|
153168
153385
|
const { filePath, flowFile, savedTo, flow, summary, headline } = await withFlowFileLock(
|
|
@@ -155672,7 +155889,7 @@ async function restoreStatusBar(device) {
|
|
|
155672
155889
|
}
|
|
155673
155890
|
|
|
155674
155891
|
// ../tool-server/src/tools/flows/flow-run.ts
|
|
155675
|
-
var
|
|
155892
|
+
var zodSchema68 = external_exports.object({
|
|
155676
155893
|
name: external_exports.string().optional().describe(
|
|
155677
155894
|
'Name of a saved flow to run from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
|
|
155678
155895
|
),
|
|
@@ -156110,7 +156327,7 @@ one-off interaction use the gesture tools instead, and to author a flow use flow
|
|
|
156110
156327
|
exactly one flow source: name (under project_root) or flow_path.
|
|
156111
156328
|
Returns a per-step report: the first failure stops the run and the rest report as skipped.`,
|
|
156112
156329
|
longRunning: true,
|
|
156113
|
-
zodSchema:
|
|
156330
|
+
zodSchema: zodSchema68,
|
|
156114
156331
|
fileInputs: fileInputs3,
|
|
156115
156332
|
services: () => ({}),
|
|
156116
156333
|
async execute(_services, params, ctx) {
|
|
@@ -156980,7 +157197,7 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
|
|
|
156980
157197
|
// ../tool-server/src/tools/flows/flow-read-prerequisite.ts
|
|
156981
157198
|
init_zod();
|
|
156982
157199
|
var fs63 = __toESM(require("node:fs/promises"));
|
|
156983
|
-
var
|
|
157200
|
+
var zodSchema69 = external_exports.object({
|
|
156984
157201
|
name: external_exports.string().optional().describe(
|
|
156985
157202
|
'Name of a saved flow to inspect from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
|
|
156986
157203
|
),
|
|
@@ -157036,7 +157253,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
|
|
|
157036
157253
|
needs booting, so calling this costs nothing but a file read.
|
|
157037
157254
|
Fails if the flow file does not exist.
|
|
157038
157255
|
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.`,
|
|
157039
|
-
zodSchema:
|
|
157256
|
+
zodSchema: zodSchema69,
|
|
157040
157257
|
fileInputs: fileInputs4,
|
|
157041
157258
|
services: () => ({}),
|
|
157042
157259
|
async execute(_services, params, ctx) {
|
|
@@ -157352,7 +157569,7 @@ async function readWorkspaceSnapshot(workspacePath) {
|
|
|
157352
157569
|
}
|
|
157353
157570
|
|
|
157354
157571
|
// ../tool-server/src/tools/workspace/gather-workspace-data.ts
|
|
157355
|
-
var
|
|
157572
|
+
var zodSchema70 = external_exports.object({
|
|
157356
157573
|
workspacePath: external_exports.string().describe("Absolute path to the project root directory to inspect (e.g. /Users/dev/MyApp)")
|
|
157357
157574
|
});
|
|
157358
157575
|
var fileInputs5 = [
|
|
@@ -157383,7 +157600,7 @@ exploration of anything the snapshot surfaces.
|
|
|
157383
157600
|
Use when you need to inspect project configuration without manually reading multiple files.
|
|
157384
157601
|
Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
|
|
157385
157602
|
Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
|
|
157386
|
-
zodSchema:
|
|
157603
|
+
zodSchema: zodSchema70,
|
|
157387
157604
|
fileInputs: fileInputs5,
|
|
157388
157605
|
services: () => ({}),
|
|
157389
157606
|
async execute(_services, params) {
|
|
@@ -157457,7 +157674,7 @@ function targetFlagsFor(target) {
|
|
|
157457
157674
|
if (target === "both") return ["--global", "--local"];
|
|
157458
157675
|
return [`--${target}`];
|
|
157459
157676
|
}
|
|
157460
|
-
var
|
|
157677
|
+
var zodSchema71 = external_exports.object({
|
|
157461
157678
|
target: external_exports.enum(["auto", "global", "local", "both"]).optional().describe(
|
|
157462
157679
|
"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."
|
|
157463
157680
|
)
|
|
@@ -157471,7 +157688,7 @@ var updateArgentTool = {
|
|
|
157471
157688
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to update Argent: ${failureSignal2.error_code}`
|
|
157472
157689
|
},
|
|
157473
157690
|
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.",
|
|
157474
|
-
zodSchema:
|
|
157691
|
+
zodSchema: zodSchema71,
|
|
157475
157692
|
services: () => ({}),
|
|
157476
157693
|
async execute(_services, params, _options) {
|
|
157477
157694
|
const { updateAvailable, updateInstallable, currentVersion, installableVersion } = getUpdateState();
|
|
@@ -157556,7 +157773,7 @@ var updateArgentTool = {
|
|
|
157556
157773
|
|
|
157557
157774
|
// ../tool-server/src/tools/system/dismiss-update.ts
|
|
157558
157775
|
init_zod();
|
|
157559
|
-
var
|
|
157776
|
+
var zodSchema72 = external_exports.object({
|
|
157560
157777
|
hours: external_exports.number().min(0).describe("Number of hours to suppress the update notification")
|
|
157561
157778
|
});
|
|
157562
157779
|
var dismissUpdateTool = {
|
|
@@ -157567,7 +157784,7 @@ var dismissUpdateTool = {
|
|
|
157567
157784
|
failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to dismiss Argent update: ${failureSignal2.error_code}`
|
|
157568
157785
|
},
|
|
157569
157786
|
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.",
|
|
157570
|
-
zodSchema:
|
|
157787
|
+
zodSchema: zodSchema72,
|
|
157571
157788
|
services: () => ({}),
|
|
157572
157789
|
async execute(_services, params, _options) {
|
|
157573
157790
|
const durationMs = params.hours * 60 * 60 * 1e3;
|
|
@@ -157586,7 +157803,7 @@ var import_path8 = __toESM(require("path"));
|
|
|
157586
157803
|
init_zod();
|
|
157587
157804
|
init_src2();
|
|
157588
157805
|
init_device_info();
|
|
157589
|
-
var
|
|
157806
|
+
var zodSchema73 = external_exports.object({
|
|
157590
157807
|
baselinePath: external_exports.string().min(1).optional().describe("Path to the baseline PNG file. Required unless captureBaseline is true."),
|
|
157591
157808
|
currentPath: external_exports.string().min(1).optional().describe("Path to the current PNG file. Required unless captureCurrent is true."),
|
|
157592
157809
|
udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
|
|
@@ -157603,7 +157820,7 @@ var zodSchema72 = external_exports.object({
|
|
|
157603
157820
|
"Directory where diff artifacts should be written. Optional \u2014 defaults to a temp directory; the diff images are returned in the result either way."
|
|
157604
157821
|
)
|
|
157605
157822
|
}).strict();
|
|
157606
|
-
var
|
|
157823
|
+
var capability32 = {
|
|
157607
157824
|
apple: { simulator: true, device: true },
|
|
157608
157825
|
android: { emulator: true, device: true, unknown: true }
|
|
157609
157826
|
};
|
|
@@ -157628,8 +157845,8 @@ Returns { summary, diffPath, contextDiffPath }. The summary uses normalized [0,1
|
|
|
157628
157845
|
Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
|
|
157629
157846
|
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.`,
|
|
157630
157847
|
searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
|
|
157631
|
-
zodSchema:
|
|
157632
|
-
capability:
|
|
157848
|
+
zodSchema: zodSchema73,
|
|
157849
|
+
capability: capability32,
|
|
157633
157850
|
fileInputs: fileInputs6,
|
|
157634
157851
|
services: (params) => {
|
|
157635
157852
|
if (params.captureBaseline || params.captureCurrent) {
|
|
@@ -157942,7 +158159,7 @@ async function captureElementFrame(registry2, udid, match, opts = {}) {
|
|
|
157942
158159
|
}
|
|
157943
158160
|
|
|
157944
158161
|
// ../tool-server/src/tools/variants/propose-variant.ts
|
|
157945
|
-
var
|
|
158162
|
+
var zodSchema74 = external_exports.object({
|
|
157946
158163
|
element: external_exports.string().min(1).max(200).describe(
|
|
157947
158164
|
'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.'
|
|
157948
158165
|
),
|
|
@@ -158002,7 +158219,7 @@ arrives as a follow-up message (this is the case in an \`argent lens\` CLI sessi
|
|
|
158002
158219
|
Returns { round, elementId, variantId, element, variantCount, totalElements } \u2014 confirmation only;
|
|
158003
158220
|
it does not wait for the user.`,
|
|
158004
158221
|
searchHint: "propose design variant alternative option for element non-blocking ab choice",
|
|
158005
|
-
zodSchema:
|
|
158222
|
+
zodSchema: zodSchema74,
|
|
158006
158223
|
services: () => ({}),
|
|
158007
158224
|
async execute(_services, params) {
|
|
158008
158225
|
let frame = params.variant.frame;
|
|
@@ -158026,7 +158243,7 @@ it does not wait for the user.`,
|
|
|
158026
158243
|
|
|
158027
158244
|
// ../tool-server/src/tools/variants/await-user-selection.ts
|
|
158028
158245
|
init_zod();
|
|
158029
|
-
var
|
|
158246
|
+
var zodSchema75 = external_exports.object({
|
|
158030
158247
|
timeoutSeconds: external_exports.number().int().min(5).max(86400).optional().describe(
|
|
158031
158248
|
"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."
|
|
158032
158249
|
)
|
|
@@ -158067,7 +158284,7 @@ This tool is long-running; it intentionally holds the request open. It honors cl
|
|
|
158067
158284
|
disconnects (aborts cleanly).`,
|
|
158068
158285
|
searchHint: "await wait user selection choice variant blocking confirm picks complete",
|
|
158069
158286
|
longRunning: true,
|
|
158070
|
-
zodSchema:
|
|
158287
|
+
zodSchema: zodSchema75,
|
|
158071
158288
|
services: () => ({}),
|
|
158072
158289
|
async execute(_services, params, options) {
|
|
158073
158290
|
const timeoutMs = (params.timeoutSeconds ?? 1800) * 1e3;
|
|
@@ -158082,7 +158299,7 @@ disconnects (aborts cleanly).`,
|
|
|
158082
158299
|
init_zod();
|
|
158083
158300
|
init_src2();
|
|
158084
158301
|
init_device_info();
|
|
158085
|
-
var
|
|
158302
|
+
var zodSchema76 = external_exports.object({
|
|
158086
158303
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
158087
158304
|
action: external_exports.enum(["list", "select", "new", "close"]).describe(
|
|
158088
158305
|
"list: enumerate tabs/windows. select: make a tab active (every other tool then acts on it). new: open a tab. close: close a tab."
|
|
@@ -158115,7 +158332,7 @@ var tabAction = {
|
|
|
158115
158332
|
failure: "close"
|
|
158116
158333
|
}
|
|
158117
158334
|
};
|
|
158118
|
-
var
|
|
158335
|
+
var capability33 = {
|
|
158119
158336
|
chromium: { app: true }
|
|
158120
158337
|
};
|
|
158121
158338
|
var chromiumTabsTool = {
|
|
@@ -158133,8 +158350,8 @@ var chromiumTabsTool = {
|
|
|
158133
158350
|
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.
|
|
158134
158351
|
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.`,
|
|
158135
158352
|
searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
|
|
158136
|
-
zodSchema:
|
|
158137
|
-
capability:
|
|
158353
|
+
zodSchema: zodSchema76,
|
|
158354
|
+
capability: capability33,
|
|
158138
158355
|
services: (params) => {
|
|
158139
158356
|
const device = resolveDevice(params.udid);
|
|
158140
158357
|
if (device.platform === "chromium") {
|
|
@@ -158235,7 +158452,7 @@ async function clearStorage(cdp, type) {
|
|
|
158235
158452
|
}
|
|
158236
158453
|
|
|
158237
158454
|
// ../tool-server/src/tools/chromium-cookies/index.ts
|
|
158238
|
-
var
|
|
158455
|
+
var zodSchema77 = external_exports.object({
|
|
158239
158456
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
158240
158457
|
action: external_exports.enum(["get", "set", "delete", "clear"]).describe(
|
|
158241
158458
|
"get: read cookies. set: create/update a cookie. delete: remove a named cookie. clear: remove all browser cookies."
|
|
@@ -158258,7 +158475,7 @@ var cookieAction = {
|
|
|
158258
158475
|
delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
|
|
158259
158476
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
158260
158477
|
};
|
|
158261
|
-
var
|
|
158478
|
+
var capability34 = {
|
|
158262
158479
|
chromium: { app: true }
|
|
158263
158480
|
};
|
|
158264
158481
|
var chromiumCookiesTool = {
|
|
@@ -158276,8 +158493,8 @@ var chromiumCookiesTool = {
|
|
|
158276
158493
|
Use when seeding an authenticated session before a flow (set the session cookie, then navigate) or asserting cookie state after one.
|
|
158277
158494
|
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.`,
|
|
158278
158495
|
searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
|
|
158279
|
-
zodSchema:
|
|
158280
|
-
capability:
|
|
158496
|
+
zodSchema: zodSchema77,
|
|
158497
|
+
capability: capability34,
|
|
158281
158498
|
services: (params) => {
|
|
158282
158499
|
const device = resolveDevice(params.udid);
|
|
158283
158500
|
if (device.platform === "chromium") {
|
|
@@ -158342,7 +158559,7 @@ Returns { cookies, count } for get, or a small status object ({ set } / { delete
|
|
|
158342
158559
|
init_zod();
|
|
158343
158560
|
init_src2();
|
|
158344
158561
|
init_device_info();
|
|
158345
|
-
var
|
|
158562
|
+
var zodSchema78 = external_exports.object({
|
|
158346
158563
|
udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
|
|
158347
158564
|
store: external_exports.enum(["local", "session"]).describe("Which Web Storage area: `local` (localStorage) or `session` (sessionStorage)."),
|
|
158348
158565
|
action: external_exports.enum(["get", "set", "remove", "clear"]).describe(
|
|
@@ -158357,7 +158574,7 @@ var storageAction = {
|
|
|
158357
158574
|
remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
|
|
158358
158575
|
clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
|
|
158359
158576
|
};
|
|
158360
|
-
var
|
|
158577
|
+
var capability35 = {
|
|
158361
158578
|
chromium: { app: true }
|
|
158362
158579
|
};
|
|
158363
158580
|
var chromiumStorageTool = {
|
|
@@ -158376,8 +158593,8 @@ Set \`store\` to "local" or "session". Storage is per-origin, so it reflects the
|
|
|
158376
158593
|
Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one.
|
|
158377
158594
|
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.`,
|
|
158378
158595
|
searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
|
|
158379
|
-
zodSchema:
|
|
158380
|
-
capability:
|
|
158596
|
+
zodSchema: zodSchema78,
|
|
158597
|
+
capability: capability35,
|
|
158381
158598
|
services: (params) => {
|
|
158382
158599
|
const device = resolveDevice(params.udid);
|
|
158383
158600
|
if (device.platform === "chromium") {
|
|
@@ -158487,6 +158704,7 @@ function createRegistry() {
|
|
|
158487
158704
|
registry2.registerTool(networkLogsTool);
|
|
158488
158705
|
registry2.registerTool(networkRequestTool);
|
|
158489
158706
|
registry2.registerTool(createDescribeTool(registry2));
|
|
158707
|
+
registry2.registerTool(createUiTreeTool(registry2));
|
|
158490
158708
|
registry2.registerTool(createAwaitUiElementTool(registry2));
|
|
158491
158709
|
registry2.registerTool(createAwaitScreenIdleTool(registry2));
|
|
158492
158710
|
registry2.registerTool(createReactProfilerStartTool(registry2));
|