@swmansion/argent 0.27.1-next.6 → 0.27.1-next.8

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.
@@ -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 = (zodSchema78) => {
13122
- const seen = ctx.seen.get(zodSchema78);
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 = zodSchema78._zod.parent === ref;
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 = zodSchema78._zod.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: zodSchema78,
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 zodSchema79 = convertSchema(resolved, ctx);
15980
- ctx.refs.set(refPath, zodSchema79);
15979
+ const zodSchema80 = convertSchema(resolved, ctx);
15980
+ ctx.refs.set(refPath, zodSchema80);
15981
15981
  ctx.processing.delete(refPath);
15982
- return zodSchema79;
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 zodSchema78;
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
- zodSchema78 = stringSchema;
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
- zodSchema78 = numberSchema;
16112
+ zodSchema79 = numberSchema;
16113
16113
  break;
16114
16114
  }
16115
16115
  case "boolean": {
16116
- zodSchema78 = z.boolean();
16116
+ zodSchema79 = z.boolean();
16117
16117
  break;
16118
16118
  }
16119
16119
  case "null": {
16120
- zodSchema78 = z.null();
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
- zodSchema78 = z.record(keySchema, valueSchema);
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
- zodSchema78 = z.intersection(objectSchema2, recordSchema);
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
- zodSchema78 = z.object({}).passthrough();
16158
+ zodSchema79 = z.object({}).passthrough();
16159
16159
  } else if (schemasToIntersect.length === 1) {
16160
- zodSchema78 = schemasToIntersect[0];
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
- zodSchema78 = result;
16166
+ zodSchema79 = result;
16167
16167
  }
16168
16168
  break;
16169
16169
  }
16170
16170
  const objectSchema = z.object(shape);
16171
16171
  if (schema.additionalProperties === false) {
16172
- zodSchema78 = objectSchema.strict();
16172
+ zodSchema79 = objectSchema.strict();
16173
16173
  } else if (typeof schema.additionalProperties === "object") {
16174
- zodSchema78 = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));
16174
+ zodSchema79 = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));
16175
16175
  } else {
16176
- zodSchema78 = objectSchema.passthrough();
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
- zodSchema78 = z.tuple(tupleItems).rest(rest);
16187
+ zodSchema79 = z.tuple(tupleItems).rest(rest);
16188
16188
  } else {
16189
- zodSchema78 = z.tuple(tupleItems);
16189
+ zodSchema79 = z.tuple(tupleItems);
16190
16190
  }
16191
16191
  if (typeof schema.minItems === "number") {
16192
- zodSchema78 = zodSchema78.check(z.minLength(schema.minItems));
16192
+ zodSchema79 = zodSchema79.check(z.minLength(schema.minItems));
16193
16193
  }
16194
16194
  if (typeof schema.maxItems === "number") {
16195
- zodSchema78 = zodSchema78.check(z.maxLength(schema.maxItems));
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
- zodSchema78 = z.tuple(tupleItems).rest(rest);
16201
+ zodSchema79 = z.tuple(tupleItems).rest(rest);
16202
16202
  } else {
16203
- zodSchema78 = z.tuple(tupleItems);
16203
+ zodSchema79 = z.tuple(tupleItems);
16204
16204
  }
16205
16205
  if (typeof schema.minItems === "number") {
16206
- zodSchema78 = zodSchema78.check(z.minLength(schema.minItems));
16206
+ zodSchema79 = zodSchema79.check(z.minLength(schema.minItems));
16207
16207
  }
16208
16208
  if (typeof schema.maxItems === "number") {
16209
- zodSchema78 = zodSchema78.check(z.maxLength(schema.maxItems));
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
- zodSchema78 = arraySchema;
16220
+ zodSchema79 = arraySchema;
16221
16221
  } else {
16222
- zodSchema78 = z.array(z.any());
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 zodSchema78;
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, capability35) {
73553
- assertExternalCapabilitySync(namespace, device, capability35);
73552
+ async function assertExternalCapability(namespace, device, capability36) {
73553
+ assertExternalCapabilitySync(namespace, device, capability36);
73554
73554
  }
73555
- function assertExternalCapabilitySync(namespace, device, capability35) {
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(capability35)) return;
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 '${capability35}' capability for this device.`,
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.6";
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 capability35 = options?.granted ?? "simctl";
96592
- assertExternalCapabilitySync(capability35, udid, capability35);
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, capability35) {
97764
+ function platformMatrix(platform, capability36) {
97745
97765
  switch (platform) {
97746
97766
  case "ios":
97747
- return capability35.apple;
97767
+ return capability36.apple;
97748
97768
  case "ios-remote":
97749
- return capability35.appleRemote;
97769
+ return capability36.appleRemote;
97750
97770
  case "android":
97751
- return capability35.android;
97771
+ return capability36.android;
97752
97772
  case "chromium":
97753
- return capability35.chromium;
97773
+ return capability36.chromium;
97754
97774
  case "vega":
97755
- return capability35.vega;
97775
+ return capability36.vega;
97756
97776
  }
97757
97777
  }
97758
- function assertSupported(toolId, capability35, device) {
97759
- if (!capability35) return;
97760
- const matrix = platformMatrix(device.platform, capability35);
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 (capability35.supports && !capability35.supports(device)) {
97788
+ if (capability36.supports && !capability36.supports(device)) {
97769
97789
  throw new UnsupportedOperationError(toolId, device, "supports() refiner rejected device");
97770
97790
  }
97771
97791
  }
@@ -126800,9 +126820,9 @@ async function invokeSubTool(registry2, ctx, toolId, args) {
126800
126820
  }
126801
126821
  function describeNestedParamError(registry2, err, toolId, dispatchedArgs, authoredArgs) {
126802
126822
  if (getFailureSignal(err)?.error_code !== FAILURE_CODES.TOOL_INPUT_INVALID) return void 0;
126803
- const zodSchema78 = registry2.getTool(toolId)?.zodSchema;
126804
- if (!zodSchema78) return void 0;
126805
- const parsed = zodSchema78.safeParse(dispatchedArgs ?? {});
126823
+ const zodSchema79 = registry2.getTool(toolId)?.zodSchema;
126824
+ if (!zodSchema79) return void 0;
126825
+ const parsed = zodSchema79.safeParse(dispatchedArgs ?? {});
126806
126826
  if (parsed.success) return void 0;
126807
126827
  return `Invalid params for tool "${toolId}": ${describeParamIssues(parsed.error, authoredArgs)}`;
126808
126828
  }
@@ -136060,6 +136080,334 @@ back/menu/home), then call describe again to confirm where focus landed.`,
136060
136080
  };
136061
136081
  }
136062
136082
 
