@swmansion/argent 0.22.2-next.1 → 0.22.2-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/bin/darwin/simulator-server +0 -0
  2. package/bin/linux/simulator-server +0 -0
  3. package/bin/linux-arm64/simulator-server +0 -0
  4. package/bin/win32/simulator-server.exe +0 -0
  5. package/dist/cli-cmds.mjs +16 -1
  6. package/dist/installer.mjs +197 -7
  7. package/dist/mcp-server.mjs +92 -23
  8. package/dist/tool-server.cjs +345 -178
  9. package/package.json +1 -1
  10. package/rules/argent.md +7 -7
  11. package/skills/argent-device-interact/SKILL.md +1 -1
  12. package/bin/linux/resources/android/LICENSE.txt +0 -186
  13. package/bin/linux/resources/android/README.md +0 -11
  14. package/bin/linux/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  15. package/bin/linux/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  16. package/bin/linux/resources/android/screen-sharing-agent.jar +0 -0
  17. package/bin/linux/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  18. package/bin/linux-arm64/resources/android/LICENSE.txt +0 -186
  19. package/bin/linux-arm64/resources/android/README.md +0 -11
  20. package/bin/linux-arm64/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  21. package/bin/linux-arm64/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  22. package/bin/linux-arm64/resources/android/screen-sharing-agent.jar +0 -0
  23. package/bin/linux-arm64/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  24. package/bin/win32/resources/android/LICENSE.txt +0 -186
  25. package/bin/win32/resources/android/README.md +0 -11
  26. package/bin/win32/resources/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  27. package/bin/win32/resources/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  28. package/bin/win32/resources/android/screen-sharing-agent.jar +0 -0
  29. package/bin/win32/resources/android/x86_64/libscreen-sharing-agent.so +0 -0
  30. /package/bin/{darwin/resources → resources}/android/LICENSE.txt +0 -0
  31. /package/bin/{darwin/resources → resources}/android/README.md +0 -0
  32. /package/bin/{darwin/resources → resources}/android/arm64-v8a/libscreen-sharing-agent.so +0 -0
  33. /package/bin/{darwin/resources → resources}/android/armeabi-v7a/libscreen-sharing-agent.so +0 -0
  34. /package/bin/{darwin/resources → resources}/android/screen-sharing-agent.jar +0 -0
  35. /package/bin/{darwin/resources → resources}/android/x86_64/libscreen-sharing-agent.so +0 -0
