@swmansion/argent 0.7.1 → 0.8.0

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.
@@ -17652,6 +17652,7 @@ var require_path_to_regexp = __commonJS({
17652
17652
  }
17653
17653
  pos = offset + match.length;
17654
17654
  if (match === "*") {
17655
+ backtrack = "";
17655
17656
  extraOffset += 3;
17656
17657
  return "(.*)";
17657
17658
  }
@@ -17672,6 +17673,7 @@ var require_path_to_regexp = __commonJS({
17672
17673
  offset: offset + extraOffset
17673
17674
  });
17674
17675
  var result = "(?:" + format + slash + capture + (star ? "((?:[/" + format + "].+?)?)" : "") + ")" + optional;
17676
+ backtrack = "";
17675
17677
  extraOffset += result.length - match.length;
17676
17678
  return result;
17677
17679
  }
@@ -23413,6 +23415,47 @@ var require_coerce = __commonJS({
23413
23415
  }
23414
23416
  });
23415
23417
 
23418
+ // ../../node_modules/semver/functions/truncate.js
23419
+ var require_truncate = __commonJS({
23420
+ "../../node_modules/semver/functions/truncate.js"(exports2, module2) {
23421
+ "use strict";
23422
+ var parse = require_parse2();
23423
+ var constants = require_constants();
23424
+ var SemVer = require_semver();
23425
+ var truncate = (version2, truncation, options) => {
23426
+ if (!constants.RELEASE_TYPES.includes(truncation)) {
23427
+ return null;
23428
+ }
23429
+ const clonedVersion = cloneInputVersion(version2, options);
23430
+ return clonedVersion && doTruncation(clonedVersion, truncation);
23431
+ };
23432
+ var cloneInputVersion = (version2, options) => {
23433
+ const versionStringToParse = version2 instanceof SemVer ? version2.version : version2;
23434
+ return parse(versionStringToParse, options);
23435
+ };
23436
+ var doTruncation = (version2, truncation) => {
23437
+ if (isPrerelease(truncation)) {
23438
+ return version2.version;
23439
+ }
23440
+ version2.prerelease = [];
23441
+ switch (truncation) {
23442
+ case "major":
23443
+ version2.minor = 0;
23444
+ version2.patch = 0;
23445
+ break;
23446
+ case "minor":
23447
+ version2.patch = 0;
23448
+ break;
23449
+ }
23450
+ return version2.format();
23451
+ };
23452
+ var isPrerelease = (type) => {
23453
+ return type.startsWith("pre");
23454
+ };
23455
+ module2.exports = truncate;
23456
+ }
23457
+ });
23458
+
23416
23459
  // ../../node_modules/semver/internal/lrucache.js