136083
+ // ../tool-server/src/tools/ui-tree/index.ts
136084
+ init_zod();
136085
+
136086
+ // ../tool-server/src/tools/ui-tree/ios.ts
136087
+ var UNSUPPORTED_FIELDS = [
136088
+ "type",
136089
+ "password",
136090
+ "placeholder",
136091
+ "hintShowing",
136092
+ "hidden",
136093
+ "foregroundApp"
136094
+ ];
136095
+ function adaptAxTree(response) {
136096
+ const byIndex = /* @__PURE__ */ new Map();
136097
+ const roots = [];
136098
+ let keyboardVisible = false;
136099
+ for (const raw of response.nodes) {
136100
+ const traits = raw.traits ?? [];
136101
+ const has = (name) => traits.includes(name);
136102
+ if (has("keyboardKey")) keyboardVisible = true;
136103
+ const node = {
136104
+ role: mapNativeTraitsToDescribeRole(traits),
136105
+ label: raw.label,
136106
+ value: raw.value,
136107
+ identifier: raw.identifier,
136108
+ roleDescription: raw.roleDescription,
136109
+ frame: raw.frame,
136110
+ children: []
136111
+ };
136112
+ if (traits.length > 0) node.traits = traits;
136113
+ if (has("header")) node.heading = true;
136114
+ if (has("notEnabled")) node.disabled = true;
136115
+ if (has("selected")) node.selected = true;
136116
+ if (has("isEditing")) node.focused = true;
136117
+ if (has("textEntry") || has("searchField")) node.editable = true;
136118
+ if (has("toggleButton") && (raw.value === "1" || raw.value === "0")) {
136119
+ node.checked = raw.value === "1";
136120
+ }
136121
+ if (raw.covered) node.covered = true;
136122
+ const parent = raw.parentIndex === void 0 ? void 0 : byIndex.get(raw.parentIndex);
136123
+ byIndex.set(raw.index, node);
136124
+ (parent ? parent.children : roots).push(node);
136125
+ }
136126
+ return {
136127
+ schemaVersion: 1,
136128
+ source: "ax-service",
136129
+ screen: response.screenFrame,
136130
+ roots,
136131
+ truncated: response.truncated,
136132
+ alertVisible: response.alertVisible,
136133
+ // A truncated walk may have cut the keyboard, so absence is unknown there.
136134
+ keyboardVisible: keyboardVisible || (response.truncated ? void 0 : false),
136135
+ unsupportedFields: UNSUPPORTED_FIELDS
136136
+ };
136137
+ }
136138
+ async function readIosUiTree(registry2, device) {
136139
+ const ref = axServiceRef(device);
136140
+ const ax = await registry2.resolveService(ref.urn, ref.options);
136141
+ return adaptAxTree(await ax.tree());
136142
+ }
136143
+
136144
+ // ../tool-server/src/tools/flows/flow-tree-flatten.ts
136145
+ function intersectClip(rect, clip3) {
136146
+ if (!clip3) return rect;
136147
+ const x1 = Math.max(rect.x, clip3.x);
136148
+ const y1 = Math.max(rect.y, clip3.y);
136149
+ const x2 = Math.min(rect.x + rect.w, clip3.x + clip3.w);
136150
+ const y2 = Math.min(rect.y + rect.h, clip3.y + clip3.h);
136151
+ return { x: x1, y: y1, w: Math.max(0, x2 - x1), h: Math.max(0, y2 - y1) };
136152
+ }
136153
+ function includesWordsCI(haystack, needle) {
136154
+ const h = haystack.toLowerCase();
136155
+ const n = needle.toLowerCase();
136156
+ if (!n) return false;
136157
+ const isWordChar = (c) => c !== void 0 && /[\p{L}\p{N}]/u.test(c);
136158
+ for (let at = h.indexOf(n); at !== -1; at = h.indexOf(n, at + 1)) {
136159
+ if (!isWordChar(h[at - 1]) && !isWordChar(h[at + n.length])) return true;
136160
+ }
136161
+ return false;
136162
+ }
136163
+ function flattenHoisting(node, project, out, scrollClip = null) {
136164
+ const view = project(node);
136165
+ if (view.skip) return "";
136166
+ if (scrollClip && view.rect && rectFullyOutside(view.rect, scrollClip)) return "";
136167
+ const childClip = view.scrolls && view.rect ? intersectClip(view.rect, scrollClip) : scrollClip;
136168
+ const childText = [];
136169
+ for (const child of view.children) {
136170
+ const t = flattenHoisting(child, project, out, childClip);
136171
+ if (t) childText.push(t);
136172
+ }
136173
+ const descendantText2 = childText.join(" ");
136174
+ const subtree = view.ownText && !includesWordsCI(descendantText2, view.ownText) ? [view.ownText, descendantText2].filter(Boolean).join(" ") : descendantText2 || view.ownText;
136175
+ if (view.leaf) {
136176
+ if (subtree && subtree !== view.ownText) view.leaf.subtreeText = subtree;
136177
+ out.push(view.leaf);
136178
+ }
136179
+ return view.shield ? "" : subtree;
136180
+ }
136181
+
136182
+ // ../tool-server/src/tools/flows/flow-android-tree.ts
136183
+ var FLOW_MAX_NODES = 12e3;
136184
+ var SYSTEM_PACKAGES2 = /* @__PURE__ */ new Set(["com.android.systemui"]);
136185
+ var SYSTEM_RID_PREFIXES2 = [
136186
+ "android:id/navigationBarBackground",
136187
+ "android:id/statusBarBackground",
136188
+ "com.android.systemui:id/"
136189
+ ];
136190
+ function isSystemChrome2(attrs) {
136191
+ if (SYSTEM_PACKAGES2.has(attrs.package ?? "")) return true;
136192
+ const rid = attrs["resource-id"] ?? "";
136193
+ return SYSTEM_RID_PREFIXES2.some((p) => rid.startsWith(p));
136194
+ }
136195
+ function labelOf2(attrs) {
136196
+ const cd = (attrs["content-desc"] ?? "").trim();
136197
+ if (cd) return cd;
136198
+ return (attrs.text ?? "").trim();
136199
+ }
136200
+ function normalizeRect(rect, screenW, screenH) {
136201
+ const clipped = clipBoundsToScreen(rect, screenW, screenH);
136202
+ if (clipped.w <= 0 || clipped.h <= 0) return null;
136203
+ return {
136204
+ x: clipped.x / screenW,
136205
+ y: clipped.y / screenH,
136206
+ width: clipped.w / screenW,
136207
+ height: clipped.h / screenH
136208
+ };
136209
+ }
136210
+ function childNodes(node) {
136211
+ return node.children.filter((c) => c.tag === "node");
136212
+ }
136213
+ function projectAndroidNode(node, screenW, screenH) {
136214
+ const attrs = node.attrs;
136215
+ const skip2 = isSystemChrome2(attrs) || isNoisyUiAutomatorClass(attrs.class ?? "");
136216
+ const identifier = (attrs["resource-id"] ?? "").trim();
136217
+ const isPassword = attrs.password === "true";
136218
+ const isFocused = attrs.focused === "true";
136219
+ const label = isPassword ? "[password]" : labelOf2(attrs);
136220
+ const rawText = (attrs.text ?? "").trim();
136221
+ const hasValue = !isPassword && Boolean(rawText) && rawText !== label;
136222
+ const className = attrs.class ?? "";
136223
+ const role = deriveUiAutomatorRole(className);
136224
+ const hasSemanticRole = !isUiAutomatorLayoutContainer(className);
136225
+ const ownText2 = [label, hasValue ? rawText : ""].filter(Boolean).join(" ");
136226
+ const rect = parseUiAutomatorBounds(attrs.bounds ?? "");
136227
+ let leaf = null;
136228
+ let frame = null;
136229
+ if (!skip2 && (identifier || label || hasSemanticRole || isFocused)) {
136230
+ frame = rect ? normalizeRect(rect, screenW, screenH) : null;
136231
+ if (frame) {
136232
+ leaf = { role, frame, children: [] };
136233
+ if (label) leaf.label = label;
136234
+ if (identifier) leaf.identifier = identifier;
136235
+ if (hasValue) leaf.value = rawText;
136236
+ if (attrs.clickable === "true") leaf.clickable = true;
136237
+ if (attrs["long-clickable"] === "true") leaf.longClickable = true;
136238
+ if (attrs.scrollable === "true") leaf.scrollable = true;
136239
+ if (attrs.checkable === "true") leaf.checkable = true;
136240
+ if (attrs.checked === "true") leaf.checked = true;
136241
+ if (attrs.enabled === "false") leaf.disabled = true;
136242
+ if (isPassword) leaf.password = true;
136243
+ if (isFocused) leaf.focused = true;
136244
+ }
136245
+ }
136246
+ return {
136247
+ skip: skip2,
136248
+ children: childNodes(node),
136249
+ // Off-screen text must not hoist, or an ancestor text assert would pass on
136250
+ // content the screen doesn't show. Any node with text is leaf-eligible (its
136251
+ // label is non-empty), so `frame` was computed for it.
136252
+ ownText: frame ? ownText2 : "",
136253
+ leaf,
136254
+ // A password field shields even when it carries no id, so nothing from it
136255
+ // bubbles into an ancestor's hoisted text.
136256
+ shield: Boolean(identifier) || isPassword,
136257
+ // Scroll-clip inputs (see `flattenHoisting`): a scroller's raw bounds clip
136258
+ // its subtree, so a row scrolled out of view — but still on the device
136259
+ // screen — is dropped, matching the describe path's prune.
136260
+ rect,
136261
+ scrolls: isUiAutomatorScrollable(attrs)
136262
+ };
136263
+ }
136264
+ function adaptFullAndroidHierarchyToDescribeResult(xml, screenW, screenH) {
136265
+ const children = [];
136266
+ if (screenW > 0 && screenH > 0) {
136267
+ const root = parseUiAutomatorXml(xml);
136268
+ if (root) {
136269
+ for (const c of childNodes(root)) {
136270
+ flattenHoisting(c, (n) => projectAndroidNode(n, screenW, screenH), children);
136271
+ }
136272
+ }
136273
+ }
136274
+ return parseDescribeResult({
136275
+ role: "Screen",
136276
+ frame: { x: 0, y: 0, width: 1, height: 1 },
136277
+ children
136278
+ });
136279
+ }
136280
+ async function queryAndroidFullHierarchy(registry2, device) {
136281
+ let devtools;
136282
+ try {
136283
+ const ref = androidDevtoolsRef(device);
136284
+ devtools = await registry2.resolveService(ref.urn, ref.options);
136285
+ } catch (err) {
136286
+ const msg = err instanceof Error ? err.message : String(err);
136287
+ throw new Error(`the argent android helper is unavailable: ${msg}`, { cause: err });
136288
+ }
136289
+ const [{ xml }, size] = await Promise.all([
136290
+ // clearCache: await/assert polls must see text changes, not cached reads.
136291
+ devtools.getHierarchy({ maxNodes: FLOW_MAX_NODES, clearCache: true }),
136292
+ devtools.getScreenSize()
136293
+ ]);
136294
+ const tree = adaptFullAndroidHierarchyToDescribeResult(xml, size.width, size.height);
136295
+ return {
136296
+ tree,
136297
+ source: "android-devtools",
136298
+ ...size.width > 0 && size.height > 0 ? { screen: { width: size.width, height: size.height } } : {}
136299
+ };
136300
+ }
136301
+
136302
+ // ../tool-server/src/tools/ui-tree/android.ts
136303
+ var UNSUPPORTED_FIELDS2 = [
136304
+ "placeholder",
136305
+ "hintShowing",
136306
+ "hidden",
136307
+ "heading",
136308
+ "keyboardVisible",
136309
+ "foregroundApp"
136310
+ ];
136311
+ function mapNode(xml, screenW, screenH, isRoot) {
136312
+ const a = xml.attrs;
136313
+ const type = a.class ?? "";
136314
+ const password = attrIsTrue(a, "password");
136315
+ const text = password ? "" : a.text ?? "";
136316
+ const desc = a["content-desc"] ?? "";
136317
+ const rect = parseUiAutomatorBounds(a.bounds ?? "");
136318
+ const editable = type.endsWith("EditText") || type.endsWith("AutoCompleteTextView");
136319
+ const node = { role: deriveUiAutomatorRole(type), children: [] };
136320
+ if (type) node.type = type;
136321
+ if (text || desc) node.label = text || desc;
136322
+ if (editable && text) node.value = text;
136323
+ if (desc) node.contentDescription = desc;
136324
+ if (a["resource-id"]) node.identifier = a["resource-id"];
136325
+ if (isRoot && a.package) node.bundleId = a.package;
136326
+ if (rect && screenW > 0 && screenH > 0) {
136327
+ node.frame = {
136328
+ x: rect.x / screenW,
136329
+ y: rect.y / screenH,
136330
+ width: rect.w / screenW,
136331
+ height: rect.h / screenH
136332
+ };
136333
+ }
136334
+ if (a.enabled === "false") node.disabled = true;
136335
+ if (attrIsTrue(a, "selected")) node.selected = true;
136336
+ if (attrIsTrue(a, "focused")) node.focused = true;
136337
+ if (attrIsTrue(a, "checkable")) node.checked = attrIsTrue(a, "checked");
136338
+ if (password) node.password = true;
136339
+ if (editable) node.editable = true;
136340
+ for (const child of xml.children) {
136341
+ if (child.tag === "node") node.children.push(mapNode(child, screenW, screenH, false));
136342
+ }
136343
+ return node;
136344
+ }
136345
+ function adaptAndroidTree(xml, truncated, screen) {
136346
+ const root = parseUiAutomatorXml(xml);
136347
+ const roots = (root?.children ?? []).filter((c) => c.tag === "node").map((c) => mapNode(c, screen.width, screen.height, true));
136348
+ return {
136349
+ schemaVersion: 1,
136350
+ source: "android-devtools",
136351
+ screen: { width: screen.width, height: screen.height },
136352
+ roots,
136353
+ truncated,
136354
+ unsupportedFields: UNSUPPORTED_FIELDS2
136355
+ };
136356
+ }
136357
+ async function readAndroidUiTree(registry2, device) {
136358
+ const ref = androidDevtoolsRef(device);
136359
+ const devtools = await registry2.resolveService(ref.urn, ref.options);
136360
+ const [{ xml, truncated }, size] = await Promise.all([
136361
+ devtools.getHierarchy({ maxNodes: FLOW_MAX_NODES, clearCache: true }),
136362
+ devtools.getScreenSize()
136363
+ ]);
136364
+ return adaptAndroidTree(xml, truncated, size);
136365
+ }
136366
+
136367
+ // ../tool-server/src/tools/ui-tree/index.ts
136368
+ var zodSchema40 = external_exports.object({
136369
+ udid: external_exports.string().min(1).describe("Target device id from `list-devices`.")
136370
+ });
136371
+ var capability25 = {
136372
+ apple: { simulator: true },
136373
+ android: { emulator: true, device: true, unknown: true }
136374
+ };
136375
+ function createUiTreeTool(registry2) {
136376
+ return {
136377
+ id: "ui-tree",
136378
+ interaction: {
136379
+ startedMsg: () => "Reading UI tree",
136380
+ completedMsg: () => "Read UI tree",
136381
+ failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to read UI tree: ${failureSignal2.error_code}`
136382
+ },
136383
+ description: `Read the raw accessibility tree of the screen as nested JSON, for SDK callers.
136384
+ Use when a program needs element ancestry, such as an e2e engine's scoped selectors; agents use describe.
136385
+ Returns { schemaVersion, roots, truncated, alertVisible, keyboardVisible, unsupportedFields }.
136386
+ Fails if the iOS ax-service predates the tree command; update argent.`,
136387
+ hideFromMcp: true,
136388
+ zodSchema: zodSchema40,
136389
+ capability: capability25,
136390
+ services: () => ({}),
136391
+ execute: dispatchByPlatform({
136392
+ toolId: "ui-tree",
136393
+ capability: capability25,
136394
+ ios: {
136395
+ requires: iosRequires,
136396
+ handler: async (_services, _params, device) => {
136397
+ if (await isTvOsSimulator(device.id)) {
136398
+ throw new UnsupportedOperationError("ui-tree", device, "tvOS");
136399
+ }
136400
+ return readIosUiTree(registry2, device);
136401
+ }
136402
+ },
136403
+ android: {
136404
+ requires: androidRequires,
136405
+ handler: async (_services, _params, device) => readAndroidUiTree(registry2, device)
136406
+ }
136407
+ })
136408
+ };
136409
+ }
136410
+
136063
136411
  // ../tool-server/src/tools/await-screen-idle/index.ts
136064
136412
  init_zod();
136065
136413
  init_device_info();
@@ -136068,7 +136416,7 @@ var AWAIT_SCREEN_IDLE_TOOL_ID = "await-screen-idle";
136068
136416
  var DEFAULT_TIMEOUT_MS4 = 3e3;
136069
136417
  var DEFAULT_POLL_INTERVAL_MS2 = 200;
136070
136418
  var DEFAULT_MIN_STABLE_MS = 250;
136071
- var zodSchema40 = external_exports.object({
136419
+ var zodSchema41 = external_exports.object({
136072
136420
  udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id)."),
136073
136421
  timeoutMs: external_exports.number().int().positive().max(12e4).optional().describe(
136074
136422
  `Max time to wait for the screen to settle before giving up (default ${DEFAULT_TIMEOUT_MS4}).`
@@ -136078,7 +136426,7 @@ var zodSchema40 = external_exports.object({
136078
136426
  `The screen must hold the same content for at least this long to count as settled (default ${DEFAULT_MIN_STABLE_MS}).`
136079
136427
  )
136080
136428
  });
136081
- var capability25 = {
136429
+ var capability26 = {
136082
136430
  apple: { simulator: true, device: true },
136083
136431
  appleRemote: { simulator: true },
136084
136432
  android: { emulator: true, device: true, unknown: true },
@@ -136125,8 +136473,8 @@ ${DEFAULT_TIMEOUT_MS4}ms) is reached. Returns { settled, waitedMs, polls } \u201
136125
136473
  still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.`,
136126
136474
  searchHint: "wait until screen settles idle stable stops changing animation transition rendered ready before screenshot",
136127
136475
  longRunning: true,
136128
- zodSchema: zodSchema40,
136129
- capability: capability25,
136476
+ zodSchema: zodSchema41,
136477
+ capability: capability26,
136130
136478
  services: (params) => {
136131
136479
  const device = resolveDevice(params.udid);
136132
136480
  if (device.platform === "chromium") {
@@ -136136,7 +136484,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
136136
136484
  },
136137
136485
  async execute(services, params, ctx) {
136138
136486
  const device = resolveDevice(params.udid);
136139
- assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability25, device);
136487
+ assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability26, device);
136140
136488
  if (device.platform === "ios") await ensureDeps(iosRequires);
136141
136489
  else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
136142
136490
  else if (device.platform === "android") await ensureDeps(androidRequires);
@@ -136223,7 +136571,7 @@ function bootstrapFailureMessage(bootstrap) {
136223
136571
  // ../tool-server/src/tools/profiler/react/react-profiler-start.ts
136224
136572
  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
136573
  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 zodSchema41 = external_exports.object({
136574
+ var zodSchema42 = external_exports.object({
136227
136575
  port: metroPortField,
136228
136576
  device_id: external_exports.string().describe(
136229
136577
  "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
@@ -136255,7 +136603,7 @@ Before calling this, ask the user if they also want native profiling (native-pro
136255
136603
  After starting, ask the user to perform the interaction to profile, then call react-profiler-stop.
136256
136604
  Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above.
136257
136605
  Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.`,
136258
- zodSchema: zodSchema41,
136606
+ zodSchema: zodSchema42,
136259
136607
  capability: RN_ONLY_TOOL_CAPABILITY,
136260
136608
  services: () => ({}),
136261
136609
  async execute(_services, params) {
@@ -136526,7 +136874,7 @@ async function readCommitTree(path51) {
136526
136874
  }
136527
136875
 
136528
136876
  // ../tool-server/src/tools/profiler/react/react-profiler-stop.ts
136529
- var zodSchema42 = external_exports.object({
136877
+ var zodSchema43 = external_exports.object({
136530
136878
  port: metroPortField,
136531
136879
  device_id: external_exports.string().describe(
136532
136880
  "Device id from list-devices \u2014 the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
@@ -136615,7 +136963,7 @@ Call react-profiler-start first, then exercise the app, then call this.
136615
136963
  Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session.
136616
136964
  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
136965
  Fails if no active profiling session exists or the CDP connection was lost during recording.`,
136618
- zodSchema: zodSchema42,
136966
+ zodSchema: zodSchema43,
136619
136967
  capability: RN_ONLY_TOOL_CAPABILITY,
136620
136968
  services: () => ({}),
136621
136969
  async execute(_services, params) {
@@ -136840,7 +137188,7 @@ Fails if no active profiling session exists or the CDP connection was lost durin
136840
137188
 
136841
137189
  // ../tool-server/src/tools/profiler/react/react-profiler-status.ts
136842
137190
  init_zod();
136843
- var zodSchema43 = external_exports.object({
137191
+ var zodSchema44 = external_exports.object({
136844
137192
  port: metroPortField,
136845
137193
  device_id: external_exports.string().describe(
136846
137194
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -136855,7 +137203,7 @@ function createReactProfilerStatusTool(registry2) {
136855
137203
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to check React profiler: ${failureSignal2.error_code}`
136856
137204
  },
136857
137205
  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: zodSchema43,
137206
+ zodSchema: zodSchema44,
136859
137207
  // RN-only: companion to react-profiler-start.
136860
137208
  capability: RN_ONLY_TOOL_CAPABILITY,
136861
137209
  services: () => ({}),
@@ -138469,7 +138817,7 @@ var annotationSchema = external_exports.object({
138469
138817
  ),
138470
138818
  label: external_exports.string().describe("Description of the action performed")
138471
138819
  });
138472
- var zodSchema44 = external_exports.object({
138820
+ var zodSchema45 = external_exports.object({
138473
138821
  port: metroPortField,
138474
138822
  device_id: external_exports.string().describe(
138475
138823
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -138502,7 +138850,7 @@ where tapTimestampMs is the timestampMs returned by the tap/swipe tool and start
138502
138850
  is returned by react-profiler-start.
138503
138851
  Use when the profiling session is complete and you need to interpret the collected data.
138504
138852
  Fails if react-profiler-stop has not been called or no profiling data is stored.`,
138505
- zodSchema: zodSchema44,
138853
+ zodSchema: zodSchema45,
138506
138854
  // RN-only: reads commit data captured via the React DevTools backend, which
138507
138855
  // Chromium does not have.
138508
138856
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -138639,7 +138987,7 @@ Fails if react-profiler-stop has not been called or no profiling data is stored.
138639
138987
  // ../tool-server/src/tools/profiler/react/react-profiler-component-source.ts
138640
138988
  init_zod();
138641
138989
  var import_fs6 = require("fs");
138642
- var zodSchema45 = external_exports.object({
138990
+ var zodSchema46 = external_exports.object({
138643
138991
  component_name: external_exports.string().describe("Name of the React component to look up"),
138644
138992
  project_root: external_exports.string().describe("Absolute path to the RN project root")
138645
138993
  });
@@ -138657,7 +139005,7 @@ var reactProfilerComponentSourceTool = {
138657
139005
  Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.
138658
139006
  Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules).
138659
139007
  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: zodSchema45,
139008
+ zodSchema: zodSchema46,
138661
139009
  // Declared so the tool catalogue groups this with the other react-profiler-*
138662
139010
  // tools; the HTTP gate itself is a no-op here, as there is no device arg to
138663
139011
  // inspect.
@@ -138713,7 +139061,7 @@ When several files define a component with the same name (e.g. platform variants
138713
139061
  // ../tool-server/src/tools/profiler/react/react-profiler-cpu-summary.ts
138714
139062
  init_zod();
138715
139063
  init_src2();
138716
- var zodSchema46 = external_exports.object({
139064
+ var zodSchema47 = external_exports.object({
138717
139065
  port: metroPortField,
138718
139066
  device_id: external_exports.string().describe(
138719
139067
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -138795,7 +139143,7 @@ Use when you specifically need to investigate JS CPU hotspots that are NOT tied
138795
139143
  Call react-profiler-stop first. Reads directly from the stored cpuProfile.
138796
139144
  Returns a markdown table of the top hotspot functions with self-time, total-time, and location.
138797
139145
  Fails if react-profiler-stop has not been called or no CPU profile is stored.`,
138798
- zodSchema: zodSchema46,
139146
+ zodSchema: zodSchema47,
138799
139147
  // RN-only: reads a Hermes CPU profile; Chromium's V8 sample format differs.
138800
139148
  capability: RN_ONLY_TOOL_CAPABILITY,
138801
139149
  services: () => ({}),
@@ -138891,7 +139239,7 @@ function renderMarkdownTable2(entries) {
138891
139239
  );
138892
139240
  return [header, sep5, ...rows].join("\n");
138893
139241
  }
138894
- var zodSchema47 = external_exports.object({
139242
+ var zodSchema48 = external_exports.object({
138895
139243
  port: metroPortField,
138896
139244
  device_id: external_exports.string().describe(
138897
139245
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -138909,7 +139257,7 @@ var reactProfilerRendersTool = {
138909
139257
  Returns a markdown table of the top re-rendering components. No profiling session required \u2014 works on a live connected app.
138910
139258
  Use when you want a quick snapshot of render counts without a full profiling session.
138911
139259
  Fails if the React DevTools hook is not present in the runtime or the app is not connected.`,
138912
- zodSchema: zodSchema47,
139260
+ zodSchema: zodSchema48,
138913
139261
  // RN-only: queries the React DevTools backend hook on the live runtime.
138914
139262
  capability: RN_ONLY_TOOL_CAPABILITY,
138915
139263
  services: (params) => ({
@@ -139066,7 +139414,7 @@ function buildFiberTreeScript(maxDepth, filter) {
139066
139414
  }
139067
139415
  })()`;
139068
139416
  }
139069
- var zodSchema48 = external_exports.object({
139417
+ var zodSchema49 = external_exports.object({
139070
139418
  port: metroPortField,
139071
139419
  device_id: external_exports.string().describe(
139072
139420
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -139085,7 +139433,7 @@ var reactProfilerFiberTreeTool = {
139085
139433
  Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component).
139086
139434
  Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children.
139087
139435
  Fails if the React DevTools hook is not present or no fiber roots have been committed yet.`,
139088
- zodSchema: zodSchema48,
139436
+ zodSchema: zodSchema49,
139089
139437
  // RN-only: walks the fiber tree via the React DevTools backend hook.
139090
139438
  capability: RN_ONLY_TOOL_CAPABILITY,
139091
139439
  services: (params) => ({
@@ -142883,7 +143231,7 @@ function metroDeviceIdParam(description) {
142883
143231
  }
142884
143232
 
142885
143233
  // ../tool-server/src/tools/profiler/native-profiler/native-profiler-start.ts
142886
- var zodSchema49 = external_exports.object({
143234
+ var zodSchema50 = external_exports.object({
142887
143235
  device_id: metroDeviceIdParam(
142888
143236
  "Target device id from `list-devices` (iOS UDID or Android serial)."
142889
143237
  ),
@@ -142897,7 +143245,7 @@ var zodSchema49 = external_exports.object({
142897
143245
  "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
143246
  )
142899
143247
  });
142900
- var capability26 = {
143248
+ var capability27 = {
142901
143249
  apple: { simulator: true },
142902
143250
  android: { emulator: true, device: true, unknown: true }
142903
143251
  };
@@ -142908,21 +143256,21 @@ var nativeProfilerStartTool = {
142908
143256
  completedMsg: () => "Started native profiler",
142909
143257
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start native profiler: ${failureSignal2.error_code}`
142910
143258
  },
142911
- capability: capability26,
143259
+ capability: capability27,
142912
143260
  description: `Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal).
142913
143261
  Auto-detects the running app process unless app_process is explicitly provided.
142914
143262
  After starting, let the user interact with the app, then call native-profiler-stop.
142915
143263
  Use when you want to capture native CPU, hang, and memory data for a running app.
142916
143264
  Returns { status, pid, traceFile } confirming the recording has started.
142917
143265
  Fails if no app is running on the device, or the profiler cannot attach to the process.`,
142918
- zodSchema: zodSchema49,
143266
+ zodSchema: zodSchema50,
142919
143267
  services: (params) => ({
142920
143268
  session: nativeProfilerSessionRef(resolveDevice(params.device_id))
142921
143269
  }),
142922
143270
  async execute(services, params) {
142923
143271
  const api = services.session;
142924
143272
  const device = resolveDevice(params.device_id);
142925
- assertSupported("native-profiler-start", capability26, device);
143273
+ assertSupported("native-profiler-start", capability27, device);
142926
143274
  if (api.platform === "ios") {
142927
143275
  await ensureDeps(["xcrun"]);
142928
143276
  return startNativeProfilerIos(api, params);
@@ -142935,12 +143283,12 @@ Fails if no app is running on the device, or the profiler cannot attach to the p
142935
143283
  // ../tool-server/src/tools/profiler/native-profiler/native-profiler-stop.ts
142936
143284
  init_zod();
142937
143285
  init_device_info();
142938
- var zodSchema50 = external_exports.object({
143286
+ var zodSchema51 = external_exports.object({
142939
143287
  device_id: metroDeviceIdParam(
142940
143288
  "Target device id from `list-devices` (iOS UDID or Android serial)."
142941
143289
  )
142942
143290
  });
142943
- var capability27 = {
143291
+ var capability28 = {
142944
143292
  apple: { simulator: true },
142945
143293
  android: { emulator: true, device: true, unknown: true }
142946
143294
  };
@@ -142968,7 +143316,7 @@ var nativeProfilerStopTool = {
142968
143316
  completedMsg: ({ result }) => `Saved native profile ${result.traceFile.filename}`,
142969
143317
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop native profiler: ${failureSignal2.error_code}`
142970
143318
  },
142971
- capability: capability27,
143319
+ capability: capability28,
142972
143320
  // Packaging plus the export passes routinely exceed the 30s MCP fetch timeout.
142973
143321
  longRunning: true,
142974
143322
  description: `Stop native profiling and export trace data.
@@ -142978,14 +143326,14 @@ Call native-profiler-start first.
142978
143326
  Use when the user has finished the interaction to profile and you need to export the trace.
142979
143327
  Returns { traceFile, exportedFiles, exportDiagnostics? }; traceFile is the raw trace bundle and exportedFiles the exports, all downloadable artifacts materialized to local paths.
142980
143328
  Fails if no active native-profiler-start session exists for the given device_id.`,
142981
- zodSchema: zodSchema50,
143329
+ zodSchema: zodSchema51,
142982
143330
  services: (params) => ({
142983
143331
  session: nativeProfilerSessionRef(resolveDevice(params.device_id))
142984
143332
  }),
142985
143333
  async execute(services, params, ctx) {
142986
143334
  const api = services.session;
142987
143335
  const device = resolveDevice(params.device_id);
142988
- assertSupported("native-profiler-stop", capability27, device);
143336
+ assertSupported("native-profiler-stop", capability28, device);
142989
143337
  if (api.platform === "ios") {
142990
143338
  await ensureDeps(["xcrun"]);
142991
143339
  const ios = await stopNativeProfilerIos(api);
@@ -143013,12 +143361,12 @@ Fails if no active native-profiler-start session exists for the given device_id.
143013
143361
  // ../tool-server/src/tools/profiler/native-profiler/native-profiler-analyze.ts
143014
143362
  init_zod();
143015
143363
  init_device_info();
143016
- var zodSchema51 = external_exports.object({
143364
+ var zodSchema52 = external_exports.object({
143017
143365
  device_id: metroDeviceIdParam(
143018
143366
  "Target device id from `list-devices` (iOS UDID or Android serial)."
143019
143367
  )
143020
143368
  });
143021
- var capability28 = {
143369
+ var capability29 = {
143022
143370
  apple: { simulator: true },
143023
143371
  android: { emulator: true, device: true, unknown: true }
143024
143372
  };
@@ -143029,7 +143377,7 @@ var nativeProfilerAnalyzeTool = {
143029
143377
  completedMsg: () => "Analyzed native profile",
143030
143378
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to analyze native profile: ${failureSignal2.error_code}`
143031
143379
  },
143032
- capability: capability28,
143380
+ capability: capability29,
143033
143381
  // Parsing a trace from a recording up to RECORDING_CAP_MS long routinely exceeds
143034
143382
  // the 30s MCP fetch timeout, and an aborted call is replayed, not cancelled.
143035
143383
  longRunning: true,
@@ -143042,14 +143390,14 @@ profiler-stack-query for hang stacks, CPU context, leak details) or implement fi
143042
143390
  Call native-profiler-stop first to export the trace data.
143043
143391
  Use when you need to interpret a completed native profiling recording.
143044
143392
  Fails if native-profiler-stop has not been called first to export trace data.`,
143045
- zodSchema: zodSchema51,
143393
+ zodSchema: zodSchema52,
143046
143394
  services: (params) => ({
143047
143395
  session: nativeProfilerSessionRef(resolveDevice(params.device_id))
143048
143396
  }),
143049
143397
  async execute(services, params, ctx) {
143050
143398
  const api = services.session;
143051
143399
  const device = resolveDevice(params.device_id);
143052
- assertSupported("native-profiler-analyze", capability28, device);
143400
+ assertSupported("native-profiler-analyze", capability29, device);
143053
143401
  let result;
143054
143402
  if (api.platform === "ios") {
143055
143403
  await ensureDeps(["xcrun"]);
@@ -144112,7 +144460,7 @@ var DEFAULT_TIME_LIMIT_SECONDS = 180;
144112
144460
  var MAX_TIME_LIMIT_SECONDS = 600;
144113
144461
  var POINTER_TRAIL_LENGTH = 8;
144114
144462
  var POINTER_REQUEST_TIMEOUT_MS = 2e3;
144115
- var zodSchema52 = external_exports.object({
144463
+ var zodSchema53 = external_exports.object({
144116
144464
  udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial)."),
144117
144465
  timeLimitSeconds: external_exports.number().int().min(1).max(MAX_TIME_LIMIT_SECONDS).optional().describe(
144118
144466
  `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 +144472,7 @@ var zodSchema52 = external_exports.object({
144124
144472
  "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
144473
  )
144126
144474
  });
144127
- var capability29 = {
144475
+ var capability30 = {
144128
144476
  apple: { simulator: true },
144129
144477
  android: { emulator: true, device: true, unknown: true }
144130
144478
  };
@@ -144136,7 +144484,7 @@ function createScreenRecordingStartTool(registry2) {
144136
144484
  completedMsg: () => "Started screen recording",
144137
144485
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to start screen recording: ${failureSignal2.error_code}`
144138
144486
  },
144139
- capability: capability29,
144487
+ capability: capability30,
144140
144488
  description: `Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
144141
144489
  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
144490
  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 +144493,7 @@ Use when the user wants a video of an interaction, animation, or app behavior \u
144145
144493
  Returns { status: "recording", timeLimitSeconds, outputFile } \u2014 the video is retrieved later by \`screen-recording-stop\`, not by reading outputFile directly.
144146
144494
  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
144495
  searchHint: "record video screen capture movie mp4 start filming screencast",
144148
- zodSchema: zodSchema52,
144496
+ zodSchema: zodSchema53,
144149
144497
  // Resolved inside execute, not declared eagerly: a tvOS udid classifies as
144150
144498
  // iOS by shape, so an eager service would spawn simulator-server for a
144151
144499
  // device it cannot drive and hang on its ready timeout (as in `screenshot`).
@@ -144155,7 +144503,7 @@ Fails if a recording is already running on the device, the device is not booted,
144155
144503
  async execute(services, params) {
144156
144504
  const api = services.session;
144157
144505
  const device = resolveDevice(params.udid);
144158
- assertSupported("screen-recording-start", capability29, device);
144506
+ assertSupported("screen-recording-start", capability30, device);
144159
144507
  if (device.platform === "ios" && await isTvOsSimulator(params.udid)) {
144160
144508
  throw new FailureError(
144161
144509
  `Screen recording is not supported on tvOS simulators (device ${params.udid}).`,
@@ -144244,11 +144592,11 @@ function makePointerControl(simulator) {
144244
144592
  var import_node_path22 = require("node:path");
144245
144593
  init_zod();
144246
144594
  init_device_info();
144247
- var zodSchema53 = external_exports.object({
144595
+ var zodSchema54 = external_exports.object({
144248
144596
  udid: external_exports.string().describe("Target device id from `list-devices` (iOS Simulator UDID or Android serial).")
144249
144597
  });
144250
144598
  var RECORDINGS_DIR = ".argent/recordings";
144251
- var capability30 = {
144599
+ var capability31 = {
144252
144600
  apple: { simulator: true },
144253
144601
  android: { emulator: true, device: true, unknown: true }
144254
144602
  };
@@ -144259,21 +144607,21 @@ var screenRecordingStopTool = {
144259
144607
  completedMsg: ({ result }) => `Saved screen recording ${result.video.filename}`,
144260
144608
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to stop screen recording: ${failureSignal2.error_code}`
144261
144609
  },
144262
- capability: capability30,
144610
+ capability: capability31,
144263
144611
  description: `Stop the screen recording started by \`screen-recording-start\` and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
144264
144612
  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
144613
  Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
144266
144614
  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
144615
  Fails if no recording (running or finished-but-unretrieved) exists for the given udid.`,
144268
144616
  searchHint: "stop end finish screen recording video capture save retrieve",
144269
- zodSchema: zodSchema53,
144617
+ zodSchema: zodSchema54,
144270
144618
  services: (params) => ({
144271
144619
  session: screenRecordingSessionRef(resolveDevice(params.udid))
144272
144620
  }),
144273
144621
  async execute(services, params, ctx) {
144274
144622
  const api = services.session;
144275
144623
  const device = resolveDevice(params.udid);
144276
- assertSupported("screen-recording-stop", capability30, device);
144624
+ assertSupported("screen-recording-stop", capability31, device);
144277
144625
  const stopped = await stopCapture(api);
144278
144626
  const artifacts = requireArtifacts(ctx);
144279
144627
  const video = await artifacts.register({
@@ -144305,7 +144653,7 @@ var timeWindowSchema = external_exports.object({
144305
144653
  "End of window in ms since profiling started \u2014 the same clock profiler-commit-query prints"
144306
144654
  )
144307
144655
  });
144308
- var zodSchema54 = external_exports.object({
144656
+ var zodSchema55 = external_exports.object({
144309
144657
  port: metroPortField,
144310
144658
  device_id: metroDeviceIdParam(
144311
144659
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -144594,7 +144942,7 @@ Every table states how many samples it covers and how much of that was idle.
144594
144942
  Use when investigating JS CPU hotspots or correlating CPU cost with specific components.
144595
144943
  Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown.
144596
144944
  Fails if no CPU profile is stored \u2014 run react-profiler-stop first.`,
144597
- zodSchema: zodSchema54,
144945
+ zodSchema: zodSchema55,
144598
144946
  // RN-only: reads Hermes-format CPU profiles; Chromium's V8 sample format differs.
144599
144947
  capability: RN_ONLY_TOOL_CAPABILITY,
144600
144948
  services: () => ({}),
@@ -144680,7 +145028,7 @@ var timeRangeSchema = external_exports.object({
144680
145028
  "End of range in ms since profiling started \u2014 the same clock profiler-commit-query prints"
144681
145029
  )
144682
145030
  });
144683
- var zodSchema55 = external_exports.object({
145031
+ var zodSchema56 = external_exports.object({
144684
145032
  port: metroPortField,
144685
145033
  device_id: metroDeviceIdParam(
144686
145034
  "Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."
@@ -144953,7 +145301,7 @@ Modes:
144953
145301
  Use when drilling into specific components or time windows after react-profiler-analyze.
144954
145302
  Returns a markdown table or tree of commit data matching the requested mode.
144955
145303
  Fails if react-profiler-stop has not been called or no commit data is stored.`,
144956
- zodSchema: zodSchema55,
145304
+ zodSchema: zodSchema56,
144957
145305
  // Reads React commit data captured via the React DevTools backend.
144958
145306
  capability: RN_ONLY_TOOL_CAPABILITY,
144959
145307
  services: () => ({}),
@@ -145024,7 +145372,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
145024
145372
  init_zod();
145025
145373
  init_src2();
145026
145374
  init_device_info();
145027
- var zodSchema56 = external_exports.object({
145375
+ var zodSchema57 = external_exports.object({
145028
145376
  device_id: metroDeviceIdParam("iOS Simulator UDID or Android serial."),
145029
145377
  mode: external_exports.enum(["hang_stacks", "function_callers", "thread_breakdown", "leak_stacks"]).describe(
145030
145378
  "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 +145690,7 @@ Modes:
145342
145690
  Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.
145343
145691
  Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode.
145344
145692
  Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.`,
145345
- zodSchema: zodSchema56,
145693
+ zodSchema: zodSchema57,
145346
145694
  // No chromium entry: it has no native trace capture.
145347
145695
  capability: {
145348
145696
  apple: { simulator: true },
@@ -145412,7 +145760,7 @@ function buildPerfettoAnchor(wallClockStartMs) {
145412
145760
  }
145413
145761
 
145414
145762
  // ../tool-server/src/tools/profiler/combined/profiler-combined-report.ts
145415
- var zodSchema57 = external_exports.object({
145763
+ var zodSchema58 = external_exports.object({
145416
145764
  port: metroPortField,
145417
145765
  device_id: metroDeviceIdParam("iOS Simulator/device UDID or Android serial")
145418
145766
  });
@@ -145429,7 +145777,7 @@ Requires both react-profiler-analyze and native-profiler-analyze to have been ca
145429
145777
  Call this tool when both profilers were run in parallel on the same session.
145430
145778
  Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints.
145431
145779
  Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.`,
145432
- zodSchema: zodSchema57,
145780
+ zodSchema: zodSchema58,
145433
145781
  // iOS reads xctrace output; Android re-queries the Perfetto .pftrace via
145434
145782
  // loadAndroidCombinedData. Chromium has no native trace capture.
145435
145783
  capability: {
@@ -145753,7 +146101,7 @@ function assertSafeSessionId(sessionId) {
145753
146101
  );
145754
146102
  }
145755
146103
  }
145756
- var zodSchema58 = external_exports.object({
146104
+ var zodSchema59 = external_exports.object({
145757
146105
  mode: external_exports.enum(["list", "load_react", "load_native"]).describe(
145758
146106
  "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
146107
  ),
@@ -146114,7 +146462,7 @@ Modes:
146114
146462
  For Android .pftrace restores, pass app_process for older sessions that do not have a metadata sidecar.
146115
146463
  Returns a summary of the loaded session or a session list for the list mode.
146116
146464
  Fails if the session_id is not found or required XML files are missing from disk.`,
146117
- zodSchema: zodSchema58,
146465
+ zodSchema: zodSchema59,
146118
146466
  // The Hermes, xctrace and perfetto formats this loads have no Chromium
146119
146467
  // equivalent; the gate fails at the call site, not inside the trace parser.
146120
146468
  capability: RN_ONLY_TOOL_CAPABILITY,
@@ -146243,7 +146591,7 @@ function unnameableSessionUrns(urns) {
146243
146591
  }
146244
146592
 
146245
146593
  // ../tool-server/src/tools/simulator/stop-simulator-server.ts
146246
- var zodSchema59 = external_exports.object({
146594
+ var zodSchema60 = external_exports.object({
146247
146595
  udid: external_exports.string().describe(
146248
146596
  "Target device id (iOS UDID, Android serial, or Chromium id) whose transport session to stop"
146249
146597
  )
@@ -146257,7 +146605,7 @@ function createStopSimulatorServerTool(registry2) {
146257
146605
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop simulator server for ${params.udid}: ${failureSignal2.error_code}`
146258
146606
  },
146259
146607
  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: zodSchema59,
146608
+ zodSchema: zodSchema60,
146261
146609
  services: () => ({}),
146262
146610
  async execute(_services, params) {
146263
146611
  const udid = params.udid;
@@ -146288,7 +146636,7 @@ function createStopSimulatorServerTool(registry2) {
146288
146636
  init_zod();
146289
146637
  init_src2();
146290
146638
  init_external_devices();
146291
- var zodSchema60 = external_exports.object({
146639
+ var zodSchema61 = external_exports.object({
146292
146640
  devices: external_exports.array(external_exports.string()).optional().describe(
146293
146641
  "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
146642
  )
@@ -146327,7 +146675,7 @@ function createStopAllSimulatorServersTool(registry2) {
146327
146675
  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
146676
  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
146677
  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: zodSchema60,
146678
+ zodSchema: zodSchema61,
146331
146679
  services: () => ({}),
146332
146680
  async execute(_services, params, ctx) {
146333
146681
  const devices = params.devices;
@@ -146407,7 +146755,7 @@ function listeningPids(port) {
146407
146755
  if (!output) return [];
146408
146756
  return output.split("\n").map((s) => parseInt(s.trim(), 10)).filter((n) => !Number.isNaN(n));
146409
146757
  }
146410
- var zodSchema61 = external_exports.object({
146758
+ var zodSchema62 = external_exports.object({
146411
146759
  port: external_exports.number().int().min(1).max(65535).default(8081).describe("TCP port Metro is listening on (default 8081)")
146412
146760
  });
146413
146761
  var stopMetroTool = {
@@ -146418,7 +146766,7 @@ var stopMetroTool = {
146418
146766
  failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to stop Metro on port ${params.port}: ${failureSignal2.error_code}`
146419
146767
  },
146420
146768
  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: zodSchema61,
146769
+ zodSchema: zodSchema62,
146422
146770
  services: () => ({}),
146423
146771
  async execute(_services, params) {
146424
146772
  const port = params.port;
@@ -148701,7 +149049,7 @@ async function appendStepToFlow(session, step) {
148701
149049
  }
148702
149050
 
148703
149051
  // ../tool-server/src/tools/flows/flow-start-recording.ts
148704
- var zodSchema62 = external_exports.object({
149052
+ var zodSchema63 = external_exports.object({
148705
149053
  name: external_exports.string().describe(
148706
149054
  'Name for this flow (e.g. "settings-explore") \u2014 letters, digits, underscore and hyphen only.'
148707
149055
  ),
@@ -148758,7 +149106,7 @@ recording. Against a remote client the in-memory copy is authoritative and
148758
149106
  every write serializes it over your edit; in host mode the recorder re-reads
148759
149107
  the file before each append, so a mid-recording edit renumbers the steps and
148760
149108
  costs the finish the cross-tree verdicts anchored to them.`,
148761
- zodSchema: zodSchema62,
149109
+ zodSchema: zodSchema63,
148762
149110
  fileInputs: fileInputs2,
148763
149111
  services: () => ({}),
148764
149112
  async execute(_services, params, ctx) {
@@ -148970,46 +149318,6 @@ function bindDeviceArgs(registry2, toolName, deviceId, args, deviceIsExplicit =
148970
149318
  // ../tool-server/src/tools/flows/flow-ios-tree.ts
148971
149319
  init_src2();
148972
149320
  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
149321
  function clamp013(value) {
149014
149322
  return Math.min(1, Math.max(0, value));
149015
149323
  }
@@ -149449,126 +149757,6 @@ async function queryIosDeviceFlowTree(registry2, device) {
149449
149757
  return { ...data, tree: adaptIosDeviceTreeForFlows(data.tree) };
149450
149758
  }
149451
149759
 
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
149760
  // ../tool-server/src/tools/flows/flow-chromium-tree.ts
149573
149761
  function projectChromiumNode(node) {
149574
149762
  const onScreen = node.frame.width > 0 && node.frame.height > 0;
@@ -151042,7 +151230,7 @@ function stepAnchor(step) {
151042
151230
 
151043
151231
  // ../tool-server/src/tools/flows/flow-add-step.ts
151044
151232
  init_device_info();
151045
- var zodSchema63 = external_exports.object({
151233
+ var zodSchema64 = external_exports.object({
151046
151234
  name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
151047
151235
  project_root: external_exports.string().describe(
151048
151236
  "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 +151662,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
151474
151662
  // more times — and every retry re-runs the action and appends another step,
151475
151663
  // because an aborted request still appends its first.
151476
151664
  longRunning: true,
151477
- zodSchema: zodSchema63,
151665
+ zodSchema: zodSchema64,
151478
151666
  services: () => ({}),
151479
151667
  async execute(_services, params, ctx) {
151480
151668
  const session = await requireRecordingSession(params.project_root, params.name);
@@ -151610,7 +151798,7 @@ Returns { message, stepCount, recorded, savedTo }; \`recorded\`, not the status,
151610
151798
 
151611
151799
  // ../tool-server/src/tools/flows/flow-insert-echo.ts
151612
151800
  init_zod();
151613
- var zodSchema64 = external_exports.object({
151801
+ var zodSchema65 = external_exports.object({
151614
151802
  name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
151615
151803
  project_root: external_exports.string().describe(
151616
151804
  "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 +151816,7 @@ var flowInsertEchoTool = {
151628
151816
  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
151817
  Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.
151630
151818
  Returns { message, stepCount, savedTo }. Fails if that flow has no recording in progress.`,
151631
- zodSchema: zodSchema64,
151819
+ zodSchema: zodSchema65,
151632
151820
  services: () => ({}),
151633
151821
  async execute(_services, params) {
151634
151822
  const session = await requireRecordingSession(params.project_root, params.name);
@@ -152956,7 +153144,7 @@ function errMsg3(err) {
152956
153144
 
152957
153145
  // ../tool-server/src/tools/flows/flow-add-script.ts
152958
153146
  var OUTPUT_RENDER_LIMIT_BYTES = 64 * 1024;
152959
- var zodSchema65 = external_exports.object({
153147
+ var zodSchema66 = external_exports.object({
152960
153148
  name: external_exports.string().describe("Flow name passed to flow-start-recording."),
152961
153149
  project_root: external_exports.string().describe("Absolute project root passed to flow-start-recording."),
152962
153150
  path: external_exports.string().describe(
@@ -153013,7 +153201,7 @@ var flowAddScriptTool = {
153013
153201
  // The flag only skips the adapter's own abort timer; its retry loop is
153014
153202
  // untouched, so a call that fails some other way is still re-POSTed.
153015
153203
  longRunning: true,
153016
- zodSchema: zodSchema65,
153204
+ zodSchema: zodSchema66,
153017
153205
  services: () => ({}),
153018
153206
  async execute(_services, params, ctx) {
153019
153207
  const session = await requireRecordingSession(params.project_root, params.name);
@@ -153103,7 +153291,7 @@ var flowAddScriptTool = {
153103
153291
  // ../tool-server/src/tools/flows/flow-finish-recording.ts
153104
153292
  init_zod();
153105
153293
  var fs59 = __toESM(require("node:fs/promises"));
153106
- var zodSchema66 = external_exports.object({
153294
+ var zodSchema67 = external_exports.object({
153107
153295
  name: external_exports.string().describe("Name of the flow being recorded \u2014 the one passed to flow-start-recording."),
153108
153296
  project_root: external_exports.string().describe(
153109
153297
  "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 +153350,7 @@ var flowFinishRecordingTool = {
153162
153350
  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
153351
  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
153352
  You can still edit the .yaml file directly afterwards to remove or reorder steps.`,
153165
- zodSchema: zodSchema66,
153353
+ zodSchema: zodSchema67,
153166
153354
  services: () => ({}),
153167
153355
  async execute(_services, params) {
153168
153356
  const { filePath, flowFile, savedTo, flow, summary, headline } = await withFlowFileLock(
@@ -155672,7 +155860,7 @@ async function restoreStatusBar(device) {
155672
155860
  }
155673
155861
 
155674
155862
  // ../tool-server/src/tools/flows/flow-run.ts
155675
- var zodSchema67 = external_exports.object({
155863
+ var zodSchema68 = external_exports.object({
155676
155864
  name: external_exports.string().optional().describe(
155677
155865
  'Name of a saved flow to run from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
155678
155866
  ),
@@ -156110,7 +156298,7 @@ one-off interaction use the gesture tools instead, and to author a flow use flow
156110
156298
  exactly one flow source: name (under project_root) or flow_path.
156111
156299
  Returns a per-step report: the first failure stops the run and the rest report as skipped.`,
156112
156300
  longRunning: true,
156113
- zodSchema: zodSchema67,
156301
+ zodSchema: zodSchema68,
156114
156302
  fileInputs: fileInputs3,
156115
156303
  services: () => ({}),
156116
156304
  async execute(_services, params, ctx) {
@@ -156980,7 +157168,7 @@ async function resolveFlowSource(params, fileInput, flowPathInput) {
156980
157168
  // ../tool-server/src/tools/flows/flow-read-prerequisite.ts
156981
157169
  init_zod();
156982
157170
  var fs63 = __toESM(require("node:fs/promises"));
156983
- var zodSchema68 = external_exports.object({
157171
+ var zodSchema69 = external_exports.object({
156984
157172
  name: external_exports.string().optional().describe(
156985
157173
  'Name of a saved flow to inspect from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set.'
156986
157174
  ),
@@ -157036,7 +157224,7 @@ Touches no device: nothing is launched, tapped, dispatched or torn down, and no
157036
157224
  needs booting, so calling this costs nothing but a file read.
157037
157225
  Fails if the flow file does not exist.
157038
157226
  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: zodSchema68,
157227
+ zodSchema: zodSchema69,
157040
157228
  fileInputs: fileInputs4,
157041
157229
  services: () => ({}),
157042
157230
  async execute(_services, params, ctx) {
@@ -157352,7 +157540,7 @@ async function readWorkspaceSnapshot(workspacePath) {
157352
157540
  }
157353
157541
 
157354
157542
  // ../tool-server/src/tools/workspace/gather-workspace-data.ts
157355
- var zodSchema69 = external_exports.object({
157543
+ var zodSchema70 = external_exports.object({
157356
157544
  workspacePath: external_exports.string().describe("Absolute path to the project root directory to inspect (e.g. /Users/dev/MyApp)")
157357
157545
  });
157358
157546
  var fileInputs5 = [
@@ -157383,7 +157571,7 @@ exploration of anything the snapshot surfaces.
157383
157571
  Use when you need to inspect project configuration without manually reading multiple files.
157384
157572
  Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.
157385
157573
  Fails if the workspacePath is not an absolute path or the directory cannot be accessed.`,
157386
- zodSchema: zodSchema69,
157574
+ zodSchema: zodSchema70,
157387
157575
  fileInputs: fileInputs5,
157388
157576
  services: () => ({}),
157389
157577
  async execute(_services, params) {
@@ -157457,7 +157645,7 @@ function targetFlagsFor(target) {
157457
157645
  if (target === "both") return ["--global", "--local"];
157458
157646
  return [`--${target}`];
157459
157647
  }
157460
- var zodSchema70 = external_exports.object({
157648
+ var zodSchema71 = external_exports.object({
157461
157649
  target: external_exports.enum(["auto", "global", "local", "both"]).optional().describe(
157462
157650
  "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
157651
  )
@@ -157471,7 +157659,7 @@ var updateArgentTool = {
157471
157659
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to update Argent: ${failureSignal2.error_code}`
157472
157660
  },
157473
157661
  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: zodSchema70,
157662
+ zodSchema: zodSchema71,
157475
157663
  services: () => ({}),
157476
157664
  async execute(_services, params, _options) {
157477
157665
  const { updateAvailable, updateInstallable, currentVersion, installableVersion } = getUpdateState();
@@ -157556,7 +157744,7 @@ var updateArgentTool = {
157556
157744
 
157557
157745
  // ../tool-server/src/tools/system/dismiss-update.ts
157558
157746
  init_zod();
157559
- var zodSchema71 = external_exports.object({
157747
+ var zodSchema72 = external_exports.object({
157560
157748
  hours: external_exports.number().min(0).describe("Number of hours to suppress the update notification")
157561
157749
  });
157562
157750
  var dismissUpdateTool = {
@@ -157567,7 +157755,7 @@ var dismissUpdateTool = {
157567
157755
  failedMsg: ({ failureSignal: failureSignal2 }) => `Failed to dismiss Argent update: ${failureSignal2.error_code}`
157568
157756
  },
157569
157757
  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: zodSchema71,
157758
+ zodSchema: zodSchema72,
157571
157759
  services: () => ({}),
157572
157760
  async execute(_services, params, _options) {
157573
157761
  const durationMs = params.hours * 60 * 60 * 1e3;
@@ -157586,7 +157774,7 @@ var import_path8 = __toESM(require("path"));
157586
157774
  init_zod();
157587
157775
  init_src2();
157588
157776
  init_device_info();
157589
- var zodSchema72 = external_exports.object({
157777
+ var zodSchema73 = external_exports.object({
157590
157778
  baselinePath: external_exports.string().min(1).optional().describe("Path to the baseline PNG file. Required unless captureBaseline is true."),
157591
157779
  currentPath: external_exports.string().min(1).optional().describe("Path to the current PNG file. Required unless captureCurrent is true."),
157592
157780
  udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
@@ -157603,7 +157791,7 @@ var zodSchema72 = external_exports.object({
157603
157791
  "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
157792
  )
157605
157793
  }).strict();
157606
- var capability31 = {
157794
+ var capability32 = {
157607
157795
  apple: { simulator: true, device: true },
157608
157796
  android: { emulator: true, device: true, unknown: true }
157609
157797
  };
@@ -157628,8 +157816,8 @@ Returns { summary, diffPath, contextDiffPath }. The summary uses normalized [0,1
157628
157816
  Ignores the fixed top status-bar band for both pixel and OCR text comparisons.
157629
157817
  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
157818
  searchHint: "compare screenshots png diff visual UI changes UI regression visual regression screenshot diff changed regions text ocr live capture",
157631
- zodSchema: zodSchema72,
157632
- capability: capability31,
157819
+ zodSchema: zodSchema73,
157820
+ capability: capability32,
157633
157821
  fileInputs: fileInputs6,
157634
157822
  services: (params) => {
157635
157823
  if (params.captureBaseline || params.captureCurrent) {
@@ -157942,7 +158130,7 @@ async function captureElementFrame(registry2, udid, match, opts = {}) {
157942
158130
  }
157943
158131
 
157944
158132
  // ../tool-server/src/tools/variants/propose-variant.ts
157945
- var zodSchema73 = external_exports.object({
158133
+ var zodSchema74 = external_exports.object({
157946
158134
  element: external_exports.string().min(1).max(200).describe(
157947
158135
  '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
158136
  ),
@@ -158002,7 +158190,7 @@ arrives as a follow-up message (this is the case in an \`argent lens\` CLI sessi
158002
158190
  Returns { round, elementId, variantId, element, variantCount, totalElements } \u2014 confirmation only;
158003
158191
  it does not wait for the user.`,
158004
158192
  searchHint: "propose design variant alternative option for element non-blocking ab choice",
158005
- zodSchema: zodSchema73,
158193
+ zodSchema: zodSchema74,
158006
158194
  services: () => ({}),
158007
158195
  async execute(_services, params) {
158008
158196
  let frame = params.variant.frame;
@@ -158026,7 +158214,7 @@ it does not wait for the user.`,
158026
158214
 
158027
158215
  // ../tool-server/src/tools/variants/await-user-selection.ts
158028
158216
  init_zod();
158029
- var zodSchema74 = external_exports.object({
158217
+ var zodSchema75 = external_exports.object({
158030
158218
  timeoutSeconds: external_exports.number().int().min(5).max(86400).optional().describe(
158031
158219
  "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
158220
  )
@@ -158067,7 +158255,7 @@ This tool is long-running; it intentionally holds the request open. It honors cl
158067
158255
  disconnects (aborts cleanly).`,
158068
158256
  searchHint: "await wait user selection choice variant blocking confirm picks complete",
158069
158257
  longRunning: true,
158070
- zodSchema: zodSchema74,
158258
+ zodSchema: zodSchema75,
158071
158259
  services: () => ({}),
158072
158260
  async execute(_services, params, options) {
158073
158261
  const timeoutMs = (params.timeoutSeconds ?? 1800) * 1e3;
@@ -158082,7 +158270,7 @@ disconnects (aborts cleanly).`,
158082
158270
  init_zod();
158083
158271
  init_src2();
158084
158272
  init_device_info();
158085
- var zodSchema75 = external_exports.object({
158273
+ var zodSchema76 = external_exports.object({
158086
158274
  udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
158087
158275
  action: external_exports.enum(["list", "select", "new", "close"]).describe(
158088
158276
  "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 +158303,7 @@ var tabAction = {
158115
158303
  failure: "close"
158116
158304
  }
158117
158305
  };
158118
- var capability32 = {
158306
+ var capability33 = {
158119
158307
  chromium: { app: true }
158120
158308
  };
158121
158309
  var chromiumTabsTool = {
@@ -158133,8 +158321,8 @@ var chromiumTabsTool = {
158133
158321
  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
158322
  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
158323
  searchHint: "tab tabs window windows switch select close new open multi-tab chromium electron",
158136
- zodSchema: zodSchema75,
158137
- capability: capability32,
158324
+ zodSchema: zodSchema76,
158325
+ capability: capability33,
158138
158326
  services: (params) => {
158139
158327
  const device = resolveDevice(params.udid);
158140
158328
  if (device.platform === "chromium") {
@@ -158235,7 +158423,7 @@ async function clearStorage(cdp, type) {
158235
158423
  }
158236
158424
 
158237
158425
  // ../tool-server/src/tools/chromium-cookies/index.ts
158238
- var zodSchema76 = external_exports.object({
158426
+ var zodSchema77 = external_exports.object({
158239
158427
  udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
158240
158428
  action: external_exports.enum(["get", "set", "delete", "clear"]).describe(
158241
158429
  "get: read cookies. set: create/update a cookie. delete: remove a named cookie. clear: remove all browser cookies."
@@ -158258,7 +158446,7 @@ var cookieAction = {
158258
158446
  delete: { started: "Deleting", completed: "Deleted", failure: "delete" },
158259
158447
  clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
158260
158448
  };
158261
- var capability33 = {
158449
+ var capability34 = {
158262
158450
  chromium: { app: true }
158263
158451
  };
158264
158452
  var chromiumCookiesTool = {
@@ -158276,8 +158464,8 @@ var chromiumCookiesTool = {
158276
158464
  Use when seeding an authenticated session before a flow (set the session cookie, then navigate) or asserting cookie state after one.
158277
158465
  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
158466
  searchHint: "cookies cookie get set delete clear httponly samesite session auth chromium",
158279
- zodSchema: zodSchema76,
158280
- capability: capability33,
158467
+ zodSchema: zodSchema77,
158468
+ capability: capability34,
158281
158469
  services: (params) => {
158282
158470
  const device = resolveDevice(params.udid);
158283
158471
  if (device.platform === "chromium") {
@@ -158342,7 +158530,7 @@ Returns { cookies, count } for get, or a small status object ({ set } / { delete
158342
158530
  init_zod();
158343
158531
  init_src2();
158344
158532
  init_device_info();
158345
- var zodSchema77 = external_exports.object({
158533
+ var zodSchema78 = external_exports.object({
158346
158534
  udid: external_exports.string().describe("Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`)."),
158347
158535
  store: external_exports.enum(["local", "session"]).describe("Which Web Storage area: `local` (localStorage) or `session` (sessionStorage)."),
158348
158536
  action: external_exports.enum(["get", "set", "remove", "clear"]).describe(
@@ -158357,7 +158545,7 @@ var storageAction = {
158357
158545
  remove: { started: "Removing from", completed: "Removed from", failure: "remove from" },
158358
158546
  clear: { started: "Clearing", completed: "Cleared", failure: "clear" }
158359
158547
  };
158360
- var capability34 = {
158548
+ var capability35 = {
158361
158549
  chromium: { app: true }
158362
158550
  };
158363
158551
  var chromiumStorageTool = {
@@ -158376,8 +158564,8 @@ Set \`store\` to "local" or "session". Storage is per-origin, so it reflects the
158376
158564
  Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one.
158377
158565
  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
158566
  searchHint: "storage localstorage sessionstorage local session get set remove clear key value chromium",
158379
- zodSchema: zodSchema77,
158380
- capability: capability34,
158567
+ zodSchema: zodSchema78,
158568
+ capability: capability35,
158381
158569
  services: (params) => {
158382
158570
  const device = resolveDevice(params.udid);
158383
158571
  if (device.platform === "chromium") {
@@ -158487,6 +158675,7 @@ function createRegistry() {
158487
158675
  registry2.registerTool(networkLogsTool);
158488
158676
  registry2.registerTool(networkRequestTool);
158489
158677
  registry2.registerTool(createDescribeTool(registry2));
158678
+ registry2.registerTool(createUiTreeTool(registry2));
158490
158679
  registry2.registerTool(createAwaitUiElementTool(registry2));
158491
158680
  registry2.registerTool(createAwaitScreenIdleTool(registry2));
158492
158681
  registry2.registerTool(createReactProfilerStartTool(registry2));