@@ -628,6 +628,9 @@ var init_failure_codes = __esm({
628
628
  SIMULATOR_SERVER_READY_TIMEOUT: "SIMULATOR_SERVER_READY_TIMEOUT",
629
629
  SIMULATOR_SERVER_PROCESS_ERROR: "SIMULATOR_SERVER_PROCESS_ERROR",
630
630
  SIMULATOR_SERVER_TERMINATED: "SIMULATOR_SERVER_TERMINATED",
631
+ SIMULATOR_COMMAND_REJECTED: "SIMULATOR_COMMAND_REJECTED",
632
+ SIMULATOR_COMMAND_ACK_TIMEOUT: "SIMULATOR_COMMAND_ACK_TIMEOUT",
633
+ SIMULATOR_COMMAND_TRANSPORT_FAILED: "SIMULATOR_COMMAND_TRANSPORT_FAILED",
631
634
  AX_QUERY_TIMEOUT: "AX_QUERY_TIMEOUT",
632
635
  AX_DAEMON_READY_TIMEOUT: "AX_DAEMON_READY_TIMEOUT",
633
636
  AX_DAEMON_EXITED_BEFORE_READY: "AX_DAEMON_EXITED_BEFORE_READY",
@@ -76339,15 +76342,28 @@ async function emulatorSupportsFlag(flag, options = {}) {
76339
76342
  const cached3 = emulatorFlagSupportCache.get(cacheKey3);
76340
76343
  if (cached3 !== void 0) return cached3;
76341
76344
  let output;
76345
+ let failure = null;
76342
76346
  try {
76343
76347
  const { stdout, stderr } = await execFileAsync9(emulatorPath, ["-help"], {
76344
76348
  timeout: options.timeoutMs ?? 1e4,
76349
+ // Same hazard runAdb guards against: a SIGTERM-immune child (emulator
76350
+ // wedged in Qt/graphics init) leaves execFile unsettled forever, and
76351
+ // this await has no deadline of its own.
76352
+ killSignal: "SIGKILL",
76345
76353
  maxBuffer: 8 * 1024 * 1024
76346
76354
  });
76347
76355
  output = stdout + stderr;
76348
76356
  } catch (err) {
76349
76357
  const e = err;
76350
- output = (e.stdout ?? "") + (e.stderr ?? "");
76358
+ output = e.killed ? "" : (e.stdout ?? "") + (e.stderr ?? "");
76359
+ failure = err instanceof Error ? err.message : String(err);
76360
+ }
76361
+ if (output === "") {
76362
+ process.stderr.write(
76363
+ `[argent] \`${emulatorPath} -help\` produced no complete listing ` + (failure ? `(${failure})` : "but exited successfully") + `; assuming "${flag}" unsupported for this boot and retrying on the next one
76364
+ `
76365
+ );
76366
+ return false;
76351
76367
  }
76352
76368
  const supported = output.includes(flag);
76353
76369
  emulatorFlagSupportCache.set(cacheKey3, supported);
@@ -76557,7 +76573,10 @@ async function listAvds() {
76557
76573
  const emulatorPath = await resolveAndroidBinary("emulator");
76558
76574
  if (!emulatorPath) return [];
76559
76575
  try {
76560
- const { stdout } = await execFileAsync9(emulatorPath, ["-list-avds"], { timeout: 5e3 });
76576
+ const { stdout } = await execFileAsync9(emulatorPath, ["-list-avds"], {
76577
+ timeout: 5e3,
76578
+ killSignal: "SIGKILL"
76579
+ });
76561
76580
  return stdout.split("\n").map((l) => l.trim()).filter((l) => l && AVD_NAME_PATTERN.test(l)).map((name) => ({ name }));
76562
76581
  } catch {
76563
76582
  return [];
@@ -76575,6 +76594,7 @@ async function checkSnapshotLoadable(avdName, snapshotName = "default_boot", opt
76575
76594
  ];
76576
76595
  const { stdout } = await execFileAsync9(emulatorPath, args, {
76577
76596
  timeout: options.timeoutMs ?? 1e4,
76597
+ killSignal: "SIGKILL",
76578
76598
  maxBuffer: 4 * 1024 * 1024
76579
76599
  });
76580
76600
  const tail = stdout.split("\n").slice(-6).join("\n");
@@ -89978,6 +89998,10 @@ var FLAG_REGISTRY = [
89978
89998
  name: "disable-auto-screenshot",
89979
89999
  description: "Disable the automatic screenshot captured after interaction tools."
89980
90000
  },
90001
+ {
90002
+ name: "disable-auto-describe",
90003
+ description: "Disable the accessibility element tree appended after interaction tools."
90004
+ },
89981
90005
  {
89982
90006
  name: "argent-lens",
89983
90007
  description: "Argent Lens \u2014 the propose_variant / await_user_selection tools and the Electron preview window for staging UI design variants and letting a human pick among them. Off by default while the feature is in development."
@@ -90278,6 +90302,14 @@ var CONFIG_SCHEMA = [
90278
90302
  // drained/reset, not just the file rewritten.
90279
90303
  manageCommand: "argent telemetry"
90280
90304
  },
90305
+ {
90306
+ key: "allowlist.enabled",
90307
+ description: "Whether `argent update` re-applies editor auto-approve allowlist rules. Unset (the default) keeps the current behavior: update refreshes the rules for editors that already have argent configured. Set to `false` to keep update from touching editor allowlists. `false` in either scope wins, so a committed project opt-out holds for every teammate.",
90308
+ scopes: ["project", "global"],
90309
+ parse: asBoolean,
90310
+ merge: "prioritize-restrictive",
90311
+ example: "false"
90312
+ },
90281
90313
  {
90282
90314
  key: "lens.agent",
90283
90315
  description: "Coding-agent id remembered by `argent lens` to skip the picker.",
@@ -93869,7 +93901,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
93869
93901
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
93870
93902
  function readCliVersion() {
93871
93903
  if (true) {
93872
- return "0.22.2-next.1";
93904
+ return "0.22.2-next.11";
93873
93905
  }
93874
93906
  return "0.0.0";
93875
93907
  }
@@ -94237,7 +94269,10 @@ function simulatorServerBinaryPath() {
94237
94269
  }
94238
94270
  return p;
94239
94271
  }
94240
- function simulatorServerBinaryDir() {
94272
+ function simulatorServerRunDir() {
94273
+ if (fs7.existsSync(path8.join(BIN_DIR, "resources", "android"))) {
94274
+ return BIN_DIR;
94275
+ }
94241
94276
  return platformBinDir();
94242
94277
  }
94243
94278
  function requireBinIn(dir, name) {
@@ -95217,7 +95252,7 @@ var import_node_path5 = __toESM(require("node:path"));
95217
95252
  var import_semver2 = __toESM(require_semver2());
95218
95253
 
95219
95254
  // ../tool-server/package.json
95220
- var version2 = "0.22.1";
95255
+ var version2 = "0.23.0";
95221
95256
 
95222
95257
  // ../tool-server/src/utils/update-checker.ts
95223
95258
  var import_update_core = __toESM(require_dist4());
@@ -95381,13 +95416,56 @@ var import_express = __toESM(require_express2());
95381
95416
 
95382
95417
  // ../tool-server/src/blueprints/simulator-server.ts
95383
95418
  var import_node_child_process10 = require("node:child_process");
95384
- var readline2 = __toESM(require("node:readline"));
95419
+ var readline = __toESM(require("node:readline"));
95385
95420
  init_src();
95386
95421
 
95387
95422
  // ../tool-server/src/blueprints/ax-service.ts
95388
95423
  var net = __toESM(require("node:net"));
95389
95424
  var fs13 = __toESM(require("node:fs"));
95390
- var readline = __toESM(require("node:readline"));
95425
+
95426
+ // ../tool-server/src/utils/ndjson-socket.ts
95427
+ var PREVIEW_CHARS = 80;
95428
+ function preview(raw) {
95429
+ const printable = raw.replace(/[\x00-\x1f\x7f\u2028\u2029]/g, "\xB7");
95430
+ return printable.length > PREVIEW_CHARS ? `${printable.slice(0, PREVIEW_CHARS)}\u2026` : printable;
95431
+ }
95432
+ function reportDroppedFrameToStderr(tag3) {
95433
+ return ({ bytes, preview: preview2 }) => {
95434
+ process.stderr.write(`[${tag3}] dropped unparseable frame (${bytes} bytes): ${preview2}
95435
+ `);
95436
+ };
95437
+ }
95438
+ function attachNdjsonReader(socket, handlers) {
95439
+ socket.setEncoding("utf8");
95440
+ let buf = "";
95441
+ const deliver = (raw) => {
95442
+ if (raw.length === 0 || raw === "\r") return;
95443
+ let msg;
95444
+ try {
95445
+ msg = JSON.parse(raw);
95446
+ } catch {
95447
+ handlers.onDropped({ bytes: Buffer.byteLength(raw, "utf8"), preview: preview(raw) });
95448
+ return;
95449
+ }
95450
+ handlers.onMessage(msg);
95451
+ };
95452
+ socket.on("data", (chunk) => {
95453
+ buf += typeof chunk === "string" ? chunk : chunk.toString("utf8");
95454
+ let nl;
95455
+ while ((nl = buf.indexOf("\n")) !== -1) {
95456
+ const raw = buf.slice(0, nl);
95457
+ buf = buf.slice(nl + 1);
95458
+ deliver(raw);
95459
+ }
95460
+ });
95461
+ socket.on("end", () => {
95462
+ const rest = buf;
95463
+ buf = "";
95464
+ if (rest.length > 0) deliver(rest);
95465
+ });
95466
+ }
95467
+
95468
+ // ../tool-server/src/blueprints/ax-service.ts
95391
95469
  init_src();
95392
95470
 
95393
95471
  // ../tool-server/src/utils/ios-host.ts
@@ -95686,9 +95764,8 @@ async function simctlShutdown(udid) {
95686
95764
  await run(["simctl", "shutdown", stripRemotePrefix(udid)]);
95687
95765
  }
95688
95766
  async function simctlBootstatus(udid, opts) {
95689
- const args = ["simctl", "bootstatus"];
95767
+ const args = ["simctl", "bootstatus", stripRemotePrefix(udid)];
95690
95768
  if (opts?.boot) args.push("-b");
95691
- args.push(stripRemotePrefix(udid));
95692
95769
  await run(args, { timeoutMs: 5 * 6e4 });
95693
95770
  }
95694
95771
  async function simctlLaunch(udid, bundleId, args = []) {
@@ -96223,37 +96300,33 @@ var axServiceBlueprint = {
96223
96300
  daemonSocket.destroy();
96224
96301
  }
96225
96302
  daemonSocket = socket;
96226
- const rl = readline.createInterface({ input: socket });
96227
- rl.on("line", (raw) => {
96228
- let msg;
96229
- try {
96230
- msg = JSON.parse(raw);
96231
- } catch {
96232
- return;
96233
- }
96234
- if (typeof msg.id !== "number") return;
96235
- const pending = pendingRpc.get(msg.id);
96236
- if (!pending) return;
96237
- pendingRpc.delete(msg.id);
96238
- clearTimeout(pending.timer);
96239
- if (msg.error !== void 0 && msg.error !== null) {
96240
- pending.reject(
96241
- new FailureError(
96242
- typeof msg.error === "string" ? msg.error : JSON.stringify(msg.error),
96243
- {
96244
- error_code: FAILURE_CODES.AX_QUERY_FAILED,
96245
- failure_stage: "ax_service_query_rpc",
96246
- failure_area: "tool_server",
96247
- error_kind: "unknown"
96248
- }
96249
- )
96250
- );
96251
- } else {
96252
- pending.resolve(msg.result);
96303
+ attachNdjsonReader(socket, {
96304
+ onDropped: reportDroppedFrameToStderr(`ax-service ${udid.slice(0, 8)}`),
96305
+ onMessage: (parsed) => {
96306
+ const msg = parsed;
96307
+ if (typeof msg.id !== "number") return;
96308
+ const pending = pendingRpc.get(msg.id);
96309
+ if (!pending) return;
96310
+ pendingRpc.delete(msg.id);
96311
+ clearTimeout(pending.timer);
96312
+ if (msg.error !== void 0 && msg.error !== null) {
96313
+ pending.reject(
96314
+ new FailureError(
96315
+ typeof msg.error === "string" ? msg.error : JSON.stringify(msg.error),
96316
+ {
96317
+ error_code: FAILURE_CODES.AX_QUERY_FAILED,
96318
+ failure_stage: "ax_service_query_rpc",
96319
+ failure_area: "tool_server",
96320
+ error_kind: "unknown"
96321
+ }
96322
+ )
96323
+ );
96324
+ } else {
96325
+ pending.resolve(msg.result);
96326
+ }
96253
96327
  }
96254
96328
  });
96255
96329
  socket.on("close", () => {
96256
- rl.close();
96257
96330
  if (daemonSocket === socket) {
96258
96331
  daemonSocket = null;
96259
96332
  if (!disposed) {
@@ -106263,33 +106336,127 @@ var DEFAULT_SCREENSHOT_SCALE = 0.25;
106263
106336
  var NO_IMAGE_ERROR = /no image to export/i;
106264
106337
  var FIRST_FRAME_WAIT_MS = 6e3;
106265
106338
  var FIRST_FRAME_POLL_MS = 250;
106339
+ var COMMAND_ACK_TIMEOUT_MS = 5e3;
106266
106340
  var connections = /* @__PURE__ */ new Map();
106267
106341
  var cmdId = 0;
106268
- function getOrCreateWs(api) {
106342
+ function failAllPending(conn, makeError) {
106343
+ const entries = [...conn.pending.values()];
106344
+ conn.pending.clear();
106345
+ for (const entry of entries) entry.settle(makeError(entry.cmd));
106346
+ }
106347
+ function transportError(cmd, apiUrl, detail) {
106348
+ return new FailureError(
106349
+ `simulator-server did not accept the '${cmd}' command: ${detail}. The command was NOT delivered to the device. Check that the simulator is still booted and the simulator-server for ${apiUrl} is running.`,
106350
+ {
106351
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_TRANSPORT_FAILED,
106352
+ failure_stage: "simulator_command_transport",
106353
+ failure_area: "tool_server",
106354
+ error_kind: "network",
106355
+ network_failure: "connection_reset",
106356
+ failure_command: "simulator_server"
106357
+ }
106358
+ );
106359
+ }
106360
+ function getOrCreateConnection(api) {
106269
106361
  const key2 = api.apiUrl;
106270
106362
  const existing = connections.get(key2);
106271
- if (existing && (existing.readyState === wrapper_default.OPEN || existing.readyState === wrapper_default.CONNECTING)) {
106363
+ if (existing && (existing.ws.readyState === wrapper_default.OPEN || existing.ws.readyState === wrapper_default.CONNECTING)) {
106272
106364
  return existing;
106273
106365
  }
106274
106366
  const { host } = new URL(api.apiUrl);
106275
106367
  const ws = new wrapper_default(`ws://${host}/ws`);
106276
- ws.on("error", () => connections.delete(key2));
106277
- ws.on("close", () => connections.delete(key2));
106278
- connections.set(key2, ws);
106279
- return ws;
106368
+ const conn = { ws, pending: /* @__PURE__ */ new Map() };
106369
+ ws.on("message", (data) => {
106370
+ const text = Buffer.isBuffer(data) ? data.toString() : Array.isArray(data) ? Buffer.concat(data).toString() : Buffer.from(data).toString();
106371
+ let ack;
106372
+ try {
106373
+ ack = JSON.parse(text);
106374
+ } catch {
106375
+ return;
106376
+ }
106377
+ if (ack.status !== "ok" && ack.status !== "error") return;
106378
+ if (ack.id != null && !conn.pending.has(ack.id)) return;
106379
+ const id = ack.id ?? conn.pending.keys().next().value;
106380
+ if (id == null) return;
106381
+ const entry = conn.pending.get(id);
106382
+ if (entry == null) return;
106383
+ conn.pending.delete(id);
106384
+ if (ack.status === "ok") {
106385
+ entry.settle();
106386
+ return;
106387
+ }
106388
+ entry.settle(
106389
+ new FailureError(
106390
+ `simulator-server rejected the '${entry.cmd}' command: ${ack.message ?? "unknown error"}. The command was NOT delivered to the device.`,
106391
+ {
106392
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_REJECTED,
106393
+ failure_stage: "simulator_command_rejected",
106394
+ failure_area: "tool_server",
106395
+ error_kind: "unknown",
106396
+ failure_command: "simulator_server"
106397
+ }
106398
+ )
106399
+ );
106400
+ });
106401
+ ws.on("error", (err) => {
106402
+ connections.delete(key2);
106403
+ failAllPending(conn, (cmd) => transportError(cmd, key2, err.message));
106404
+ });
106405
+ ws.on("close", () => {
106406
+ connections.delete(key2);
106407
+ failAllPending(conn, (cmd) => transportError(cmd, key2, "the connection closed"));
106408
+ });
106409
+ connections.set(key2, conn);
106410
+ return conn;
106280
106411
  }
106281
106412
  function sendCommand(api, cmd) {
106282
106413
  if (api.transport) {
106283
106414
  routeViaTransport(api.transport, cmd);
106284
- return;
106285
- }
106286
- const ws = getOrCreateWs(api);
106287
- const payload = JSON.stringify({ id: String(++cmdId), ...cmd });
106288
- if (ws.readyState === wrapper_default.OPEN) {
106289
- ws.send(payload);
106290
- } else {
106291
- ws.once("open", () => ws.send(payload));
106415
+ return Promise.resolve();
106292
106416
  }
106417
+ const conn = getOrCreateConnection(api);
106418
+ const id = String(++cmdId);
106419
+ const cmdName = typeof cmd.cmd === "string" ? cmd.cmd : "unknown";
106420
+ const payload = JSON.stringify({ id, ...cmd });
106421
+ return new Promise((resolve12, reject) => {
106422
+ let done = false;
106423
+ const settle = (err) => {
106424
+ if (done) return;
106425
+ done = true;
106426
+ clearTimeout(timer);
106427
+ conn.pending.delete(id);
106428
+ if (err) reject(err);
106429
+ else resolve12();
106430
+ };
106431
+ const timer = setTimeout(
106432
+ () => settleAndDropConnection(
106433
+ new FailureError(
106434
+ `simulator-server did not acknowledge the '${cmdName}' command within ${COMMAND_ACK_TIMEOUT_MS}ms. The command may not have reached the device \u2014 the simulator may be wedged or the simulator-server unresponsive.`,
106435
+ {
106436
+ error_code: FAILURE_CODES.SIMULATOR_COMMAND_ACK_TIMEOUT,
106437
+ failure_stage: "simulator_command_ack",
106438
+ failure_area: "tool_server",
106439
+ error_kind: "timeout",
106440
+ network_failure: "timeout",
106441
+ failure_command: "simulator_server"
106442
+ }
106443
+ )
106444
+ ),
106445
+ COMMAND_ACK_TIMEOUT_MS
106446
+ );
106447
+ timer.unref?.();
106448
+ const settleAndDropConnection = (err) => {
106449
+ settle(err);
106450
+ connections.delete(api.apiUrl);
106451
+ conn.ws.close();
106452
+ };
106453
+ conn.pending.set(id, { settle, cmd: cmdName });
106454
+ const write = () => conn.ws.send(payload, (err) => {
106455
+ if (err) settle(transportError(cmdName, api.apiUrl, err.message));
106456
+ });
106457
+ if (conn.ws.readyState === wrapper_default.OPEN) write();
106458
+ else conn.ws.once("open", write);
106459
+ });
106293
106460
  }
106294
106461
  function setPointerVisible(api, show, signal) {
106295
106462
  return pointerPost(api, { show }, signal);
@@ -106517,8 +106684,8 @@ function simulatorServerRef(device) {
106517
106684
  }
106518
106685
  var getPaths = () => {
106519
106686
  const BINARY_PATH = simulatorServerBinaryPath();
106520
- const BINARY_DIR = simulatorServerBinaryDir();
106521
- return { BINARY_PATH, BINARY_DIR };
106687
+ const RUN_DIR = simulatorServerRunDir();
106688
+ return { BINARY_PATH, RUN_DIR };
106522
106689
  };
106523
106690
  var READY_TIMEOUT_MS = 3e4;
106524
106691
  async function buildRemoteInstance(device) {
@@ -106562,12 +106729,12 @@ async function spawnSimulatorServerProcess(udid, subcommand) {
106562
106729
  throw new Error(`Refusing to start simulator-server for unsafe device id "${udid}".`);
106563
106730
  }
106564
106731
  const deviceSet = subcommand === "ios" ? await deviceSetForUdid(udid) : null;
106565
- const { BINARY_PATH, BINARY_DIR } = getPaths();
106732
+ const { BINARY_PATH, RUN_DIR } = getPaths();
106566
106733
  return new Promise((resolve12, reject) => {
106567
106734
  const args = [subcommand, "--id", udid];
106568
106735
  if (deviceSet) args.push("--device-set", deviceSet);
106569
106736
  const proc = (0, import_node_child_process10.spawn)(BINARY_PATH, args, {
106570
- cwd: BINARY_DIR,
106737
+ cwd: RUN_DIR,
106571
106738
  stdio: ["pipe", "pipe", "pipe"]
106572
106739
  });
106573
106740
  let apiUrl = null;
@@ -106575,7 +106742,7 @@ async function spawnSimulatorServerProcess(udid, subcommand) {
106575
106742
  let settled = false;
106576
106743
  const STREAM_GRACE_MS = 500;
106577
106744
  let apiReadyTimer = null;
106578
- const rl = readline2.createInterface({ input: proc.stdout });
106745
+ const rl = readline.createInterface({ input: proc.stdout });
106579
106746
  const settle = (fn, cleanup) => {
106580
106747
  if (settled) return;
106581
106748
  settled = true;
@@ -109223,7 +109390,6 @@ var variantProposalStore = new VariantProposalStore();
109223
109390
  // ../tool-server/src/blueprints/native-devtools.ts
109224
109391
  var net2 = __toESM(require("node:net"));
109225
109392
  var fs18 = __toESM(require("node:fs"));
109226
- var readline3 = __toESM(require("node:readline"));
109227
109393
  init_src();
109228
109394
  var NATIVE_DEVTOOLS_NAMESPACE = "NativeDevtools";
109229
109395
  function isInjectableBundleId(bundleId) {
@@ -109490,67 +109656,63 @@ var nativeDevtoolsBlueprint = {
109490
109656
  }
109491
109657
  const server = net2.createServer((socket) => {
109492
109658
  let bundleId = null;
109493
- const rl = readline3.createInterface({ input: socket });
109494
- rl.on("line", (raw) => {
109495
- let msg;
109496
- try {
109497
- msg = JSON.parse(raw);
109498
- } catch {
109499
- return;
109500
- }
109501
- if (bundleId === null) {
109502
- if (msg.type !== "Control") return;
109503
- bundleId = msg.payload.bundleId;
109504
- const existing = connections2.get(bundleId);
109505
- if (existing) {
109506
- existing.socket.destroy();
109507
- }
109508
- connections2.set(bundleId, { socket, networkLog: [] });
109509
- if (activatedBundleIds.has(bundleId)) {
109510
- socket.write(
109511
- JSON.stringify({
109512
- type: "Control",
109513
- payload: { command: "activateNetworkInspection" }
109514
- }) + "\n"
109515
- );
109659
+ attachNdjsonReader(socket, {
109660
+ onDropped: reportDroppedFrameToStderr(`native-devtools ${udid.slice(0, 8)}`),
109661
+ onMessage: (parsed) => {
109662
+ const msg = parsed;
109663
+ if (bundleId === null) {
109664
+ if (msg.type !== "Control") return;
109665
+ bundleId = msg.payload.bundleId;
109666
+ const existing = connections2.get(bundleId);
109667
+ if (existing) {
109668
+ existing.socket.destroy();
109669
+ }
109670
+ connections2.set(bundleId, { socket, networkLog: [] });
109671
+ if (activatedBundleIds.has(bundleId)) {
109672
+ socket.write(
109673
+ JSON.stringify({
109674
+ type: "Control",
109675
+ payload: { command: "activateNetworkInspection" }
109676
+ }) + "\n"
109677
+ );
109678
+ }
109679
+ return;
109516
109680
  }
109517
- return;
109518
- }
109519
- if (msg.type === "CDP") {
109520
- const p = msg.payload;
109521
- if (p.method && p.id === void 0) {
109522
- const conn = connections2.get(bundleId);
109523
- if (conn) {
109524
- if (conn.networkLog.length >= MAX_LOG_ENTRIES) {
109525
- conn.networkLog.shift();
109681
+ if (msg.type === "CDP") {
109682
+ const p = msg.payload;
109683
+ if (p.method && p.id === void 0) {
109684
+ const conn = connections2.get(bundleId);
109685
+ if (conn) {
109686
+ if (conn.networkLog.length >= MAX_LOG_ENTRIES) {
109687
+ conn.networkLog.shift();
109688
+ }
109689
+ conn.networkLog.push({
109690
+ method: p.method,
109691
+ params: p.params,
109692
+ timestamp: Date.now()
109693
+ });
109526
109694
  }
109527
- conn.networkLog.push({
109528
- method: p.method,
109529
- params: p.params,
109530
- timestamp: Date.now()
109531
- });
109532
109695
  }
109533
109696
  }
109534
- }
109535
- if (msg.type === "ViewInspector") {
109536
- const p = msg.payload;
109537
- const pending = pendingRpc.get(p.id);
109538
- if (!pending) return;
109539
- pendingRpc.delete(p.id);
109540
- if (p.error) {
109541
- pending.reject(
109542
- new FailureError(p.error.message, {
109543
- error_code: FAILURE_CODES.NATIVE_DEVTOOLS_RPC_ERROR,
109544
- failure_stage: "native_devtools_rpc_response",
109545
- failure_area: "tool_server",
109546
- error_kind: "subprocess"
109547
- })
109548
- );
109549
- } else pending.resolve(p.result);
109697
+ if (msg.type === "ViewInspector") {
109698
+ const p = msg.payload;
109699
+ const pending = pendingRpc.get(p.id);
109700
+ if (!pending) return;
109701
+ pendingRpc.delete(p.id);
109702
+ if (p.error) {
109703
+ pending.reject(
109704
+ new FailureError(p.error.message, {
109705
+ error_code: FAILURE_CODES.NATIVE_DEVTOOLS_RPC_ERROR,
109706
+ failure_stage: "native_devtools_rpc_response",
109707
+ failure_area: "tool_server",
109708
+ error_kind: "subprocess"
109709
+ })
109710
+ );
109711
+ } else pending.resolve(p.result);
109712
+ }
109550
109713
  }
109551
109714
  });
109552
109715
  socket.on("close", () => {
109553
- rl.close();
109554
109716
  if (bundleId !== null) {
109555
109717
  if (connections2.get(bundleId)?.socket === socket) {
109556
109718
  connections2.delete(bundleId);
@@ -109994,22 +110156,28 @@ async function describeIos(registry2, device, params, options = {}) {
109994
110156
  if (isTvOs) {
109995
110157
  return { tree: emptyTree(), source: "ax-service", hint: TVOS_HINT };
109996
110158
  }
109997
- let tree;
110159
+ let tree = emptyTree();
109998
110160
  let degraded;
109999
110161
  let resolverHint;
110162
+ let readFailureHint;
110163
+ let axApi;
110000
110164
  try {
110001
110165
  const axRef = axServiceRef(device);
110002
- const axApi = await registry2.resolveService(axRef.urn, axRef.options);
110003
- const response = await axApi.describe();
110004
- tree = adaptAXDescribeToDescribeResult(response);
110166
+ axApi = await registry2.resolveService(axRef.urn, axRef.options);
110005
110167
  degraded = axApi.degraded;
110006
110168
  } catch (err) {
110007
- tree = emptyTree();
110008
110169
  resolverHint = tcpArtifactHint(err);
110009
110170
  degraded = resolverHint === void 0;
110010
110171
  }
110172
+ if (axApi) {
110173
+ try {
110174
+ tree = adaptAXDescribeToDescribeResult(await axApi.describe());
110175
+ } catch (err) {
110176
+ readFailureHint = `The accessibility read failed (${errMsg(err)}).`;
110177
+ }
110178
+ }
110011
110179
  const degradedHint = !degraded ? void 0 : tree.children.length === 0 ? DEGRADED_BLIND_HINT : DEGRADED_STANDING_HINT;
110012
- const hint = resolverHint ?? degradedHint;
110180
+ const hint = resolverHint ?? (readFailureHint ? degradedHint ? `${degradedHint}. ${readFailureHint}` : readFailureHint : degradedHint);
110013
110181
  if (tree.children.length > 0) {
110014
110182
  return { tree, source: "ax-service", hint };
110015
110183
  }
@@ -110501,7 +110669,7 @@ function parseUiAutomatorDump(rawOutput, screenW, screenH, options = {}) {
110501
110669
 
110502
110670
  // ../tool-server/src/blueprints/android-devtools.ts
110503
110671
  var import_node_child_process13 = require("node:child_process");
110504
- var readline5 = __toESM(require("node:readline"));
110672
+ var readline2 = __toESM(require("node:readline"));
110505
110673
  init_src();
110506
110674
 
110507
110675
  // ../native-devtools-android/src/index.ts
@@ -110898,7 +111066,6 @@ async function ensureAndroidDevtoolsInstalled(serial) {
110898
111066
 
110899
111067
  // ../tool-server/src/utils/android-devtools-client.ts
110900
111068
  var net3 = __toESM(require("node:net"));
110901
- var readline4 = __toESM(require("node:readline"));
110902
111069
  init_src();
110903
111070
  var DEFAULT_RPC_TIMEOUT_MS = 5e3;
110904
111071
  var LONG_RPC_TIMEOUT_MS = 15e3;
@@ -110932,36 +111099,32 @@ function connectAndroidDevtoolsClient(localPort, onTerminated) {
110932
111099
  onTerminated(error52);
110933
111100
  };
110934
111101
  socket.once("connect", () => {
110935
- const rl = readline4.createInterface({ input: socket });
110936
- rl.on("line", (line) => {
110937
- if (!line.trim()) return;
110938
- let parsed;
110939
- try {
110940
- parsed = JSON.parse(line);
110941
- } catch {
110942
- return;
110943
- }
110944
- if (typeof parsed.id !== "number") return;
110945
- const req = pending.get(parsed.id);
110946
- if (!req) return;
110947
- pending.delete(parsed.id);
110948
- clearTimeout(req.timer);
110949
- if (parsed.error) {
110950
- const message = parsed.error.message ?? "Unknown helper error";
110951
- const type = parsed.error.type ?? "HelperError";
110952
- req.reject(
110953
- new FailureError(`${type}: ${message}`, {
110954
- error_code: FAILURE_CODES.ANDROID_DEVTOOLS_RPC_ERROR,
110955
- failure_stage: "android_devtools_rpc_response",
110956
- failure_area: "tool_server",
110957
- error_kind: "subprocess"
110958
- })
110959
- );
110960
- } else {
110961
- req.resolve(parsed.result);
111102
+ attachNdjsonReader(socket, {
111103
+ onDropped: reportDroppedFrameToStderr("android-devtools"),
111104
+ onMessage: (raw) => {
111105
+ const parsed = raw;
111106
+ if (typeof parsed.id !== "number") return;
111107
+ const req = pending.get(parsed.id);
111108
+ if (!req) return;
111109
+ pending.delete(parsed.id);
111110
+ clearTimeout(req.timer);
111111
+ if (parsed.error) {
111112
+ const message = parsed.error.message ?? "Unknown helper error";
111113
+ const type = parsed.error.type ?? "HelperError";
111114
+ req.reject(
111115
+ new FailureError(`${type}: ${message}`, {
111116
+ error_code: FAILURE_CODES.ANDROID_DEVTOOLS_RPC_ERROR,
111117
+ failure_stage: "android_devtools_rpc_response",
111118
+ failure_area: "tool_server",
111119
+ error_kind: "subprocess"
111120
+ })
111121
+ );
111122
+ } else {
111123
+ req.resolve(parsed.result);
111124
+ }
110962
111125
  }
110963
111126
  });
110964
- rl.on("close", () => cleanup());
111127
+ socket.on("close", () => cleanup());
110965
111128
  resolve12({
110966
111129
  request(method, params = {}) {
110967
111130
  const send = () => {
@@ -111076,7 +111239,7 @@ async function spawnHelper(serial) {
111076
111239
  cleanup?.();
111077
111240
  fn();
111078
111241
  };
111079
- const rl = readline5.createInterface({ input: proc.stdout });
111242
+ const rl = readline2.createInterface({ input: proc.stdout });
111080
111243
  rl.on("line", async (rawLine) => {
111081
111244
  const line = rawLine.trim();
111082
111245
  const portMatch = HELPER_PORT_MARKER.exec(line);
@@ -116837,13 +117000,7 @@ var zodSchema9 = external_exports.object({
116837
117000
  function bootTarget(params) {
116838
117001
  return params.udid ?? params.avdName ?? params.vvdImage ?? params.electronAppPath ?? "device";
116839
117002
  }
116840
- var LAUNCH_HARDENING_ARGS = [
116841
- "-no-boot-anim",
116842
- "-netfast",
116843
- "-crash-report-mode",
116844
- "never",
116845
- "-no-metrics"
116846
- ];
117003
+ var LAUNCH_HARDENING_ARGS = ["-no-boot-anim", "-netfast", "-no-metrics"];
116847
117004
  function launchHardeningArgs(sound) {
116848
117005
  return sound ? [...LAUNCH_HARDENING_ARGS] : ["-noaudio", ...LAUNCH_HARDENING_ARGS];
116849
117006
  }
@@ -117357,7 +117514,7 @@ async function bootAndroidImpl(params) {
117357
117514
  } else {
117358
117515
  const RENDERER_ARGS = ["-gpu", gpuMode, ...extraEmulatorArgs];
117359
117516
  const probe3 = await checkSnapshotLoadable(params.avdName, "default_boot", {
117360
- extraArgs: [...RENDERER_ARGS, ...hardeningArgs]
117517
+ extraArgs: [...RENDERER_ARGS, ...hardeningArgs, ...crashReportArgs]
117361
117518
  });
117362
117519
  if (!probe3.loadable) {
117363
117520
  hotBootFailureReason = `-check-snapshot-loadable: ${probe3.reason ?? "unknown"}`;
@@ -119392,7 +119549,7 @@ Before tapping, determine the correct coordinates by using discovery tools \u201
119392
119549
  const api = services.simulatorServer;
119393
119550
  for (let i = 1; i <= clickCount; i++) {
119394
119551
  if (i > 1) await sleep2(MULTI_TAP_GAP_MS);
119395
- sendCommand(api, {
119552
+ await sendCommand(api, {
119396
119553
  cmd: "touch",
119397
119554
  type: "Down",
119398
119555
  x: params.x,
@@ -119401,7 +119558,7 @@ Before tapping, determine the correct coordinates by using discovery tools \u201
119401
119558
  second_y: null
119402
119559
  });
119403
119560
  await sleep2(TAP_HOLD_MS);
119404
- sendCommand(api, {
119561
+ await sendCommand(api, {
119405
119562
  cmd: "touch",
119406
119563
  type: "Up",
119407
119564
  x: params.x,
@@ -119486,20 +119643,24 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119486
119643
  let lastY = 0;
119487
119644
  for (let i = 0; i <= steps; i++) {
119488
119645
  if (ctx?.signal?.aborted) {
119489
- if (i > 0) {
119490
- sendCommand(api, {
119491
- cmd: "touch",
119492
- type: "Up",
119493
- x: lastX,
119494
- y: lastY,
119495
- second_x: null,
119496
- second_y: null
119497
- });
119498
- }
119499
119646
  const err = new Error(
119500
119647
  `gesture-swipe aborted - cancelled mid-gesture after ${i} of ${steps + 1} frames`
119501
119648
  );
119502
119649
  err.name = "AbortError";
119650
+ if (i > 0) {
119651
+ try {
119652
+ await sendCommand(api, {
119653
+ cmd: "touch",
119654
+ type: "Up",
119655
+ x: lastX,
119656
+ y: lastY,
119657
+ second_x: null,
119658
+ second_y: null
119659
+ });
119660
+ } catch (liftErr) {
119661
+ err.cause = liftErr;
119662
+ }
119663
+ }
119503
119664
  throw err;
119504
119665
  }
119505
119666
  const t = i / steps;
@@ -119508,7 +119669,7 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119508
119669
  const y = params.fromY + (params.toY - params.fromY) * progress;
119509
119670
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
119510
119671
  if (type === "Up") {
119511
- sendCommand(api, {
119672
+ await sendCommand(api, {
119512
119673
  cmd: "touch",
119513
119674
  type: "Move",
119514
119675
  x,
@@ -119517,7 +119678,7 @@ Pass momentum:false for a momentum-free swipe that lands where the finger lifts
119517
119678
  second_y: null
119518
119679
  });
119519
119680
  }
119520
- sendCommand(api, {
119681
+ await sendCommand(api, {
119521
119682
  cmd: "touch",
119522
119683
  type,
119523
119684
  x,
@@ -119760,7 +119921,7 @@ function interpolateEvents(events, steps) {
119760
119921
  return result;
119761
119922
  }
119762
119923
  function sendTouchEvent(api, type, x, y, x2, y2) {
119763
- sendCommand(api, {
119924
+ return sendCommand(api, {
119764
119925
  cmd: "touch",
119765
119926
  type,
119766
119927
  x,
@@ -119831,7 +119992,7 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
119831
119992
  const events = params.interpolate && params.interpolate > 0 ? interpolateEvents(params.events, params.interpolate) : params.events;
119832
119993
  for (const event2 of events) {
119833
119994
  await sleep6(event2.delayMs ?? 16);
119834
- sendCommand(api, {
119995
+ await sendCommand(api, {
119835
119996
  cmd: "touch",
119836
119997
  type: event2.type,
119837
119998
  x: event2.x,
@@ -119914,7 +120075,7 @@ Use when you need to zoom in or out on a map, image, or zoomable view. Returns {
119914
120075
  const y2 = cy + halfDist * sinA;
119915
120076
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
119916
120077
  if (i === 0) timestampMs = Date.now();
119917
- sendTouchEvent(api, type, x1, y1, x2, y2);
120078
+ await sendTouchEvent(api, type, x1, y1, x2, y2);
119918
120079
  if (i < steps) await sleep(16);
119919
120080
  }
119920
120081
  return { pinched: true, timestampMs };
@@ -119992,11 +120153,17 @@ Size the orbit with radius, or with radiusX and radiusY together (the pair overr
119992
120153
  let lastY2 = 0;
119993
120154
  for (let i = 0; i <= steps; i++) {
119994
120155
  if (ctx?.signal?.aborted) {
119995
- if (i > 0) sendTouchEvent(api, "Up", lastX1, lastY1, lastX2, lastY2);
119996
120156
  const err = new Error(
119997
120157
  `gesture-rotate aborted \u2014 cancelled mid-gesture after ${i} of ${steps + 1} frames`
119998
120158
  );
119999
120159
  err.name = "AbortError";
120160
+ if (i > 0) {
120161
+ try {
120162
+ await sendTouchEvent(api, "Up", lastX1, lastY1, lastX2, lastY2);
120163
+ } catch (liftErr) {
120164
+ err.cause = liftErr;
120165
+ }
120166
+ }
120000
120167
  throw err;
120001
120168
  }
120002
120169
  const t = i / steps;
@@ -120008,7 +120175,7 @@ Size the orbit with radius, or with radiusX and radiusY together (the pair overr
120008
120175
  const y2 = params.centerY - radiusY * Math.sin(angleRad);
120009
120176
  const type = i === 0 ? "Down" : i === steps ? "Up" : "Move";
120010
120177
  if (i === 0) timestampMs = Date.now();
120011
- sendTouchEvent(api, type, x1, y1, x2, y2);
120178
+ await sendTouchEvent(api, type, x1, y1, x2, y2);
120012
120179
  lastX1 = x1;
120013
120180
  lastY1 = y1;
120014
120181
  lastX2 = x2;
@@ -120077,13 +120244,13 @@ Fails if the device backend is not reachable \u2014 the simulator-server for iOS
120077
120244
  return { pressed: params.button };
120078
120245
  }
120079
120246
  const api = services.simulatorServer;
120080
- sendCommand(api, {
120247
+ await sendCommand(api, {
120081
120248
  cmd: "button",
120082
120249
  direction: "Down",
120083
120250
  button: params.button
120084
120251
  });
120085
120252
  await sleep7(50);
120086
- sendCommand(api, { cmd: "button", direction: "Up", button: params.button });
120253
+ await sendCommand(api, { cmd: "button", direction: "Up", button: params.button });
120087
120254
  return { pressed: params.button };
120088
120255
  }
120089
120256
  };
@@ -120894,7 +121061,7 @@ Returns { orientation }. Fails if the target device is not booted.`,
120894
121061
  }),
120895
121062
  async execute(services, params) {
120896
121063
  const api = services.simulatorServer;
120897
- sendCommand(api, { cmd: "rotate", direction: params.orientation });
121064
+ await sendCommand(api, { cmd: "rotate", direction: params.orientation });
120898
121065
  return { orientation: params.orientation };
120899
121066
  }
120900
121067
  };