@swmansion/argent 0.20.1-next.2 → 0.20.1-next.4

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.
@@ -112329,6 +112329,7 @@ var nativeDevtoolsBlueprint = {
112329
112329
  );
112330
112330
  }
112331
112331
  const id = nextRpcId++;
112332
+ const timeoutMs = method === "ViewHierarchy.getFullHierarchy" ? 15e3 : 5e3;
112332
112333
  return new Promise((resolve11, reject) => {
112333
112334
  pendingRpc.set(id, { resolve: resolve11, reject });
112334
112335
  conn.socket.write(
@@ -112349,7 +112350,7 @@ var nativeDevtoolsBlueprint = {
112349
112350
  })
112350
112351
  );
112351
112352
  }
112352
- }, 5e3);
112353
+ }, timeoutMs);
112353
112354
  });
112354
112355
  }
112355
112356
  if (transport === "unix") {
@@ -134485,7 +134486,7 @@ function renderCommit(summary, annotations, _sessionContext) {
134485
134486
  const hiddenCount = (summary.totalComponentCount ?? summary.components.length) - summary.components.length;
134486
134487
  if (hiddenCount > 0) {
134487
134488
  lines.push(
134488
- `- _Shown: ${roundedShown}ms self / ${summary.totalRenderMs}ms commit (${coveragePct}%) \u2014 ${hiddenCount} more components not shown. Use \`profiler-commit-query mode=by_index\` to see all._`
134489
+ `- _Shown: ${roundedShown}ms self / ${summary.totalRenderMs}ms commit (${coveragePct}%) \u2014 ${hiddenCount} more components not shown. Use \`profiler-commit-query mode=by_index commit_index=${summary.commitIndex}\` to see all._`
134489
134490
  );
134490
134491
  } else if (coveragePct < 80) {
134491
134492
  lines.push(
@@ -140684,7 +140685,9 @@ var zodSchema54 = external_exports.object({
140684
140685
  component_name: external_exports.string().optional().describe("Component name for by_component mode"),
140685
140686
  time_range_ms: timeRangeSchema.optional().describe("Time range filter for by_time_range mode"),
140686
140687
  commit_index: external_exports.coerce.number().int().optional().describe("Commit index for by_index and cascade_tree modes"),
140687
- top_n: external_exports.coerce.number().int().positive().default(20).describe("Max results to return (default 20)")
140688
+ top_n: external_exports.coerce.number().int().positive().optional().describe(
140689
+ "Max results to return. Defaults to 20 for by_component / by_time_range, which count commits. by_index counts individual fibers and returns all of them unless this is set, because one commit's fibers collapse to far fewer distinct components \u2014 a small cap there can show less than the analyze report it is meant to expand on."
140690
+ )
140688
140691
  });
140689
140692
  async function getCommitTree(port, deviceId) {
140690
140693
  const sessionPaths = getCachedProfilerPaths(port, deviceId);
@@ -140821,23 +140824,25 @@ function renderByTimeRange(commits, start2, end, topN2) {
140821
140824
  }
140822
140825
  return lines.join("\n");
140823
140826
  }
140824
- function renderByIndex(commits, commitIndex) {
140827
+ function renderByIndex(commits, commitIndex, topN2) {
140825
140828
  const matching = commits.filter((c) => c.commitIndex === commitIndex);
140826
140829
  if (matching.length === 0) {
140827
140830
  return `_Commit #${commitIndex} not found in stored data._`;
140828
140831
  }
140829
140832
  const commitDuration = matching[0].commitDuration;
140830
140833
  const timestamp = matching[0].timestamp;
140834
+ const sorted = [...matching].sort((a, b) => b.actualDuration - a.actualDuration);
140835
+ const shown = topN2 !== void 0 ? sorted.slice(0, topN2) : sorted;
140836
+ const hidden = sorted.length - shown.length;
140831
140837
  const lines = [
140832
- `## Commit #${commitIndex} \u2014 Full Detail`,
140838
+ `## Commit #${commitIndex} \u2014 ${hidden > 0 ? "Top Fibers" : "Full Detail"}`,
140833
140839
  "",
140834
- `**Time:** ${timestamp.toFixed(0)}ms **Duration:** ${commitDuration.toFixed(1)}ms **Fibers:** ${matching.length}`,
140840
+ `**Time:** ${timestamp.toFixed(0)}ms **Duration:** ${commitDuration.toFixed(1)}ms **Fibers:** ${matching.length}${hidden > 0 ? ` (showing ${shown.length})` : ""}`,
140835
140841
  "",
140836
140842
  "| Component | Duration (ms) | Self (ms) | Reason | Parent | Compiler |",
140837
140843
  "|---|---|---|---|---|---|"
140838
140844
  ];
140839
- const sorted = [...matching].sort((a, b) => b.actualDuration - a.actualDuration);
140840
- for (const c of sorted) {
140845
+ for (const c of shown) {
140841
140846
  const reason = formatReason2(c);
140842
140847
  const parent = c.parentName ?? "\u2014";
140843
140848
  const compiler = c.isCompilerOptimized ? "\u2713" : "";
@@ -140845,6 +140850,12 @@ function renderByIndex(commits, commitIndex) {
140845
140850
  `| \`${c.componentName}\` | ${c.actualDuration.toFixed(1)} | ${c.selfDuration.toFixed(1)} | ${reason} | \`${parent}\` | ${compiler} |`
140846
140851
  );
140847
140852
  }
140853
+ if (hidden > 0) {
140854
+ lines.push("");
140855
+ lines.push(
140856
+ `_Showing the ${shown.length} costliest of ${sorted.length} fibers \u2014 ${hidden} cheaper fibers hidden. Note these are fibers, not components: the full set covers ${new Set(sorted.map((c) => c.componentName)).size} distinct components and this view covers ${new Set(shown.map((c) => c.componentName)).size}. Omit top_n for everything._`
140857
+ );
140858
+ }
140848
140859
  const withRootCause = matching.find((c) => c.rootCauseParent);
140849
140860
  if (withRootCause?.rootCauseChain && withRootCause.rootCauseChain.length > 0) {
140850
140861
  lines.push("");
@@ -140952,7 +140963,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
140952
140963
  error_kind: "validation"
140953
140964
  });
140954
140965
  }
140955
- return renderByComponent(commitTree.commits, params.component_name, params.top_n);
140966
+ return renderByComponent(commitTree.commits, params.component_name, params.top_n ?? 20);
140956
140967
  }
140957
140968
  case "by_time_range": {
140958
140969
  if (!params.time_range_ms) {
@@ -140967,7 +140978,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
140967
140978
  commitTree.commits,
140968
140979
  params.time_range_ms.start,
140969
140980
  params.time_range_ms.end,
140970
- params.top_n
140981
+ params.top_n ?? 20
140971
140982
  );
140972
140983
  }
140973
140984
  case "by_index": {
@@ -140979,7 +140990,7 @@ Fails if react-profiler-stop has not been called or no commit data is stored.`,
140979
140990
  error_kind: "validation"
140980
140991
  });
140981
140992
  }
140982
- return renderByIndex(commitTree.commits, params.commit_index);
140993
+ return renderByIndex(commitTree.commits, params.commit_index, params.top_n);
140983
140994
  }
140984
140995
  case "cascade_tree": {
140985
140996
  if (params.commit_index == null) {
@@ -144427,6 +144438,9 @@ function bindDeviceArgs(registry2, toolName, deviceId, args, deviceIsExplicit =
144427
144438
  return out;
144428
144439
  }
144429
144440
 
144441
+ // ../tool-server/src/tools/flows/flow-ios-tree.ts
144442
+ init_src();
144443
+
144430
144444
  // ../tool-server/src/tools/flows/flow-tree-flatten.ts
144431
144445
  function intersectClip(rect, clip3) {
144432
144446
  if (!clip3) return rect;
@@ -144603,7 +144617,7 @@ var FULL_HIERARCHY_FIELDS = [
144603
144617
  // request, which just leaves the wait's poll unconfirmed.
144604
144618
  "firstResponder"
144605
144619
  ];
144606
- async function queryFullHierarchyTree(registry2, device) {
144620
+ async function queryFullHierarchyTree(registry2, device, launchedNativeApp) {
144607
144621
  let nativeApi;
144608
144622
  try {
144609
144623
  const ndRef = nativeDevtoolsRef(device);
@@ -144614,7 +144628,17 @@ async function queryFullHierarchyTree(registry2, device) {
144614
144628
  { cause: err }
144615
144629
  );
144616
144630
  }
144617
- const target = await resolveNativeTargetApp(nativeApi, void 0);
144631
+ let target;
144632
+ try {
144633
+ target = await resolveNativeTargetApp(nativeApi, void 0);
144634
+ } catch (err) {
144635
+ const timedOut = getFailureSignal(err)?.error_code === FAILURE_CODES.NATIVE_DEVTOOLS_RPC_TIMEOUT;
144636
+ if (timedOut && launchedNativeApp !== void 0 && nativeApi.listConnectedBundleIds().includes(launchedNativeApp)) {
144637
+ target = { bundleId: launchedNativeApp };
144638
+ } else {
144639
+ throw err;
144640
+ }
144641
+ }
144618
144642
  if (await nativeApi.requiresAppRestart(target.bundleId)) {
144619
144643
  throw new Error(
144620
144644
  `${target.bundleId} was launched before argent's instrumentation loaded \u2014 relaunch it (launch-app, or a flow \`launch\` step) so the full view hierarchy is readable`
@@ -144841,9 +144865,9 @@ async function queryVegaTree(device) {
144841
144865
  }
144842
144866
 
144843
144867
  // ../tool-server/src/tools/flows/flow-tree.ts
144844
- async function fetchFlowTree(registry2, device) {
144868
+ async function fetchFlowTree(registry2, device, launchedNativeApp) {
144845
144869
  if (device.platform === "ios") {
144846
- return queryFullHierarchyTree(registry2, device);
144870
+ return queryFullHierarchyTree(registry2, device, launchedNativeApp);
144847
144871
  }
144848
144872
  if (device.platform === "android") {
144849
144873
  return queryAndroidFullHierarchy(registry2, device);
@@ -145395,7 +145419,7 @@ async function settleTree(env) {
145395
145419
  if (env.signal?.aborted) return void 0;
145396
145420
  let tree;
145397
145421
  try {
145398
- ({ tree } = await fetchFlowTree(env.registry, env.device));
145422
+ ({ tree } = await fetchFlowTree(env.registry, env.device, env.launchedNativeApp));
145399
145423
  } catch (err) {
145400
145424
  lastError = err instanceof Error ? err : new Error(String(err));
145401
145425
  }
@@ -145456,7 +145480,7 @@ async function waitForFocus(env, into, tappedFrame) {
145456
145480
  for (; ; ) {
145457
145481
  if (env.signal?.aborted) return;
145458
145482
  try {
145459
- const { tree, source } = await fetchFlowTree(env.registry, env.device);
145483
+ const { tree, source } = await fetchFlowTree(env.registry, env.device, env.launchedNativeApp);
145460
145484
  if (!FOCUS_REPORTING_SOURCES.has(source)) return;
145461
145485
  const target = flowSelectorToFrame(tree, into) ?? tappedFrame;
145462
145486
  if (collectFocused(tree, []).some((n) => framesOverlap(n.frame, target))) return;
@@ -145658,7 +145682,7 @@ async function runPinch(env, step) {
145658
145682
  }
145659
145683
  async function fetchScreenAspect(env) {
145660
145684
  try {
145661
- const { screen } = await fetchFlowTree(env.registry, env.device);
145685
+ const { screen } = await fetchFlowTree(env.registry, env.device, env.launchedNativeApp);
145662
145686
  return screen && screen.width > 0 && screen.height > 0 ? screen.width / screen.height : void 0;
145663
145687
  } catch {
145664
145688
  return void 0;
@@ -145746,7 +145770,7 @@ async function waitForCondition(env, step, timeoutMs) {
145746
145770
  for (; ; ) {
145747
145771
  if (env.signal?.aborted) return ABORTED_OUTCOME;
145748
145772
  try {
145749
- const data = await fetchFlowTree(env.registry, env.device);
145773
+ const data = await fetchFlowTree(env.registry, env.device, env.launchedNativeApp);
145750
145774
  lastMatches = flowFindAll(data.tree, step.selector);
145751
145775
  fetchError = void 0;
145752
145776
  everMatched ||= lastMatches.length > 0;
@@ -145841,7 +145865,11 @@ async function waitForIdle(env, step) {
145841
145865
  const roundStartedAt = Date.now();
145842
145866
  let answeredReadMs;
145843
145867
  const [read, frame] = await Promise.all([
145844
- settleWithin(fetchFlowTree(env.registry, env.device), roundBudget, env.signal).then((r) => {
145868
+ settleWithin(
145869
+ fetchFlowTree(env.registry, env.device, env.launchedNativeApp),
145870
+ roundBudget,
145871
+ env.signal
145872
+ ).then((r) => {
145845
145873
  answeredReadMs = Date.now() - roundStartedAt;
145846
145874
  return r;
145847
145875
  }),
@@ -148417,8 +148445,15 @@ var fileInputs3 = [
148417
148445
  ];
148418
148446
  var MAX_RUN_DEPTH = 20;
148419
148447
  var POST_LAUNCH_SETTLE_MS = 1500;
148420
- var NATIVE_READY_TIMEOUT_MS = 8e3;
148448
+ var NATIVE_READY_TIMEOUT_MS = 15e3;
148421
148449
  var NATIVE_READY_POLL_MS = 250;
148450
+ var FOREGROUND_CHANGING_TOOLS = /* @__PURE__ */ new Set([
148451
+ "launch-app",
148452
+ "restart-app",
148453
+ "reinstall-app",
148454
+ "open-url",
148455
+ "button"
148456
+ ]);
148422
148457
  async function waitForNativeDevtools(registry2, device, bundleId, signal) {
148423
148458
  let api;
148424
148459
  try {
@@ -148499,6 +148534,7 @@ async function runLaunch(state3, app) {
148499
148534
  const gate = await treeSourceGate(registry2, device, bundleId, signal);
148500
148535
  if (signal?.aborted) return ABORTED_OUTCOME;
148501
148536
  if (gate) return { ok: false, reason: gate };
148537
+ state3.launchedNativeApp = bundleId;
148502
148538
  return { ok: true };
148503
148539
  }
148504
148540
  async function runChromiumLaunch(state3, app) {
@@ -149359,6 +149395,9 @@ async function execLeafStep(state3, step, index, scope) {
149359
149395
  return { ...base, status: "skip", tool: step.name, reason: "run aborted during delay" };
149360
149396
  }
149361
149397
  try {
149398
+ if (FOREGROUND_CHANGING_TOOLS.has(step.name)) {
149399
+ state3.launchedNativeApp = void 0;
149400
+ }
149362
149401
  const result = await invokeSubTool(registry2, ctx, step.name, args);
149363
149402
  if (isUnmetUiWaitResult(step.name, result)) {
149364
149403
  const note = result.note;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.20.1-next.2",
3
+ "version": "0.20.1-next.4",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",