23417
23460
  var require_lrucache = __commonJS({
23418
23461
  "../../node_modules/semver/internal/lrucache.js"(exports2, module2) {
@@ -24447,6 +24490,7 @@ var require_semver2 = __commonJS({
24447
24490
  var lte = require_lte();
24448
24491
  var cmp = require_cmp();
24449
24492
  var coerce2 = require_coerce();
24493
+ var truncate = require_truncate();
24450
24494
  var Comparator = require_comparator();
24451
24495
  var Range = require_range2();
24452
24496
  var satisfies = require_satisfies();
@@ -24485,6 +24529,7 @@ var require_semver2 = __commonJS({
24485
24529
  lte,
24486
24530
  cmp,
24487
24531
  coerce: coerce2,
24532
+ truncate,
24488
24533
  Comparator,
24489
24534
  Range,
24490
24535
  satisfies,
@@ -30631,6 +30676,8 @@ var require_Alias = __commonJS({
30631
30676
  * instance of the `source` anchor before this node.
30632
30677
  */
30633
30678
  resolve(doc, ctx) {
30679
+ if (ctx?.maxAliasCount === 0)
30680
+ throw new ReferenceError("Alias resolution is disabled");
30634
30681
  let nodes;
30635
30682
  if (ctx?.aliasResolveCache) {
30636
30683
  nodes = ctx.aliasResolveCache;
@@ -31703,18 +31750,18 @@ var require_merge = __commonJS({
31703
31750
  };
31704
31751
  var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag2) => tag2.tag === merge.tag && tag2.default);
31705
31752
  function addMergeToJSMap(ctx, map, value) {
31706
- value = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
31707
- if (identity.isSeq(value))
31708
- for (const it of value.items)
31753
+ const source = resolveAliasValue(ctx, value);
31754
+ if (identity.isSeq(source))
31755
+ for (const it of source.items)
31709
31756
  mergeValue(ctx, map, it);
31710
- else if (Array.isArray(value))
31711
- for (const it of value)
31757
+ else if (Array.isArray(source))
31758
+ for (const it of source)
31712
31759
  mergeValue(ctx, map, it);
31713
31760
  else
31714
- mergeValue(ctx, map, value);
31761
+ mergeValue(ctx, map, source);
31715
31762
  }
31716
31763
  function mergeValue(ctx, map, value) {
31717
- const source = ctx && identity.isAlias(value) ? value.resolve(ctx.doc) : value;
31764
+ const source = resolveAliasValue(ctx, value);
31718
31765
  if (!identity.isMap(source))
31719
31766
  throw new Error("Merge sources must be maps or map aliases");
31720
31767
  const srcMap = source.toJSON(null, ctx, Map);
@@ -31735,6 +31782,9 @@ var require_merge = __commonJS({
31735
31782
  }
31736
31783
  return map;
31737
31784
  }
31785
+ function resolveAliasValue(ctx, value) {
31786
+ return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
31787
+ }
31738
31788
  exports2.addMergeToJSMap = addMergeToJSMap;
31739
31789
  exports2.isMergeKey = isMergeKey;
31740
31790
  exports2.merge = merge;
@@ -32372,7 +32422,7 @@ var require_stringifyNumber = __commonJS({
32372
32422
  if (!isFinite(num))
32373
32423
  return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
32374
32424
  let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
32375
- if (!format && minFractionDigits && (!tag2 || tag2 === "tag:yaml.org,2002:float") && /^\d/.test(n)) {
32425
+ if (!format && minFractionDigits && (!tag2 || tag2 === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
32376
32426
  let i = n.indexOf(".");
32377
32427
  if (i < 0) {
32378
32428
  i = n.length;
@@ -34744,7 +34794,7 @@ var require_resolve_flow_scalar = __commonJS({
34744
34794
  while (next === " " || next === " ")
34745
34795
  next = source[++i + 1];
34746
34796
  } else if (next === "x" || next === "u" || next === "U") {
34747
- const length = { x: 2, u: 4, U: 8 }[next];
34797
+ const length = next === "x" ? 2 : next === "u" ? 4 : 8;
34748
34798
  res += parseCharCode(source, i + 1, length, onError);
34749
34799
  i += length;
34750
34800
  } else {
@@ -34819,12 +34869,13 @@ var require_resolve_flow_scalar = __commonJS({
34819
34869
  const cc = source.substr(offset, length);
34820
34870
  const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
34821
34871
  const code = ok ? parseInt(cc, 16) : NaN;
34822
- if (isNaN(code)) {
34872
+ try {
34873
+ return String.fromCodePoint(code);
34874
+ } catch {
34823
34875
  const raw = source.substr(offset - 2, length + 2);
34824
34876
  onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
34825
34877
  return raw;
34826
34878
  }
34827
- return String.fromCodePoint(code);
34828
34879
  }
34829
34880
  exports2.resolveFlowScalar = resolveFlowScalar;
34830
34881
  }
@@ -35174,8 +35225,10 @@ ${cb}` : comment;
35174
35225
  }
35175
35226
  }
35176
35227
  if (afterDoc) {
35177
- Array.prototype.push.apply(doc.errors, this.errors);
35178
- Array.prototype.push.apply(doc.warnings, this.warnings);
35228
+ for (let i = 0; i < this.errors.length; ++i)
35229
+ doc.errors.push(this.errors[i]);
35230
+ for (let i = 0; i < this.warnings.length; ++i)
35231
+ doc.warnings.push(this.warnings[i]);
35179
35232
  } else {
35180
35233
  doc.errors = this.errors;
35181
35234
  doc.warnings = this.warnings;
@@ -35908,7 +35961,7 @@ var require_lexer = __commonJS({
35908
35961
  const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
35909
35962
  this.indentNext = this.indentValue + 1;
35910
35963
  this.indentValue += n;
35911
- return yield* this.parseBlockStart();
35964
+ return "block-start";
35912
35965
  }
35913
35966
  return "doc";
35914
35967
  }
@@ -36207,28 +36260,38 @@ var require_lexer = __commonJS({
36207
36260
  return 0;
36208
36261
  }
36209
36262
  *pushIndicators() {
36210
- switch (this.charAt(0)) {
36211
- case "!":
36212
- return (yield* this.pushTag()) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
36213
- case "&":
36214
- return (yield* this.pushUntil(isNotAnchorChar)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
36215
- case "-":
36216
- // this is an error
36217
- case "?":
36218
- // this is an error outside flow collections
36219
- case ":": {
36220
- const inFlow = this.flowLevel > 0;
36221
- const ch1 = this.charAt(1);
36222
- if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
36223
- if (!inFlow)
36224
- this.indentNext = this.indentValue + 1;
36225
- else if (this.flowKey)
36226
- this.flowKey = false;
36227
- return (yield* this.pushCount(1)) + (yield* this.pushSpaces(true)) + (yield* this.pushIndicators());
36263
+ let n = 0;
36264
+ loop: while (true) {
36265
+ switch (this.charAt(0)) {
36266
+ case "!":
36267
+ n += yield* this.pushTag();
36268
+ n += yield* this.pushSpaces(true);
36269
+ continue loop;
36270
+ case "&":
36271
+ n += yield* this.pushUntil(isNotAnchorChar);
36272
+ n += yield* this.pushSpaces(true);
36273
+ continue loop;
36274
+ case "-":
36275
+ // this is an error
36276
+ case "?":
36277
+ // this is an error outside flow collections
36278
+ case ":": {
36279
+ const inFlow = this.flowLevel > 0;
36280
+ const ch1 = this.charAt(1);
36281
+ if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
36282
+ if (!inFlow)
36283
+ this.indentNext = this.indentValue + 1;
36284
+ else if (this.flowKey)
36285
+ this.flowKey = false;
36286
+ n += yield* this.pushCount(1);
36287
+ n += yield* this.pushSpaces(true);
36288
+ continue loop;
36289
+ }
36228
36290
  }
36229
36291
  }
36292
+ break loop;
36230
36293
  }
36231
- return 0;
36294
+ return n;
36232
36295
  }
36233
36296
  *pushTag() {
36234
36297
  if (this.charAt(1) === "<") {
@@ -36387,6 +36450,13 @@ var require_parser = __commonJS({
36387
36450
  }
36388
36451
  return prev.splice(i, prev.length);
36389
36452
  }
36453
+ function arrayPushArray(target, source) {
36454
+ if (source.length < 1e5)
36455
+ Array.prototype.push.apply(target, source);
36456
+ else
36457
+ for (let i = 0; i < source.length; ++i)
36458
+ target.push(source[i]);
36459
+ }
36390
36460
  function fixFlowSeqItems(fc) {
36391
36461
  if (fc.start.type === "flow-seq-start") {
36392
36462
  for (const it of fc.items) {
@@ -36396,11 +36466,11 @@ var require_parser = __commonJS({
36396
36466
  delete it.key;
36397
36467
  if (isFlowToken(it.value)) {
36398
36468
  if (it.value.end)
36399
- Array.prototype.push.apply(it.value.end, it.sep);
36469
+ arrayPushArray(it.value.end, it.sep);
36400
36470
  else
36401
36471
  it.value.end = it.sep;
36402
36472
  } else
36403
- Array.prototype.push.apply(it.start, it.sep);
36473
+ arrayPushArray(it.start, it.sep);
36404
36474
  delete it.sep;
36405
36475
  }
36406
36476
  }
@@ -36755,7 +36825,7 @@ var require_parser = __commonJS({
36755
36825
  const prev = map.items[map.items.length - 2];
36756
36826
  const end = prev?.value?.end;
36757
36827
  if (Array.isArray(end)) {
36758
- Array.prototype.push.apply(end, it.start);
36828
+ arrayPushArray(end, it.start);
36759
36829
  end.push(this.sourceToken);
36760
36830
  map.items.pop();
36761
36831
  return;
@@ -36943,7 +37013,7 @@ var require_parser = __commonJS({
36943
37013
  const prev = seq.items[seq.items.length - 2];
36944
37014
  const end = prev?.value?.end;
36945
37015
  if (Array.isArray(end)) {
36946
- Array.prototype.push.apply(end, it.start);
37016
+ arrayPushArray(end, it.start);
36947
37017
  end.push(this.sourceToken);
36948
37018
  seq.items.pop();
36949
37019
  return;
@@ -41951,7 +42021,7 @@ var import_node_https = __toESM(require("node:https"));
41951
42021
  var import_semver = __toESM(require_semver2());
41952
42022
 
41953
42023
  // ../tool-server/package.json
41954
- var version = "0.7.1";
42024
+ var version = "0.8.0";
41955
42025
 
41956
42026
  // ../tool-server/src/utils/update-checker.ts
41957
42027
  var PACKAGE_NAME = "@swmansion/argent";
@@ -42111,6 +42181,11 @@ var net = __toESM(require("node:net"));
42111
42181
  var fs2 = __toESM(require("node:fs"));
42112
42182
  var import_node_util3 = require("node:util");
42113
42183
  var import_node_child_process3 = require("node:child_process");
42184
+
42185
+ // ../tool-server/src/utils/simctl-config.ts
42186
+ var SIMCTL_SPAWN_TIMEOUT_MS = 1e4;
42187
+
42188
+ // ../tool-server/src/blueprints/ax-service.ts
42114
42189
  var execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process3.execFile);
42115
42190
  var AX_SERVICE_NAMESPACE = "AXService";
42116
42191
  function axServiceRef(device) {
@@ -42165,17 +42240,21 @@ async function pingDaemon(socketPath) {
42165
42240
  }
42166
42241
  }
42167
42242
  async function ensureAutomationEnabled(udid) {
42168
- await execFileAsync3("xcrun", [
42169
- "simctl",
42170
- "spawn",
42171
- udid,
42172
- "defaults",
42173
- "write",
42174
- "com.apple.Accessibility",
42175
- "AutomationEnabled",
42176
- "-bool",
42177
- "true"
42178
- ]);
42243
+ await execFileAsync3(
42244
+ "xcrun",
42245
+ [
42246
+ "simctl",
42247
+ "spawn",
42248
+ udid,
42249
+ "defaults",
42250
+ "write",
42251
+ "com.apple.Accessibility",
42252
+ "AutomationEnabled",
42253
+ "-bool",
42254
+ "true"
42255
+ ],
42256
+ { timeout: SIMCTL_SPAWN_TIMEOUT_MS }
42257
+ );
42179
42258
  }
42180
42259
  async function killExistingDaemon(socketPath) {
42181
42260
  try {
@@ -42741,6 +42820,10 @@ function sortAndroid(a, b) {
42741
42820
  const bEmu = b.isEmulator ? 0 : 1;
42742
42821
  return aEmu - bEmu;
42743
42822
  }
42823
+ function readinessRank(d) {
42824
+ if (d.platform === "ios") return d.state === "Booted" ? 0 : 1;
42825
+ return d.state === "device" ? 0 : 1;
42826
+ }
42744
42827
  var zodSchema = external_exports.object({});
42745
42828
  var listDevicesTool = {
42746
42829
  id: "list-devices",
@@ -42770,7 +42853,9 @@ Booted/ready devices are listed first. Platforms whose CLI is unavailable are si
42770
42853
  sdkLevel: d.sdkLevel
42771
42854
  }));
42772
42855
  androidTagged.sort(sortAndroid);
42773
- return { devices: [...iosTagged, ...androidTagged], avds };
42856
+ const devices = [...iosTagged, ...androidTagged];
42857
+ devices.sort((a, b) => readinessRank(a) - readinessRank(b));
42858
+ return { devices, avds };
42774
42859
  }
42775
42860
  };
42776
42861
 
@@ -43058,6 +43143,36 @@ var import_node_child_process7 = require("node:child_process");
43058
43143
  var import_node_util6 = require("node:util");
43059
43144
  var execFileAsync6 = (0, import_node_util6.promisify)(import_node_child_process7.execFile);
43060
43145
  var NATIVE_DEVTOOLS_NAMESPACE = "NativeDevtools";
43146
+ var MAX_NATIVE_DEVTOOLS_INIT_ATTEMPTS = 3;
43147
+ function buildInitFailedResult(udid, failure) {
43148
+ return {
43149
+ status: "init_failed",
43150
+ message: `Native devtools failed to initialize for ${udid} after ${failure.attempts} attempts. Last error: ${failure.lastError}. Try shutting down and re-booting the simulator, or restart CoreSimulatorService.`,
43151
+ attempts: failure.attempts
43152
+ };
43153
+ }
43154
+ async function precheckNativeDevtools(api, udid, bundleId) {
43155
+ const existing = api.getInitFailure();
43156
+ if (existing?.givenUp) return buildInitFailedResult(udid, existing);
43157
+ try {
43158
+ await api.ensureEnvReady();
43159
+ } catch {
43160
+ const failure = api.getInitFailure();
43161
+ if (failure) return buildInitFailedResult(udid, failure);
43162
+ return buildInitFailedResult(udid, {
43163
+ attempts: 1,
43164
+ lastError: "ensureEnvReady threw without recording state",
43165
+ givenUp: false
43166
+ });
43167
+ }
43168
+ if (bundleId !== void 0 && await api.requiresAppRestart(bundleId)) {
43169
+ return {
43170
+ status: "restart_required",
43171
+ message: "Native devtools are not injected into the running app. Call restart-app then retry."
43172
+ };
43173
+ }
43174
+ return null;
43175
+ }
43061
43176
  function nativeDevtoolsRef(device) {
43062
43177
  return {
43063
43178
  urn: `${NATIVE_DEVTOOLS_NAMESPACE}:${device.id}`,
@@ -43096,17 +43211,21 @@ async function ensureAccessibilityEnabled(udid) {
43096
43211
  const flags = ["AccessibilityEnabled", "ApplicationAccessibilityEnabled"];
43097
43212
  await Promise.all(
43098
43213
  flags.map(
43099
- (flag) => execFileAsync6("xcrun", [
43100
- "simctl",
43101
- "spawn",
43102
- udid,
43103
- "defaults",
43104
- "write",
43105
- "com.apple.Accessibility",
43106
- flag,
43107
- "-bool",
43108
- "true"
43109
- ])
43214
+ (flag) => execFileAsync6(
43215
+ "xcrun",
43216
+ [
43217
+ "simctl",
43218
+ "spawn",
43219
+ udid,
43220
+ "defaults",
43221
+ "write",
43222
+ "com.apple.Accessibility",
43223
+ flag,
43224
+ "-bool",
43225
+ "true"
43226
+ ],
43227
+ { timeout: SIMCTL_SPAWN_TIMEOUT_MS }
43228
+ )
43110
43229
  )
43111
43230
  );
43112
43231
  }
@@ -43115,30 +43234,22 @@ async function ensureEnv(udid, socketPath) {
43115
43234
  const result = await execFileAsync6(
43116
43235
  "xcrun",
43117
43236
  ["simctl", "spawn", udid, "launchctl", "getenv", "DYLD_INSERT_LIBRARIES"],
43118
- { encoding: "utf8" }
43237
+ { encoding: "utf8", timeout: SIMCTL_SPAWN_TIMEOUT_MS }
43119
43238
  ).catch((e) => ({ stdout: e.stdout ?? "" }));
43120
43239
  const existing = (result.stdout ?? "").trim();
43121
43240
  const updated = buildDyldInsertLibraries(existing, bootstrapPath);
43122
43241
  if (updated !== existing) {
43123
- await execFileAsync6("xcrun", [
43124
- "simctl",
43125
- "spawn",
43126
- udid,
43127
- "launchctl",
43128
- "setenv",
43129
- "DYLD_INSERT_LIBRARIES",
43130
- updated
43131
- ]);
43242
+ await execFileAsync6(
43243
+ "xcrun",
43244
+ ["simctl", "spawn", udid, "launchctl", "setenv", "DYLD_INSERT_LIBRARIES", updated],
43245
+ { timeout: SIMCTL_SPAWN_TIMEOUT_MS }
43246
+ );
43132
43247
  }
43133
- await execFileAsync6("xcrun", [
43134
- "simctl",
43135
- "spawn",
43136
- udid,
43137
- "launchctl",
43138
- "setenv",
43139
- "NATIVE_DEVTOOLS_IOS_CDP_SOCKET",
43140
- socketPath
43141
- ]);
43248
+ await execFileAsync6(
43249
+ "xcrun",
43250
+ ["simctl", "spawn", udid, "launchctl", "setenv", "NATIVE_DEVTOOLS_IOS_CDP_SOCKET", socketPath],
43251
+ { timeout: SIMCTL_SPAWN_TIMEOUT_MS }
43252
+ );
43142
43253
  await ensureAccessibilityEnabled(udid);
43143
43254
  }
43144
43255
  async function listRunningUIKitApplicationBundleIds(udid) {
@@ -43179,11 +43290,33 @@ var nativeDevtoolsBlueprint = {
43179
43290
  const pendingRpc = /* @__PURE__ */ new Map();
43180
43291
  let nextRpcId = 1;
43181
43292
  let envSetup = false;
43293
+ let initFailure = null;
43294
+ let inFlight = null;
43182
43295
  const activatedBundleIds = /* @__PURE__ */ new Set();
43183
43296
  const events = new TypedEventEmitter();
43184
- const ensureEnvReady = async () => {
43185
- await ensureEnv(udid, socketPath);
43186
- envSetup = true;
43297
+ const noteInitFailure = (err) => {
43298
+ const lastError = err instanceof Error ? err.message : String(err);
43299
+ const attempts = (initFailure?.attempts ?? 0) + 1;
43300
+ const givenUp = attempts >= MAX_NATIVE_DEVTOOLS_INIT_ATTEMPTS;
43301
+ initFailure = { attempts, lastError, givenUp };
43302
+ const message = givenUp ? `[native-devtools] giving up on ${udid} after ${attempts} attempts: ${lastError}
43303
+ ` : `[native-devtools] init attempt ${attempts}/${MAX_NATIVE_DEVTOOLS_INIT_ATTEMPTS} failed for ${udid}: ${lastError}
43304
+ `;
43305
+ process.stderr.write(message);
43306
+ };
43307
+ const ensureEnvReady = () => {
43308
+ if (envSetup || initFailure?.givenUp) return Promise.resolve();
43309
+ if (inFlight) return inFlight;
43310
+ inFlight = Promise.resolve().then(() => ensureEnv(udid, socketPath)).then(() => {
43311
+ envSetup = true;
43312
+ initFailure = null;
43313
+ }).catch((err) => {
43314
+ noteInitFailure(err);
43315
+ throw err;
43316
+ }).finally(() => {
43317
+ inFlight = null;
43318
+ });
43319
+ return inFlight;
43187
43320
  };
43188
43321
  const isAppRunning = async (bundleId) => {
43189
43322
  const runningBundleIds = await listRunningUIKitApplicationBundleIds(udid);
@@ -43282,11 +43415,13 @@ var nativeDevtoolsBlueprint = {
43282
43415
  });
43283
43416
  });
43284
43417
  server.listen(socketPath);
43285
- await ensureEnvReady();
43418
+ await ensureEnvReady().catch(() => {
43419
+ });
43286
43420
  const api = {
43287
43421
  isEnvSetup: () => envSetup,
43288
43422
  socketPath,
43289
43423
  ensureEnvReady,
43424
+ getInitFailure: () => initFailure,
43290
43425
  isConnected: (bundleId) => connections2.has(bundleId),
43291
43426
  isAppRunning,
43292
43427
  listConnectedBundleIds: () => [...connections2.keys()],
@@ -43407,7 +43542,8 @@ Fails if the simulator server is not running for the given UDID or the bundleId
43407
43542
  }),
43408
43543
  async execute(services, params) {
43409
43544
  const api = services.nativeDevtools;
43410
- await api.ensureEnvReady();
43545
+ const blocked = await precheckNativeDevtools(api, params.udid);
43546
+ if (blocked) return blocked;
43411
43547
  const appRunning = await api.isAppRunning(params.bundleId);
43412
43548
  const connected = api.isConnected(params.bundleId);
43413
43549
  const envSetup = api.isEnvSetup();
@@ -43443,12 +43579,8 @@ Fails if native devtools are not connected or the app is not running.`,
43443
43579
  }),
43444
43580
  async execute(services, params) {
43445
43581
  const api = services.nativeDevtools;
43446
- if (await api.requiresAppRestart(params.bundleId)) {
43447
- return {
43448
- status: "restart_required",
43449
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43450
- };
43451
- }
43582
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43583
+ if (blocked) return blocked;
43452
43584
  api.activateNetworkInspection(params.bundleId);
43453
43585
  const events = api.getNetworkLog(params.bundleId).slice(-params.limit);
43454
43586
  if (params.clear) api.clearNetworkLog(params.bundleId);
@@ -43486,12 +43618,8 @@ Fails if native devtools are not connected, the app is not running, or status is
43486
43618
  }),
43487
43619
  async execute(services, params) {
43488
43620
  const api = services.nativeDevtools;
43489
- if (await api.requiresAppRestart(params.bundleId)) {
43490
- return {
43491
- status: "restart_required",
43492
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43493
- };
43494
- }
43621
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43622
+ if (blocked) return blocked;
43495
43623
  const rpcParams = {};
43496
43624
  if (params.className !== void 0) rpcParams.className = params.className;
43497
43625
  if (params.identifier !== void 0) rpcParams.identifier = params.identifier;
@@ -43546,12 +43674,8 @@ Fails if native devtools are not connected or the app is not running.`,
43546
43674
  }),
43547
43675
  async execute(services, params) {
43548
43676
  const api = services.nativeDevtools;
43549
- if (await api.requiresAppRestart(params.bundleId)) {
43550
- return {
43551
- status: "restart_required",
43552
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43553
- };
43554
- }
43677
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43678
+ if (blocked) return blocked;
43555
43679
  const rpcParams = {};
43556
43680
  if (params.fields !== void 0) rpcParams.fields = params.fields;
43557
43681
  if (params.skipClasses !== void 0) rpcParams.skipClasses = params.skipClasses;
@@ -43633,12 +43757,8 @@ If status is restart_required: call restart-app then retry.`,
43633
43757
  }),
43634
43758
  async execute(services, params) {
43635
43759
  const api = services.nativeDevtools;
43636
- if (await api.requiresAppRestart(params.bundleId)) {
43637
- return {
43638
- status: "restart_required",
43639
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43640
- };
43641
- }
43760
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43761
+ if (blocked) return blocked;
43642
43762
  const rpcParams = {};
43643
43763
  if (params.skipClasses !== void 0) rpcParams.skipClasses = params.skipClasses;
43644
43764
  if (params.skipClassPrefixes !== void 0)
@@ -43694,12 +43814,8 @@ If status is restart_required: call restart-app then retry.`,
43694
43814
  }),
43695
43815
  async execute(services, params) {
43696
43816
  const api = services.nativeDevtools;
43697
- if (await api.requiresAppRestart(params.bundleId)) {
43698
- return {
43699
- status: "restart_required",
43700
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43701
- };
43702
- }
43817
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43818
+ if (blocked) return blocked;
43703
43819
  const rpcParams = {
43704
43820
  x: params.x,
43705
43821
  y: params.y
@@ -43761,12 +43877,8 @@ If status is restart_required: call restart-app then retry.`,
43761
43877
  }),
43762
43878
  async execute(services, params) {
43763
43879
  const api = services.nativeDevtools;
43764
- if (await api.requiresAppRestart(params.bundleId)) {
43765
- return {
43766
- status: "restart_required",
43767
- message: "Native devtools are not injected into the running app. Call restart-app then retry."
43768
- };
43769
- }
43880
+ const blocked = await precheckNativeDevtools(api, params.udid, params.bundleId);
43881
+ if (blocked) return blocked;
43770
43882
  const rpcParams = {
43771
43883
  x: params.x,
43772
43884
  y: params.y
@@ -45554,7 +45666,11 @@ async function bootIos(udid, registry) {
45554
45666
  });
45555
45667
  await execFileAsync7("xcrun", ["simctl", "bootstatus", udid, "-b"]);
45556
45668
  const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
45557
- await registry.resolveService(ndRef.urn, ndRef.options);
45669
+ const ndApi = await registry.resolveService(ndRef.urn, ndRef.options);
45670
+ const initFailure = ndApi.getInitFailure();
45671
+ if (initFailure?.givenUp) {
45672
+ return buildInitFailedResult(udid, initFailure);
45673
+ }
45558
45674
  await execFileAsync7("defaults", [
45559
45675
  "write",
45560
45676
  "com.apple.iphonesimulator",
@@ -45882,7 +45998,8 @@ var execFileAsync8 = (0, import_node_util8.promisify)(import_node_child_process9
45882
45998
  var iosImpl = {
45883
45999
  requires: ["xcrun"],
45884
46000
  handler: async (services, params) => {
45885
- await services.nativeDevtools.ensureEnvReady();
46001
+ const blocked = await precheckNativeDevtools(services.nativeDevtools, params.udid);
46002
+ if (blocked) return blocked;
45886
46003
  await execFileAsync8("xcrun", ["simctl", "launch", params.udid, params.bundleId]);
45887
46004
  return { launched: true, bundleId: params.bundleId };
45888
46005
  }
@@ -45982,7 +46099,8 @@ var iosImpl2 = {
45982
46099
  requires: ["xcrun"],
45983
46100
  handler: async (services, params) => {
45984
46101
  const { udid, bundleId } = params;
45985
- await services.nativeDevtools.ensureEnvReady();
46102
+ const blocked = await precheckNativeDevtools(services.nativeDevtools, udid);
46103
+ if (blocked) return blocked;
45986
46104
  try {
45987
46105
  await execFileAsync9("xcrun", ["simctl", "terminate", udid, bundleId]);
45988
46106
  } catch {
@@ -47652,7 +47770,7 @@ function buildTextTree(data, opts) {
47652
47770
  lines.push(`Screen: ${screenW}x${screenH}`);
47653
47771
  lines.push("");
47654
47772
  }
47655
- function formatLabel(c) {
47773
+ function formatLabel2(c) {
47656
47774
  let label = c.name;
47657
47775
  const displayText = c.text ?? c.accLabel;
47658
47776
  if (displayText) label += ` "${displayText}"`;
@@ -47674,12 +47792,12 @@ function buildTextTree(data, opts) {
47674
47792
  cur = childrenOf.get(cur)[0];
47675
47793
  }
47676
47794
  const indent = " ".repeat(depth);
47677
- lines.push(`${indent}${formatLabel(c)}`);
47795
+ lines.push(`${indent}${formatLabel2(c)}`);
47678
47796
  lines.push(`${indent} ... via ${chainLen} wrapper${chainLen > 1 ? "s" : ""}`);
47679
47797
  renderNode(cur, depth + 1);
47680
47798
  return;
47681
47799
  }
47682
- lines.push(" ".repeat(depth) + formatLabel(c));
47800
+ lines.push(" ".repeat(depth) + formatLabel2(c));
47683
47801
  const children = childrenOf.get(id);
47684
47802
  if (children) {
47685
47803
  let prevSibling = null;
@@ -48301,7 +48419,7 @@ function formatEntry(entry) {
48301
48419
  }
48302
48420
  var zodSchema31 = external_exports.object({
48303
48421
  port: external_exports.coerce.number().default(8081).describe("Metro server port"),
48304
- device_id: external_exports.string().describe("iOS Simulator UDID (logicalDeviceId)."),
48422
+ device_id: external_exports.string().describe("Device UDID (logicalDeviceId)."),
48305
48423
  pageIndex: external_exports.union([external_exports.coerce.number().int().nonnegative(), external_exports.literal("latest")]).default("latest").describe(
48306
48424
  'Page index (0-based) or "latest" for the most recent page. Each page contains up to 50 entries.'
48307
48425
  )
@@ -48375,7 +48493,7 @@ function redactHeaders(headers) {
48375
48493
  var MAX_BODY_SIZE = 1e3;
48376
48494
  var zodSchema32 = external_exports.object({
48377
48495
  port: external_exports.coerce.number().default(8081).describe("Metro server port"),
48378
- device_id: external_exports.string().describe("iOS Simulator UDID (logicalDeviceId)."),
48496
+ device_id: external_exports.string().describe("Device UDID (logicalDeviceId)."),
48379
48497
  requestId: external_exports.string().describe("The requestId from view-network-logs to get full details for"),
48380
48498
  includeBody: external_exports.coerce.boolean().default(true).describe("Whether to include the response body (if captured). Defaults to true.")
48381
48499
  });
@@ -49082,7 +49200,116 @@ async function describeIos(registry, device, params) {
49082
49200
  }
49083
49201
  }
49084
49202
 
49203
+ // ../tool-server/src/tools/describe/format-tree.ts
49204
+ var CONTENT_ROLES = /* @__PURE__ */ new Set([
49205
+ // iOS AX traits surfaced by mapNativeTraitsToDescribeRole. AXGroup is
49206
+ // deliberately excluded: it's the catch-all wrapper, so requiring it to
49207
+ // carry its own label/value before we emit a line keeps decorative
49208
+ // groupings out of the output.
49209
+ "AXButton",
49210
+ "AXStaticText",
49211
+ "AXImage",
49212
+ "AXLink",
49213
+ "AXTextField",
49214
+ "AXHeading",
49215
+ "AXTabBar",
49216
+ "AXAdjustable"
49217
+ ]);
49218
+ function clampFinite(n) {
49219
+ return Number.isFinite(n) ? n : 0;
49220
+ }
49221
+ function fmtFrame(f) {
49222
+ return `(${clampFinite(f.x).toFixed(3)}, ${clampFinite(f.y).toFixed(3)}, ${clampFinite(
49223
+ f.width
49224
+ ).toFixed(3)}, ${clampFinite(f.height).toFixed(3)})`;
49225
+ }
49226
+ function escapeForLine(s) {
49227
+ return s.replace(/\\/g, "\\\\").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
49228
+ }
49229
+ function formatLabel(label) {
49230
+ if (!label) return "";
49231
+ return `"${escapeForLine(label)}"`;
49232
+ }
49233
+ function formatAttr(name, value) {
49234
+ if (!value) return "";
49235
+ return ` ${name}="${escapeForLine(value)}"`;
49236
+ }
49237
+ function formatFlags(n) {
49238
+ const flags = [];
49239
+ if (n.clickable) flags.push("clickable");
49240
+ if (n.longClickable) flags.push("long-clickable");
49241
+ if (n.scrollable) flags.push("scrollable");
49242
+ if (n.checkable) flags.push(n.checked ? "checked" : "checkable");
49243
+ if (n.disabled) flags.push("disabled");
49244
+ if (n.password) flags.push("password");
49245
+ if (typeof n.scrollHidden === "number" && n.scrollHidden > 0) {
49246
+ flags.push(`scrollHidden=${n.scrollHidden}`);
49247
+ }
49248
+ return flags.length === 0 ? "" : ` [${flags.join(",")}]`;
49249
+ }
49250
+ function hasContent(n) {
49251
+ return Boolean(
49252
+ n.label || n.value || n.identifier || n.clickable || n.longClickable || n.scrollable || n.checkable || typeof n.scrollHidden === "number" && n.scrollHidden > 0
49253
+ );
49254
+ }
49255
+ function shouldEmit(n) {
49256
+ return hasContent(n) || CONTENT_ROLES.has(n.role);
49257
+ }
49258
+ function formatLine(n, indent) {
49259
+ const pad = " ".repeat(indent);
49260
+ const dedupedValue = n.value && n.value !== n.label ? n.value : void 0;
49261
+ const labelPart = formatLabel(n.label);
49262
+ const valuePart = formatAttr("value", dedupedValue);
49263
+ const idPart = formatAttr("id", n.identifier);
49264
+ const flagPart = formatFlags(n);
49265
+ const annotations = `${labelPart}${valuePart}${idPart}${flagPart}`.trim();
49266
+ const annotated = annotations ? ` ${annotations}` : "";
49267
+ return `${pad}${n.role}${annotated} ${fmtFrame(n.frame)}`;
49268
+ }
49269
+ function renderFlat(root) {
49270
+ return root.children.filter(shouldEmit).slice().sort((a, b) => a.frame.y - b.frame.y || a.frame.x - b.frame.x).map((n) => formatLine(n, 1));
49271
+ }
49272
+ function renderNested(root) {
49273
+ const lines = [];
49274
+ const stack = [];
49275
+ for (let i = root.children.length - 1; i >= 0; i--) {
49276
+ stack.push({ node: root.children[i], depth: 1 });
49277
+ }
49278
+ while (stack.length > 0) {
49279
+ const { node, depth } = stack.pop();
49280
+ if (shouldEmit(node) || node.children.length > 0) {
49281
+ lines.push(formatLine(node, depth));
49282
+ }
49283
+ for (let i = node.children.length - 1; i >= 0; i--) {
49284
+ stack.push({ node: node.children[i], depth: depth + 1 });
49285
+ }
49286
+ }
49287
+ return lines;
49288
+ }
49289
+ function formatDescribeTree(root, opts) {
49290
+ const mode = opts.source === "uiautomator" ? "nested" : "flat";
49291
+ const header = [];
49292
+ header.push(`Source: ${opts.source}`);
49293
+ header.push(`Mode: ${mode}`);
49294
+ header.push(
49295
+ "Coordinates are normalized [0,1] fractions of the screen (x, y, width, height), not pixels \u2014 pass them straight to gesture-tap / gesture-swipe / gesture-pinch, which expect this same space. To tap an element, use its centre: tap_x = frame.x + frame.width / 2, tap_y = frame.y + frame.height / 2."
49296
+ );
49297
+ header.push("");
49298
+ header.push(`ROOT ${root.role} ${fmtFrame(root.frame)}`);
49299
+ header.push("");
49300
+ const body = mode === "flat" ? renderFlat(root) : renderNested(root);
49301
+ return [...header, ...body].join("\n").replace(/\n+$/, "\n");
49302
+ }
49303
+
49085
49304
  // ../tool-server/src/tools/describe/index.ts
49305
+ function withDescription(data) {
49306
+ const out = {
49307
+ description: formatDescribeTree(data.tree, { source: data.source }),
49308
+ source: data.source
49309
+ };
49310
+ if (data.should_restart) out.should_restart = data.should_restart;
49311
+ return out;
49312
+ }
49086
49313
  var zodSchema33 = external_exports.object({
49087
49314
  udid: external_exports.string().min(1).describe("Target device id from `list-devices` (iOS UDID or Android serial)."),
49088
49315
  bundleId: external_exports.string().optional().describe(
@@ -49103,11 +49330,14 @@ system dialogs, permission prompts, and any foreground app content. On Android,
49103
49330
  When a system dialog is visible, describe returns the dialog's interactive elements (buttons, text)
49104
49331
  with tap coordinates. When no dialog is present, it returns the foreground app's accessible elements.
49105
49332
 
49106
- Returns a JSON tree of UI elements with roles, labels, values, and frame coordinates in normalized
49107
- [0,1] space (fractions of the screen, not pixels) \u2014 the same coordinate space as tap/swipe/gesture
49108
- and simulator-server touch input.
49333
+ Returns \`{ description, source }\` where \`description\` is a text rendering of the UI tree \u2014 one
49334
+ line per element with its role, label/value/id, interactivity flags, and frame. Frame coordinates
49335
+ are normalized [0,1] fractions of the screen width/height (not pixels) \u2014 the same space as
49336
+ gesture-tap / gesture-swipe / gesture-pinch.
49109
49337
 
49110
- Use frame.x + frame.width/2 as the tap X coordinate, frame.y + frame.height/2 as tap Y.
49338
+ To tap an element use the centre of its frame: \`tap_x = frame.x + frame.width / 2\`,
49339
+ \`tap_y = frame.y + frame.height / 2\`. The same formula appears in the response header so it
49340
+ can be applied to a line in isolation.
49111
49341
 
49112
49342
  For app-scoped inspection with full UIKit properties (accessibilityIdentifier, viewClassName),
49113
49343
  use native-describe-screen with an explicit bundleId instead (iOS only).
@@ -49122,11 +49352,11 @@ For React Native apps, debugger-component-tree returns React component names wit
49122
49352
  capability: capability16,
49123
49353
  ios: {
49124
49354
  requires: iosRequires,
49125
- handler: (_services, params, device) => describeIos(registry, device, params)
49355
+ handler: async (_services, params, device) => withDescription(await describeIos(registry, device, params))
49126
49356
  },
49127
49357
  android: {
49128
49358
  requires: androidRequires,
49129
- handler: (_services, params) => describeAndroid(params.udid, params.bundleId)
49359
+ handler: async (_services, params) => withDescription(await describeAndroid(params.udid, params.bundleId))
49130
49360
  }
49131
49361
  })
49132
49362
  };
@@ -54757,13 +54987,13 @@ var zodSchema52 = external_exports.object({
54757
54987
  "Absolute path to the project root directory (the directory that contains or should contain `.argent/flows/`). The flow file is created at `<project_root>/.argent/flows/<name>.yaml`."
54758
54988
  ),
54759
54989
  executionPrerequisite: external_exports.string().describe(
54760
- 'Describes the required app/simulator state before running this flow (e.g. "App on home screen after a fresh reload", "Settings app open on General page")'
54990
+ 'Describes the required app/device state before running this flow (e.g. "App on home screen after a fresh reload", "Settings app open on General page")'
54761
54991
  )
54762
54992
  });
54763
54993
  var flowStartRecordingTool = {
54764
54994
  id: "flow-start-recording",
54765
54995
  description: `Start recording a new flow. Creates a .yaml file in the .argent/flows/ directory.
54766
- Use when you want to capture a reusable sequence of simulator interactions for later replay.
54996
+ Use when you want to capture a reusable sequence of device interactions for later replay.
54767
54997
  Returns { message, flowFile } and optionally { previousFlow } if a prior recording was abandoned.
54768
54998
  Fails if the .argent/flows/ directory cannot be created or the flow file cannot be written.
54769
54999
 
@@ -54911,7 +55141,7 @@ function createRunFlowTool(registry) {
54911
55141
  Each step is executed in order: tool calls are dispatched through the registry,
54912
55142
  echo steps print a message. A tool step may carry \`delayMs: <ms>\` to sleep
54913
55143
  that long before the step runs. Returns the result of every step, including images.
54914
- Use when you want to replay a recorded flow or run a scripted sequence of simulator actions.
55144
+ Use when you want to replay a recorded flow or run a scripted sequence of device actions.
54915
55145
  Fails if the flow file does not exist or a step tool raises an error (execution stops at that step).
54916
55146
 
54917
55147
  If the flow has an execution prerequisite and prerequisiteAcknowledged is not
@@ -55470,40 +55700,41 @@ async function getBootedUdids() {
55470
55700
  }
55471
55701
  return udids;
55472
55702
  }
55473
- async function initSimulator(registry, watchedUdids, udid) {
55474
- watchedUdids.add(udid);
55703
+ async function initUdid(registry, udid, trackedServices) {
55704
+ const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
55475
55705
  try {
55476
- const ndRef = nativeDevtoolsRef({ id: udid, platform: "ios", kind: "simulator" });
55477
- await registry.resolveService(ndRef.urn, ndRef.options);
55478
- } catch (err) {
55479
- watchedUdids.delete(udid);
55480
- process.stderr.write(
55481
- `[simulator-watcher] initSimulator failed for ${udid}: ${err instanceof Error ? err.message : err}
55482
- `
55483
- );
55706
+ const service = await registry.resolveService(ndRef.urn, ndRef.options);
55707
+ trackedServices.set(udid, service);
55708
+ } catch {
55484
55709
  }
55485
55710
  }
55486
55711
  function startSimulatorWatcher(registry) {
55487
- const watchedUdids = /* @__PURE__ */ new Set();
55488
- async function poll(awaitInit) {
55712
+ const trackedServices = /* @__PURE__ */ new Map();
55713
+ async function poll(shouldBlockUntilSettled) {
55489
55714
  let booted;
55490
55715
  try {
55491
55716
  booted = await getBootedUdids();
55492
55717
  } catch {
55493
55718
  return;
55494
55719
  }
55495
- const newUdids = [...booted].filter((udid) => !watchedUdids.has(udid));
55496
- if (awaitInit) {
55497
- await Promise.all(newUdids.map((udid) => initSimulator(registry, watchedUdids, udid)));
55498
- } else {
55499
- newUdids.forEach((udid) => {
55500
- initSimulator(registry, watchedUdids, udid).catch(() => {
55501
- });
55502
- });
55720
+ const newUdids = [...booted].filter((udid) => !trackedServices.has(udid));
55721
+ const pendingAttempts = newUdids.map(
55722
+ (udid) => initUdid(registry, udid, trackedServices)
55723
+ );
55724
+ for (const [udid, service] of trackedServices) {
55725
+ if (!booted.has(udid)) continue;
55726
+ const failure = service.getInitFailure();
55727
+ if (failure && !failure.givenUp) {
55728
+ pendingAttempts.push(service.ensureEnvReady().catch(() => {
55729
+ }));
55730
+ }
55503
55731
  }
55504
- for (const udid of watchedUdids) {
55732
+ if (shouldBlockUntilSettled) await Promise.all(pendingAttempts);
55733
+ else pendingAttempts.forEach((p) => p.catch(() => {
55734
+ }));
55735
+ for (const udid of [...trackedServices.keys()]) {
55505
55736
  if (!booted.has(udid)) {
55506
- watchedUdids.delete(udid);
55737
+ trackedServices.delete(udid);
55507
55738
  registry.disposeService(`${NATIVE_DEVTOOLS_NAMESPACE}:${udid}`).catch(() => {
55508
55739
  });
55509
55740
  }