@exodus/xqa 3.0.0 → 3.0.1

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 (2) hide show
  1. package/dist/xqa.cjs +516 -426
  2. package/package.json +3 -3
package/dist/xqa.cjs CHANGED
@@ -3733,7 +3733,7 @@ var require_index_cjs = __commonJS({
3733
3733
  }
3734
3734
  var fromPromise = ResultAsync20.fromPromise;
3735
3735
  var fromSafePromise2 = ResultAsync20.fromSafePromise;
3736
- var fromAsyncThrowable9 = ResultAsync20.fromThrowable;
3736
+ var fromAsyncThrowable8 = ResultAsync20.fromThrowable;
3737
3737
  var combineResultList = (resultList) => {
3738
3738
  let acc = ok36([]);
3739
3739
  for (const result of resultList) {
@@ -3950,7 +3950,7 @@ var require_index_cjs = __commonJS({
3950
3950
  exports2.ResultAsync = ResultAsync20;
3951
3951
  exports2.err = err36;
3952
3952
  exports2.errAsync = errAsync11;
3953
- exports2.fromAsyncThrowable = fromAsyncThrowable9;
3953
+ exports2.fromAsyncThrowable = fromAsyncThrowable8;
3954
3954
  exports2.fromPromise = fromPromise;
3955
3955
  exports2.fromSafePromise = fromSafePromise2;
3956
3956
  exports2.fromThrowable = fromThrowable18;
@@ -24656,8 +24656,108 @@ var {
24656
24656
  // src/bootstrap.ts
24657
24657
  var import_neverthrow77 = __toESM(require_index_cjs(), 1);
24658
24658
 
24659
- // src/commands/analyse-command.ts
24660
- var import_promises19 = require("node:fs/promises");
24659
+ // src/commands/analyse/input-validation.ts
24660
+ var import_promises = require("node:fs/promises");
24661
+ var import_neverthrow = __toESM(require_index_cjs(), 1);
24662
+ var checkFileExists = import_neverthrow.ResultAsync.fromThrowable(import_promises.access, () => ({
24663
+ type: "FILE_MISSING"
24664
+ }));
24665
+ function requireApiKey(input) {
24666
+ const apiKey = input.config.GOOGLE_GENERATIVE_AI_API_KEY ?? "";
24667
+ if (!apiKey) {
24668
+ return (0, import_neverthrow.errAsync)({ type: "MISSING_API_KEY" });
24669
+ }
24670
+ return (0, import_neverthrow.okAsync)(apiKey);
24671
+ }
24672
+ function requireVideoPath(input) {
24673
+ if (input.videoPath === void 0) {
24674
+ return (0, import_neverthrow.errAsync)({ type: "MISSING_VIDEO_PATH" });
24675
+ }
24676
+ const path29 = input.videoPath;
24677
+ return checkFileExists(path29).map(() => path29).mapErr(() => ({ type: "VIDEO_NOT_FOUND", path: path29 }));
24678
+ }
24679
+ function validateAnalyseInput(input) {
24680
+ return requireApiKey(input).andThen(
24681
+ (apiKey) => requireVideoPath(input).map((videoPath) => ({ videoPath, apiKey, debug: input.debug }))
24682
+ );
24683
+ }
24684
+
24685
+ // src/commands/item-events.ts
24686
+ function emitItemStart(identity, at) {
24687
+ const { display, itemId, itemName, simulatorUdid } = identity;
24688
+ display.onEvent({ type: "ITEM_QUEUED", item: { id: itemId, name: itemName } });
24689
+ display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid, at });
24690
+ }
24691
+ function emitItemCompleted(input) {
24692
+ const { identity, startedAt, findingsCount, dismissedCount } = input;
24693
+ const { display, itemId, itemName } = identity;
24694
+ const at = Date.now();
24695
+ display.onEvent({
24696
+ type: "ITEM_COMPLETED",
24697
+ itemId,
24698
+ itemName,
24699
+ findingsCount,
24700
+ dismissedCount,
24701
+ durationMs: at - startedAt,
24702
+ at
24703
+ });
24704
+ }
24705
+ function emitItemFailed(input) {
24706
+ const { identity, startedAt, error: error48 } = input;
24707
+ const { display, itemId, itemName } = identity;
24708
+ const at = Date.now();
24709
+ display.onEvent({
24710
+ type: "ITEM_FAILED",
24711
+ itemId,
24712
+ itemName,
24713
+ error: error48,
24714
+ durationMs: at - startedAt,
24715
+ at
24716
+ });
24717
+ }
24718
+
24719
+ // src/commands/analyse/result-handlers.ts
24720
+ var JSON_INDENT = 2;
24721
+ function formatInputError(error48) {
24722
+ switch (error48.type) {
24723
+ case "MISSING_API_KEY": {
24724
+ return "GOOGLE_GENERATIVE_AI_API_KEY is not set\n";
24725
+ }
24726
+ case "MISSING_VIDEO_PATH": {
24727
+ return 'A video path is required. Pass the path printed by "xqa explore".\n';
24728
+ }
24729
+ case "VIDEO_NOT_FOUND": {
24730
+ return `Video file not found: ${error48.path}
24731
+ `;
24732
+ }
24733
+ }
24734
+ }
24735
+ function buildSuccessHandler(state) {
24736
+ return (findings) => {
24737
+ emitItemCompleted({
24738
+ identity: state.identity,
24739
+ startedAt: state.startedAt,
24740
+ findingsCount: findings.length,
24741
+ dismissedCount: 0
24742
+ });
24743
+ state.identity.display.cleanup();
24744
+ process.stdout.write(JSON.stringify(findings, void 0, JSON_INDENT));
24745
+ process.exit(0);
24746
+ };
24747
+ }
24748
+ function buildErrorHandler(state) {
24749
+ return (errorType) => {
24750
+ emitItemFailed({ identity: state.identity, startedAt: state.startedAt, error: errorType });
24751
+ state.identity.display.cleanup();
24752
+ process.stderr.write(`Analysis failed: ${errorType}
24753
+ `);
24754
+ process.exit(1);
24755
+ };
24756
+ }
24757
+ function handleInputError(error48) {
24758
+ process.stderr.write(formatInputError(error48));
24759
+ process.exit(1);
24760
+ }
24661
24761
 
24662
24762
  // ../../node_modules/.pnpm/@anthropic-ai+claude-agent-sdk@0.2.91_zod@4.3.6/node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
24663
24763
  var import_path = require("path");
@@ -24668,15 +24768,15 @@ var import_readline = require("readline");
24668
24768
  var import_os = require("os");
24669
24769
  var import_path2 = require("path");
24670
24770
  var import_crypto = require("crypto");
24671
- var import_promises = require("fs/promises");
24771
+ var import_promises2 = require("fs/promises");
24672
24772
  var import_path3 = require("path");
24673
24773
  var import_fs = require("fs");
24674
24774
  var import_process = require("process");
24675
24775
  var import_crypto2 = require("crypto");
24676
- var import_promises2 = require("fs/promises");
24776
+ var import_promises3 = require("fs/promises");
24677
24777
  var import_path4 = require("path");
24678
24778
  var r = __toESM(require("fs"), 1);
24679
- var import_promises3 = require("fs/promises");
24779
+ var import_promises4 = require("fs/promises");
24680
24780
  var import_child_process2 = require("child_process");
24681
24781
  var import_util = require("util");
24682
24782
  var IL = Object.create;
@@ -31026,7 +31126,7 @@ function yF() {
31026
31126
  if (!B6(process.env.DEBUG_CLAUDE_AGENT_SDK)) return X0 = null, $0 = Promise.resolve(), $0;
31027
31127
  let $ = (0, import_path3.join)(c1(), "debug");
31028
31128
  return X0 = (0, import_path3.join)($, `sdk-${(0, import_crypto.randomUUID)()}.txt`), process.stderr.write(`SDK debug logs: ${X0}
31029
- `), $0 = (0, import_promises.mkdir)($, { recursive: true }).then(() => {
31129
+ `), $0 = (0, import_promises2.mkdir)($, { recursive: true }).then(() => {
31030
31130
  }).catch(() => {
31031
31131
  }), $0;
31032
31132
  }
@@ -31035,7 +31135,7 @@ function s$($) {
31035
31135
  let J = `${(/* @__PURE__ */ new Date()).toISOString()} ${$}
31036
31136
  `;
31037
31137
  yF().then(() => {
31038
- if (X0) (0, import_promises.appendFile)(X0, J).catch(() => {
31138
+ if (X0) (0, import_promises2.appendFile)(X0, J).catch(() => {
31039
31139
  });
31040
31140
  });
31041
31141
  }
@@ -31159,25 +31259,25 @@ var sF = { cwd() {
31159
31259
  V$(J, Y, z6);
31160
31260
  }
31161
31261
  }, async stat($) {
31162
- return (0, import_promises3.stat)($);
31262
+ return (0, import_promises4.stat)($);
31163
31263
  }, async readdir($) {
31164
- return (0, import_promises3.readdir)($, { withFileTypes: true });
31264
+ return (0, import_promises4.readdir)($, { withFileTypes: true });
31165
31265
  }, async unlink($) {
31166
- return (0, import_promises3.unlink)($);
31266
+ return (0, import_promises4.unlink)($);
31167
31267
  }, async rmdir($) {
31168
- return (0, import_promises3.rmdir)($);
31268
+ return (0, import_promises4.rmdir)($);
31169
31269
  }, async rm($, X) {
31170
- return (0, import_promises3.rm)($, X);
31270
+ return (0, import_promises4.rm)($, X);
31171
31271
  }, async mkdir($, X) {
31172
31272
  try {
31173
- await (0, import_promises3.mkdir)($, { recursive: true, ...X });
31273
+ await (0, import_promises4.mkdir)($, { recursive: true, ...X });
31174
31274
  } catch (J) {
31175
31275
  if (H1(J) !== "EEXIST") throw J;
31176
31276
  }
31177
31277
  }, async readFile($, X) {
31178
- return (0, import_promises3.readFile)($, { encoding: X.encoding });
31278
+ return (0, import_promises4.readFile)($, { encoding: X.encoding });
31179
31279
  }, async rename($, X) {
31180
- return (0, import_promises3.rename)($, X);
31280
+ return (0, import_promises4.rename)($, X);
31181
31281
  }, statSync($) {
31182
31282
  let J = [];
31183
31283
  try {
@@ -31396,8 +31496,8 @@ var sF = { cwd() {
31396
31496
  }, createWriteStream($) {
31397
31497
  return r.createWriteStream($);
31398
31498
  }, async readFileBytes($, X) {
31399
- if (X === void 0) return (0, import_promises3.readFile)($);
31400
- let J = await (0, import_promises3.open)($, "r");
31499
+ if (X === void 0) return (0, import_promises4.readFile)($);
31500
+ let J = await (0, import_promises4.open)($, "r");
31401
31501
  try {
31402
31502
  let { size: Q } = await J.stat(), Y = Math.min(Q, X), z6 = Buffer.allocUnsafe(Y), W = 0;
31403
31503
  while (W < Y) {
@@ -31458,9 +31558,9 @@ var HM = false;
31458
31558
  var ZJ = null;
31459
31559
  var xz = Promise.resolve();
31460
31560
  async function KM($, X, J, Q) {
31461
- if ($) await (0, import_promises2.mkdir)(X, { recursive: true }).catch(() => {
31561
+ if ($) await (0, import_promises3.mkdir)(X, { recursive: true }).catch(() => {
31462
31562
  });
31463
- await (0, import_promises2.appendFile)(J, Q), RK();
31563
+ await (0, import_promises3.appendFile)(J, Q), RK();
31464
31564
  }
31465
31565
  function NM() {
31466
31566
  }
@@ -31503,8 +31603,8 @@ function EK() {
31503
31603
  var RK = E6(async () => {
31504
31604
  try {
31505
31605
  let $ = EK(), X = (0, import_path4.dirname)($), J = (0, import_path4.join)(X, "latest");
31506
- await (0, import_promises2.unlink)(J).catch(() => {
31507
- }), await (0, import_promises2.symlink)($, J);
31606
+ await (0, import_promises3.unlink)(J).catch(() => {
31607
+ }), await (0, import_promises3.symlink)($, J);
31508
31608
  } catch {
31509
31609
  }
31510
31610
  });
@@ -41786,12 +41886,12 @@ function Qs({ prompt: $, options: X }) {
41786
41886
  }
41787
41887
 
41788
41888
  // ../../packages/mobile-ios/dist/index.js
41789
- var import_promises4 = require("node:timers/promises");
41790
- var import_neverthrow = __toESM(require_index_cjs(), 1);
41889
+ var import_promises5 = require("node:timers/promises");
41791
41890
  var import_neverthrow2 = __toESM(require_index_cjs(), 1);
41792
- var import_node_child_process = require("node:child_process");
41793
41891
  var import_neverthrow3 = __toESM(require_index_cjs(), 1);
41892
+ var import_node_child_process = require("node:child_process");
41794
41893
  var import_neverthrow4 = __toESM(require_index_cjs(), 1);
41894
+ var import_neverthrow5 = __toESM(require_index_cjs(), 1);
41795
41895
 
41796
41896
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
41797
41897
  var external_exports = {};
@@ -55562,18 +55662,18 @@ function date4(params) {
55562
55662
  config(en_default());
55563
55663
 
55564
55664
  // ../../packages/mobile-ios/dist/index.js
55565
- var import_promises5 = require("node:timers/promises");
55566
- var import_promises6 = require("node:fs/promises");
55665
+ var import_promises6 = require("node:timers/promises");
55666
+ var import_promises7 = require("node:fs/promises");
55567
55667
  var import_node_os = require("node:os");
55568
55668
  var import_node_path = __toESM(require("node:path"), 1);
55569
- var import_neverthrow5 = __toESM(require_index_cjs(), 1);
55570
- var import_sharp = __toESM(require("sharp"), 1);
55571
55669
  var import_neverthrow6 = __toESM(require_index_cjs(), 1);
55572
- var import_promises7 = require("node:timers/promises");
55670
+ var import_sharp = __toESM(require("sharp"), 1);
55671
+ var import_neverthrow7 = __toESM(require_index_cjs(), 1);
55672
+ var import_promises8 = require("node:timers/promises");
55573
55673
  var import_node_crypto = require("node:crypto");
55574
55674
  var import_node_child_process2 = require("node:child_process");
55575
55675
  var import_node_events = require("node:events");
55576
- var import_neverthrow7 = __toESM(require_index_cjs(), 1);
55676
+ var import_neverthrow8 = __toESM(require_index_cjs(), 1);
55577
55677
  async function execFilePromise(command, arguments_) {
55578
55678
  const { promise: promise2, resolve, reject } = Promise.withResolvers();
55579
55679
  (0, import_node_child_process.execFile)(command, arguments_, (error48, stdout) => {
@@ -55586,13 +55686,13 @@ async function execFilePromise(command, arguments_) {
55586
55686
  return promise2;
55587
55687
  }
55588
55688
  function runCommand(command, arguments_) {
55589
- return (0, import_neverthrow3.fromAsyncThrowable)(
55689
+ return (0, import_neverthrow4.fromAsyncThrowable)(
55590
55690
  execFilePromise,
55591
55691
  (cause) => ({ type: "COMMAND_FAILED", command, args: arguments_, cause })
55592
55692
  )(command, arguments_);
55593
55693
  }
55594
55694
  var cache = /* @__PURE__ */ new Map();
55595
- var safeParseSimctlOutput = (0, import_neverthrow2.fromThrowable)(
55695
+ var safeParseSimctlOutput = (0, import_neverthrow3.fromThrowable)(
55596
55696
  JSON.parse,
55597
55697
  (cause) => ({
55598
55698
  type: "COMMAND_FAILED",
@@ -55621,19 +55721,19 @@ function findBootedUdid(parsed) {
55621
55721
  }
55622
55722
  function resolveUdid(udid) {
55623
55723
  if (udid !== "booted") {
55624
- return (0, import_neverthrow2.okAsync)(udid);
55724
+ return (0, import_neverthrow3.okAsync)(udid);
55625
55725
  }
55626
55726
  const cached2 = cache.get(udid);
55627
55727
  if (cached2 !== void 0) {
55628
- return (0, import_neverthrow2.okAsync)(cached2);
55728
+ return (0, import_neverthrow3.okAsync)(cached2);
55629
55729
  }
55630
55730
  return runCommand("xcrun", ["simctl", "list", "devices", "booted", "--json"]).andThen((raw) => safeParseSimctlOutput(raw)).andThen((parsed) => {
55631
55731
  const result = findBootedUdid(parsed);
55632
55732
  if (typeof result === "string") {
55633
55733
  cache.set(udid, result);
55634
- return (0, import_neverthrow2.ok)(result);
55734
+ return (0, import_neverthrow3.ok)(result);
55635
55735
  }
55636
- return (0, import_neverthrow2.err)(result);
55736
+ return (0, import_neverthrow3.err)(result);
55637
55737
  });
55638
55738
  }
55639
55739
  var FULLSCREEN_THRESHOLD = 0.9;
@@ -55772,7 +55872,7 @@ function structuralSignature(elements) {
55772
55872
  }
55773
55873
  var STABILITY_POLL_ATTEMPTS = 10;
55774
55874
  var STABILITY_POLL_DELAY_MS = 500;
55775
- var parseIdbTree = (0, import_neverthrow.fromThrowable)(
55875
+ var parseIdbTree = (0, import_neverthrow2.fromThrowable)(
55776
55876
  (raw) => JSON.parse(raw),
55777
55877
  (cause) => ({ type: "SNAPSHOT_PARSE_FAILED", cause })
55778
55878
  );
@@ -55790,22 +55890,22 @@ async function pollUntilStable(udid) {
55790
55890
  const raw = result.value;
55791
55891
  const parsed = parseIdbTree(raw);
55792
55892
  if (parsed.isErr()) {
55793
- return (0, import_neverthrow.err)(parsed.error);
55893
+ return (0, import_neverthrow2.err)(parsed.error);
55794
55894
  }
55795
55895
  const signature = structuralSignature(parsed.value);
55796
55896
  if (signature === previousSignature) {
55797
- return (0, import_neverthrow.ok)(raw);
55897
+ return (0, import_neverthrow2.ok)(raw);
55798
55898
  }
55799
55899
  previousSignature = signature;
55800
55900
  previousRaw = raw;
55801
55901
  if (index < STABILITY_POLL_ATTEMPTS - 1) {
55802
- await (0, import_promises4.setTimeout)(STABILITY_POLL_DELAY_MS);
55902
+ await (0, import_promises5.setTimeout)(STABILITY_POLL_DELAY_MS);
55803
55903
  }
55804
55904
  }
55805
- return (0, import_neverthrow.ok)(previousRaw);
55905
+ return (0, import_neverthrow2.ok)(previousRaw);
55806
55906
  }
55807
55907
  function waitForStableSnapshot(udid) {
55808
- return import_neverthrow.ResultAsync.fromSafePromise(pollUntilStable(udid)).andThen((result) => result);
55908
+ return import_neverthrow2.ResultAsync.fromSafePromise(pollUntilStable(udid)).andThen((result) => result);
55809
55909
  }
55810
55910
  function captureAccessibilityTree(udid = "booted") {
55811
55911
  return resolveUdid(udid).andThen((resolvedUdid) => waitForStableSnapshot(resolvedUdid)).andThen((raw) => parseIdbTree(raw));
@@ -55843,7 +55943,7 @@ function errorResult(error48) {
55843
55943
  isError: true
55844
55944
  };
55845
55945
  }
55846
- var safeJsonParse = (0, import_neverthrow4.fromThrowable)(
55946
+ var safeJsonParse = (0, import_neverthrow5.fromThrowable)(
55847
55947
  JSON.parse,
55848
55948
  (cause) => ({ type: "PARSE_FAILED", cause })
55849
55949
  );
@@ -55880,7 +55980,7 @@ function parseAppList(raw) {
55880
55980
  for (const line of lines) {
55881
55981
  const lineResult = safeJsonParse(line);
55882
55982
  if (lineResult.isErr()) {
55883
- return (0, import_neverthrow4.err)(lineResult.error);
55983
+ return (0, import_neverthrow5.err)(lineResult.error);
55884
55984
  }
55885
55985
  const value = lineResult.value;
55886
55986
  if (Array.isArray(value)) {
@@ -55889,7 +55989,7 @@ function parseAppList(raw) {
55889
55989
  parsed.push(value);
55890
55990
  }
55891
55991
  }
55892
- return (0, import_neverthrow4.ok)(parsed);
55992
+ return (0, import_neverthrow5.ok)(parsed);
55893
55993
  }
55894
55994
  async function handleListApps(udid) {
55895
55995
  const result = await resolveUdid(udid).andThen(
@@ -55948,7 +56048,7 @@ function buildTapArguments(resolvedUdid, input) {
55948
56048
  return ["ui", "tap", "--udid", resolvedUdid, String(input.x), String(input.y)];
55949
56049
  }
55950
56050
  async function handleTap(input) {
55951
- await (0, import_promises5.setTimeout)(GESTURE_SETTLE_MS);
56051
+ await (0, import_promises6.setTimeout)(GESTURE_SETTLE_MS);
55952
56052
  const result = await resolveUdid(input.udid).andThen(
55953
56053
  (resolvedUdid) => runCommand("idb", buildTapArguments(resolvedUdid, input))
55954
56054
  );
@@ -56151,7 +56251,7 @@ function getDeviceInfo(udid) {
56151
56251
  return resolveUdid(udid).andThen((resolvedUdid) => {
56152
56252
  const cached2 = cache2.get(resolvedUdid);
56153
56253
  if (cached2 !== void 0) {
56154
- return (0, import_neverthrow6.okAsync)(cached2);
56254
+ return (0, import_neverthrow7.okAsync)(cached2);
56155
56255
  }
56156
56256
  return runCommand("idb", ["describe", "--udid", resolvedUdid, "--json"]).map((raw) => {
56157
56257
  const info = parseDeviceInfo(raw);
@@ -56164,7 +56264,7 @@ async function sharpResize(buffer, dimensions) {
56164
56264
  return (0, import_sharp.default)(buffer).resize(dimensions.widthPoints, dimensions.heightPoints).png().toBuffer();
56165
56265
  }
56166
56266
  function resizeToLogicalPixels(buffer, dimensions) {
56167
- return (0, import_neverthrow5.fromAsyncThrowable)(
56267
+ return (0, import_neverthrow6.fromAsyncThrowable)(
56168
56268
  sharpResize,
56169
56269
  (cause) => ({
56170
56270
  type: "COMMAND_FAILED",
@@ -56175,15 +56275,15 @@ function resizeToLogicalPixels(buffer, dimensions) {
56175
56275
  )(buffer, dimensions);
56176
56276
  }
56177
56277
  async function readAndDelete(filePath) {
56178
- const data = await (0, import_promises6.readFile)(filePath);
56179
- void (0, import_promises6.rm)(filePath, { force: true });
56278
+ const data = await (0, import_promises7.readFile)(filePath);
56279
+ void (0, import_promises7.rm)(filePath, { force: true });
56180
56280
  return data;
56181
56281
  }
56182
56282
  function captureScreenshot(udid = "booted") {
56183
56283
  const screenshotPath = import_node_path.default.join((0, import_node_os.tmpdir)(), `explorer-screenshot-${String(Date.now())}.png`);
56184
56284
  return resolveUdid(udid).andThen(
56185
56285
  (resolvedUdid) => runCommand("xcrun", ["simctl", "io", resolvedUdid, "screenshot", screenshotPath]).andThen(
56186
- () => (0, import_neverthrow5.fromAsyncThrowable)(
56286
+ () => (0, import_neverthrow6.fromAsyncThrowable)(
56187
56287
  readAndDelete,
56188
56288
  (cause) => ({
56189
56289
  type: "COMMAND_FAILED",
@@ -56194,7 +56294,7 @@ function captureScreenshot(udid = "booted") {
56194
56294
  )(screenshotPath)
56195
56295
  ).andThen(
56196
56296
  (buffer) => getDeviceInfo(resolvedUdid).andThen(
56197
- ({ widthPoints, heightPoints, density }) => density > 1 ? resizeToLogicalPixels(buffer, { widthPoints, heightPoints }) : (0, import_neverthrow5.okAsync)(buffer)
56297
+ ({ widthPoints, heightPoints, density }) => density > 1 ? resizeToLogicalPixels(buffer, { widthPoints, heightPoints }) : (0, import_neverthrow6.okAsync)(buffer)
56198
56298
  )
56199
56299
  ).map((buffer) => buffer.toString("base64"))
56200
56300
  );
@@ -56241,7 +56341,7 @@ function createWaitSecondsTool() {
56241
56341
  isError: true
56242
56342
  };
56243
56343
  }
56244
- await (0, import_promises7.setTimeout)(parsed.data * MS_PER_SECOND2);
56344
+ await (0, import_promises8.setTimeout)(parsed.data * MS_PER_SECOND2);
56245
56345
  return { content: [{ type: "text", text: `Waited ${String(parsed.data)}s` }] };
56246
56346
  }
56247
56347
  );
@@ -56315,7 +56415,7 @@ function computeScreenFingerprint(elements) {
56315
56415
  elements: fingerprintElements
56316
56416
  };
56317
56417
  }
56318
- var safeParseJson = (0, import_neverthrow7.fromThrowable)(
56418
+ var safeParseJson = (0, import_neverthrow8.fromThrowable)(
56319
56419
  JSON.parse,
56320
56420
  (cause) => ({ type: "SIMULATOR_COMMAND_FAILED", cause })
56321
56421
  );
@@ -56336,16 +56436,16 @@ function extractBootedSimulators(output) {
56336
56436
  }
56337
56437
  function handleClose(code) {
56338
56438
  if (code === 0) {
56339
- return (0, import_neverthrow7.ok)();
56439
+ return (0, import_neverthrow8.ok)();
56340
56440
  }
56341
- return (0, import_neverthrow7.err)({
56441
+ return (0, import_neverthrow8.err)({
56342
56442
  type: "SIMULATOR_COMMAND_FAILED",
56343
56443
  cause: new RangeError(`xcrun exited with code ${String(code)}`)
56344
56444
  });
56345
56445
  }
56346
56446
  function runSimctlCommand(arguments_) {
56347
56447
  const proc = (0, import_node_child_process2.spawn)("xcrun", arguments_);
56348
- return import_neverthrow7.ResultAsync.fromPromise(
56448
+ return import_neverthrow8.ResultAsync.fromPromise(
56349
56449
  (0, import_node_events.once)(proc, "close"),
56350
56450
  (cause) => ({ type: "SIMULATOR_COMMAND_FAILED", cause })
56351
56451
  ).andThen(([code]) => handleClose(code));
@@ -56403,7 +56503,7 @@ function createMobileIosServer(udid = "booted", extraTools = []) {
56403
56503
  }
56404
56504
 
56405
56505
  // ../../agents/analyser/dist/index.js
56406
- var import_promises8 = require("node:fs/promises");
56506
+ var import_promises9 = require("node:fs/promises");
56407
56507
 
56408
56508
  // ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
56409
56509
  var ANSI_BACKGROUND_OFFSET = 10;
@@ -56906,7 +57006,7 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
56906
57006
  var source_default = chalk;
56907
57007
 
56908
57008
  // ../../packages/display/dist/index.js
56909
- var import_neverthrow8 = __toESM(require_index_cjs(), 1);
57009
+ var import_neverthrow9 = __toESM(require_index_cjs(), 1);
56910
57010
  var ESC = "\x1B";
56911
57011
  var CTRL_C = "";
56912
57012
  var CTRL_O = "";
@@ -57276,6 +57376,15 @@ function normalizeItemTimeout(event) {
57276
57376
  }
57277
57377
  ];
57278
57378
  }
57379
+ function normalizeItemAborted(event) {
57380
+ return [
57381
+ {
57382
+ kind: "text",
57383
+ style: "error",
57384
+ text: `[${event.itemName}] ABORTED (${formatDuration(event.durationMs)}) ${event.reason}`
57385
+ }
57386
+ ];
57387
+ }
57279
57388
  function normalizeSimulatorUnhealthy(event) {
57280
57389
  return [
57281
57390
  {
@@ -57300,6 +57409,7 @@ var HANDLERS = {
57300
57409
  ITEM_COMPLETED: (event) => normalizeItemCompleted(event),
57301
57410
  ITEM_FAILED: (event) => normalizeItemFailed(event),
57302
57411
  ITEM_TIMEOUT: (event) => normalizeItemTimeout(event),
57412
+ ITEM_ABORTED: (event) => normalizeItemAborted(event),
57303
57413
  SIMULATOR_UNHEALTHY: (event) => normalizeSimulatorUnhealthy(event),
57304
57414
  SUITE_COMPLETED: (event) => normalizeSuiteCompleted(event)
57305
57415
  };
@@ -57702,6 +57812,7 @@ var SUITE_EVENT_TYPES = /* @__PURE__ */ new Set([
57702
57812
  "ITEM_COMPLETED",
57703
57813
  "ITEM_FAILED",
57704
57814
  "ITEM_TIMEOUT",
57815
+ "ITEM_ABORTED",
57705
57816
  "SIMULATOR_UNHEALTHY",
57706
57817
  "SUITE_COMPLETED"
57707
57818
  ]);
@@ -57715,7 +57826,8 @@ var UI_EVENT_TYPES = /* @__PURE__ */ new Set([
57715
57826
  var TERMINAL_STATUS = {
57716
57827
  ITEM_COMPLETED: "completed",
57717
57828
  ITEM_FAILED: "failed",
57718
- ITEM_TIMEOUT: "timeout"
57829
+ ITEM_TIMEOUT: "timeout",
57830
+ ITEM_ABORTED: "aborted"
57719
57831
  };
57720
57832
  function isSuiteEvent(event) {
57721
57833
  return SUITE_EVENT_TYPES.has(event.type);
@@ -57822,7 +57934,8 @@ function reduceSuiteEvent(state, event) {
57822
57934
  }
57823
57935
  case "ITEM_COMPLETED":
57824
57936
  case "ITEM_FAILED":
57825
- case "ITEM_TIMEOUT": {
57937
+ case "ITEM_TIMEOUT":
57938
+ case "ITEM_ABORTED": {
57826
57939
  return reduceItemTerminal(state, event);
57827
57940
  }
57828
57941
  case "SIMULATOR_UNHEALTHY": {
@@ -57845,7 +57958,12 @@ function reduce(state, event) {
57845
57958
  }
57846
57959
  return { ...state, spinnerFrame: state.spinnerFrame + 1 };
57847
57960
  }
57848
- var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "timeout"]);
57961
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
57962
+ "completed",
57963
+ "failed",
57964
+ "timeout",
57965
+ "aborted"
57966
+ ]);
57849
57967
  function isTerminal(item) {
57850
57968
  if (item === void 0) {
57851
57969
  return false;
@@ -57925,7 +58043,7 @@ ${body}::endgroup::
57925
58043
  function failureCount(state) {
57926
58044
  let count = 0;
57927
58045
  for (const item of state.items.values()) {
57928
- if (item.status === "failed" || item.status === "timeout") {
58046
+ if (item.status === "failed" || item.status === "timeout" || item.status === "aborted") {
57929
58047
  count += 1;
57930
58048
  }
57931
58049
  }
@@ -58112,14 +58230,14 @@ function safeHandler(handler2) {
58112
58230
  `);
58113
58231
  return void 0;
58114
58232
  };
58115
- const safe = (0, import_neverthrow8.fromThrowable)(bounded, errorMapper);
58233
+ const safe = (0, import_neverthrow9.fromThrowable)(bounded, errorMapper);
58116
58234
  safe(event).isOk();
58117
58235
  };
58118
58236
  }
58119
58237
 
58120
58238
  // ../../agents/analyser/dist/index.js
58121
- var import_neverthrow9 = __toESM(require_index_cjs(), 1);
58122
- var import_promises9 = require("node:timers/promises");
58239
+ var import_neverthrow10 = __toESM(require_index_cjs(), 1);
58240
+ var import_promises10 = require("node:timers/promises");
58123
58241
 
58124
58242
  // ../../node_modules/.pnpm/@google+generative-ai@0.24.1/node_modules/@google/generative-ai/dist/index.mjs
58125
58243
  var SchemaType;
@@ -59500,8 +59618,8 @@ var DynamicRetrievalMode2;
59500
59618
  })(DynamicRetrievalMode2 || (DynamicRetrievalMode2 = {}));
59501
59619
 
59502
59620
  // ../../agents/analyser/dist/index.js
59503
- var import_neverthrow10 = __toESM(require_index_cjs(), 1);
59504
59621
  var import_neverthrow11 = __toESM(require_index_cjs(), 1);
59622
+ var import_neverthrow12 = __toESM(require_index_cjs(), 1);
59505
59623
  var FINDINGS_RESPONSE_SCHEMA = {
59506
59624
  type: "array",
59507
59625
  items: {
@@ -59537,19 +59655,19 @@ var categoricalFindingSchema = external_exports.object({
59537
59655
  agent: external_exports.string()
59538
59656
  });
59539
59657
  var categoricalFindingsArraySchema = external_exports.array(categoricalFindingSchema);
59540
- var safeJsonParse2 = (0, import_neverthrow11.fromThrowable)(JSON.parse);
59658
+ var safeJsonParse2 = (0, import_neverthrow12.fromThrowable)(JSON.parse);
59541
59659
  function parseAnalysisResponse(text) {
59542
59660
  const parseResult = safeJsonParse2(text);
59543
59661
  if (parseResult.isErr()) {
59544
- return (0, import_neverthrow11.err)({ type: "MALFORMED_JSON", cause: parseResult.error });
59662
+ return (0, import_neverthrow12.err)({ type: "MALFORMED_JSON", cause: parseResult.error });
59545
59663
  }
59546
59664
  const raw = parseResult.value;
59547
59665
  const validated = categoricalFindingsArraySchema.safeParse(raw);
59548
59666
  if (!validated.success) {
59549
- return (0, import_neverthrow11.err)({ type: "SCHEMA_VALIDATION_FAILED", cause: validated.error });
59667
+ return (0, import_neverthrow12.err)({ type: "SCHEMA_VALIDATION_FAILED", cause: validated.error });
59550
59668
  }
59551
59669
  const findings = validated.data.map((finding) => ({ ...finding }));
59552
- return (0, import_neverthrow11.ok)(findings);
59670
+ return (0, import_neverthrow12.ok)(findings);
59553
59671
  }
59554
59672
  var MAX_POLL_ATTEMPTS = 30;
59555
59673
  var POLL_INTERVAL_MS = 2e3;
@@ -59572,7 +59690,7 @@ async function runPollLoop(checkState, onTick) {
59572
59690
  if (state === FileState.FAILED) {
59573
59691
  return "failed";
59574
59692
  }
59575
- await (0, import_promises9.setTimeout)(POLL_INTERVAL_MS);
59693
+ await (0, import_promises10.setTimeout)(POLL_INTERVAL_MS);
59576
59694
  }
59577
59695
  return "timeout";
59578
59696
  }
@@ -59621,16 +59739,16 @@ function toFindings(text) {
59621
59739
  }
59622
59740
  function pollOutcomeToResult(outcome, fileUri) {
59623
59741
  if (outcome === "active") {
59624
- return (0, import_neverthrow10.ok)(fileUri);
59742
+ return (0, import_neverthrow11.ok)(fileUri);
59625
59743
  }
59626
59744
  if (outcome === "failed") {
59627
- return (0, import_neverthrow10.err)({ type: "PROCESSING_FAILED", fileUri });
59745
+ return (0, import_neverthrow11.err)({ type: "PROCESSING_FAILED", fileUri });
59628
59746
  }
59629
- return (0, import_neverthrow10.err)({ type: "POLL_TIMEOUT", fileUri });
59747
+ return (0, import_neverthrow11.err)({ type: "POLL_TIMEOUT", fileUri });
59630
59748
  }
59631
59749
  function uploadVideo(videoPath, apiKey) {
59632
59750
  const fileManager = new GoogleAIFileManager(apiKey);
59633
- return (0, import_neverthrow10.fromAsyncThrowable)(
59751
+ return (0, import_neverthrow11.fromAsyncThrowable)(
59634
59752
  uploadVideoFile,
59635
59753
  (cause) => ({ type: "UPLOAD_FAILED", cause })
59636
59754
  )(fileManager, videoPath);
@@ -59639,7 +59757,7 @@ function pollUntilActive(fileUri, options2) {
59639
59757
  const fileManager = new GoogleAIFileManager(options2.apiKey);
59640
59758
  const fileName2 = extractFileName(fileUri);
59641
59759
  const checkState = async () => checkFileState(fileManager, fileName2);
59642
- return (0, import_neverthrow10.fromAsyncThrowable)(
59760
+ return (0, import_neverthrow11.fromAsyncThrowable)(
59643
59761
  runPollLoop,
59644
59762
  (cause) => ({ type: "UPLOAD_FAILED", cause })
59645
59763
  )(checkState, options2.onTick).andThen((outcome) => pollOutcomeToResult(outcome, fileUri));
@@ -59647,7 +59765,7 @@ function pollUntilActive(fileUri, options2) {
59647
59765
  function analyseArtifacts(options2) {
59648
59766
  const { videoUri, prompt, apiKey, model } = options2;
59649
59767
  const genModel = buildGenerativeModel(apiKey, model);
59650
- return (0, import_neverthrow10.fromAsyncThrowable)(
59768
+ return (0, import_neverthrow11.fromAsyncThrowable)(
59651
59769
  generateAnalysisText,
59652
59770
  (cause) => ({ type: "REQUEST_FAILED", cause })
59653
59771
  )({ genModel, videoUri, prompt }).andThen(toFindings);
@@ -59708,7 +59826,7 @@ var DEFAULT_MODEL = "gemini-2.5-pro";
59708
59826
  var BYTES_PER_MB = 1048576;
59709
59827
  var MAX_POLL_ATTEMPTS2 = 30;
59710
59828
  async function getFileSize(filePath) {
59711
- const fileStats = await (0, import_promises8.stat)(filePath);
59829
+ const fileStats = await (0, import_promises9.stat)(filePath);
59712
59830
  return fileStats.size;
59713
59831
  }
59714
59832
  function emitStageEnd(onEvent, start) {
@@ -59744,7 +59862,7 @@ function emitUploadProgress(onEvent, bytes) {
59744
59862
  }
59745
59863
  function runUploadPipeline(context) {
59746
59864
  const { apiKey, model, onEvent, start, videoPath, prompt } = context;
59747
- return (0, import_neverthrow9.fromAsyncThrowable)(
59865
+ return (0, import_neverthrow10.fromAsyncThrowable)(
59748
59866
  getFileSize,
59749
59867
  (cause) => ({ type: "UPLOAD_FAILED", cause })
59750
59868
  )(videoPath).andThen((bytes) => {
@@ -59764,17 +59882,17 @@ function runAnalyser(artifacts, config2) {
59764
59882
  onEvent?.({ type: "STAGE_START", agent: "analyser" });
59765
59883
  if (!videoPath) {
59766
59884
  emitStageEnd(onEvent, start);
59767
- return (0, import_neverthrow9.errAsync)({ type: "VIDEO_PATH_MISSING" });
59885
+ return (0, import_neverthrow10.errAsync)({ type: "VIDEO_PATH_MISSING" });
59768
59886
  }
59769
59887
  return runUploadPipeline(context);
59770
59888
  }
59771
59889
 
59772
59890
  // ../../packages/pipeline/dist/index.js
59773
- var import_neverthrow35 = __toESM(require_index_cjs(), 1);
59774
- var import_promises17 = require("node:timers/promises");
59891
+ var import_neverthrow36 = __toESM(require_index_cjs(), 1);
59892
+ var import_promises18 = require("node:timers/promises");
59775
59893
 
59776
59894
  // ../../agents/consolidator/dist/index.js
59777
- var import_neverthrow14 = __toESM(require_index_cjs(), 1);
59895
+ var import_neverthrow15 = __toESM(require_index_cjs(), 1);
59778
59896
 
59779
59897
  // ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/internal/tslib.mjs
59780
59898
  function __classPrivateFieldSet(receiver, state, value, kind, f6) {
@@ -65614,19 +65732,19 @@ var findingInputSchema = findingSchema.omit({ agent: true, screenshots: true, co
65614
65732
 
65615
65733
  // ../../packages/shared/dist/run-paths.js
65616
65734
  var import_node_path2 = __toESM(require("node:path"), 1);
65617
- var import_neverthrow12 = __toESM(require_index_cjs(), 1);
65735
+ var import_neverthrow13 = __toESM(require_index_cjs(), 1);
65618
65736
  function resolveRunPaths({ outputDirectory, runId, date: date5 }) {
65619
65737
  if (!outputDirectory) {
65620
- return (0, import_neverthrow12.err)({ type: "EMPTY_OUTPUT_DIRECTORY" });
65738
+ return (0, import_neverthrow13.err)({ type: "EMPTY_OUTPUT_DIRECTORY" });
65621
65739
  }
65622
65740
  if (!runId) {
65623
- return (0, import_neverthrow12.err)({ type: "EMPTY_RUN_ID" });
65741
+ return (0, import_neverthrow13.err)({ type: "EMPTY_RUN_ID" });
65624
65742
  }
65625
65743
  if (runId.includes("/") || runId.includes("\\")) {
65626
- return (0, import_neverthrow12.err)({ type: "INVALID_RUN_ID", value: runId });
65744
+ return (0, import_neverthrow13.err)({ type: "INVALID_RUN_ID", value: runId });
65627
65745
  }
65628
65746
  const baseDirectory = import_node_path2.default.join(outputDirectory, date5, runId);
65629
- return (0, import_neverthrow12.ok)({
65747
+ return (0, import_neverthrow13.ok)({
65630
65748
  baseDir: baseDirectory,
65631
65749
  videoPath: import_node_path2.default.join(baseDirectory, "recording.mp4"),
65632
65750
  findingsPath: import_node_path2.default.join(baseDirectory, "findings.json"),
@@ -65644,7 +65762,7 @@ function dismissalsPath(baseDirectory, override) {
65644
65762
  }
65645
65763
 
65646
65764
  // ../../packages/tools/dist/index.js
65647
- var import_neverthrow13 = __toESM(require_index_cjs(), 1);
65765
+ var import_neverthrow14 = __toESM(require_index_cjs(), 1);
65648
65766
  function buildGetOutputTool() {
65649
65767
  return {
65650
65768
  name: "get_output",
@@ -65661,22 +65779,22 @@ function buildSetOutputTool(schema2) {
65661
65779
  }
65662
65780
  function dispatchToolCall(request2) {
65663
65781
  if (request2.name === "get_output") {
65664
- return (0, import_neverthrow13.ok)(request2.getOutputJson());
65782
+ return (0, import_neverthrow14.ok)(request2.getOutputJson());
65665
65783
  }
65666
65784
  if (request2.name === "set_output") {
65667
65785
  return request2.setOutput(request2.input).map(() => JSON.stringify({ ok: true }));
65668
65786
  }
65669
- return (0, import_neverthrow13.err)({ type: "UNKNOWN_TOOL", name: request2.name });
65787
+ return (0, import_neverthrow14.err)({ type: "UNKNOWN_TOOL", name: request2.name });
65670
65788
  }
65671
65789
  function createOutputTools(schema2) {
65672
65790
  let current;
65673
65791
  function setOutput(value) {
65674
65792
  const parsed = schema2.safeParse(value);
65675
65793
  if (!parsed.success) {
65676
- return (0, import_neverthrow13.err)({ type: "VALIDATION_ERROR", cause: parsed.error });
65794
+ return (0, import_neverthrow14.err)({ type: "VALIDATION_ERROR", cause: parsed.error });
65677
65795
  }
65678
65796
  current = parsed.data;
65679
- return (0, import_neverthrow13.ok)();
65797
+ return (0, import_neverthrow14.ok)();
65680
65798
  }
65681
65799
  return {
65682
65800
  tools: [buildGetOutputTool(), buildSetOutputTool(schema2)],
@@ -65692,8 +65810,8 @@ function createOutputTools(schema2) {
65692
65810
  }
65693
65811
 
65694
65812
  // ../../agents/consolidator/dist/index.js
65695
- var import_neverthrow15 = __toESM(require_index_cjs(), 1);
65696
65813
  var import_neverthrow16 = __toESM(require_index_cjs(), 1);
65814
+ var import_neverthrow17 = __toESM(require_index_cjs(), 1);
65697
65815
  var MODEL = "claude-opus-4-6";
65698
65816
  var MAX_TOKENS = 4096;
65699
65817
  var findingWithoutConfidenceSchema = findingSchema.omit({ confidence: true });
@@ -65733,16 +65851,16 @@ function processToolUseBlock(toolUseBlock, context) {
65733
65851
  });
65734
65852
  const result = context.factory.handleToolCall(toolUseBlock.name, toolUseBlock.input);
65735
65853
  if (result.isErr()) {
65736
- return (0, import_neverthrow15.err)({
65854
+ return (0, import_neverthrow16.err)({
65737
65855
  type: "REQUEST_FAILED",
65738
65856
  cause: result.error
65739
65857
  });
65740
65858
  }
65741
65859
  const output = context.factory.getOutput();
65742
65860
  if (output === void 0) {
65743
- return (0, import_neverthrow15.err)({ type: "UNEXPECTED_RESPONSE" });
65861
+ return (0, import_neverthrow16.err)({ type: "UNEXPECTED_RESPONSE" });
65744
65862
  }
65745
- return (0, import_neverthrow15.ok)(output);
65863
+ return (0, import_neverthrow16.ok)(output);
65746
65864
  }
65747
65865
  function extractRawOutput(response, context) {
65748
65866
  emitThoughts(response, context.onEvent);
@@ -65750,7 +65868,7 @@ function extractRawOutput(response, context) {
65750
65868
  (block) => block.type === "tool_use" && block.name === "set_output"
65751
65869
  );
65752
65870
  if (!toolUseBlock) {
65753
- return (0, import_neverthrow15.err)({ type: "UNEXPECTED_RESPONSE" });
65871
+ return (0, import_neverthrow16.err)({ type: "UNEXPECTED_RESPONSE" });
65754
65872
  }
65755
65873
  return processToolUseBlock(toolUseBlock, context);
65756
65874
  }
@@ -65758,7 +65876,7 @@ function consolidateFindings(prompt, onEvent) {
65758
65876
  const client = new Anthropic();
65759
65877
  const factory = createOutputTools(rawConsolidationOutputSchema);
65760
65878
  const tools = [factory.tools[1]];
65761
- return (0, import_neverthrow15.fromAsyncThrowable)(
65879
+ return (0, import_neverthrow16.fromAsyncThrowable)(
65762
65880
  fetchMessage,
65763
65881
  (cause) => ({ type: "REQUEST_FAILED", cause })
65764
65882
  )({ client, prompt, tools }).andThen(
@@ -65780,15 +65898,15 @@ function resolveConfidence(output, pool) {
65780
65898
  const metadataMatch = findByKey(pool.metadataFindings, key);
65781
65899
  const visualMatch = findByKey(pool.visualFindings, key);
65782
65900
  if (metadataMatch !== void 0 && visualMatch !== void 0) {
65783
- return (0, import_neverthrow16.ok)(maxConfidence(metadataMatch.confidence, visualMatch.confidence));
65901
+ return (0, import_neverthrow17.ok)(maxConfidence(metadataMatch.confidence, visualMatch.confidence));
65784
65902
  }
65785
65903
  if (metadataMatch !== void 0) {
65786
- return (0, import_neverthrow16.ok)(metadataMatch.confidence);
65904
+ return (0, import_neverthrow17.ok)(metadataMatch.confidence);
65787
65905
  }
65788
65906
  if (visualMatch !== void 0) {
65789
- return (0, import_neverthrow16.ok)(visualMatch.confidence);
65907
+ return (0, import_neverthrow17.ok)(visualMatch.confidence);
65790
65908
  }
65791
- return (0, import_neverthrow16.err)({
65909
+ return (0, import_neverthrow17.err)({
65792
65910
  type: "UNMATCHED_OUTPUT_FINDING",
65793
65911
  flow: output.flow,
65794
65912
  description: output.description
@@ -65799,7 +65917,7 @@ function attachConfidence(output, pool) {
65799
65917
  }
65800
65918
  function mergeFindings(outputs, state) {
65801
65919
  if (outputs.length === 0) {
65802
- return (0, import_neverthrow16.ok)(state.accumulated);
65920
+ return (0, import_neverthrow17.ok)(state.accumulated);
65803
65921
  }
65804
65922
  const [head, ...tail] = outputs;
65805
65923
  return attachConfidence(head, state.pool).andThen(
@@ -65808,7 +65926,7 @@ function mergeFindings(outputs, state) {
65808
65926
  }
65809
65927
  function mergeDismissed(outputs, state) {
65810
65928
  if (outputs.length === 0) {
65811
- return (0, import_neverthrow16.ok)(state.accumulated);
65929
+ return (0, import_neverthrow17.ok)(state.accumulated);
65812
65930
  }
65813
65931
  const [head, ...tail] = outputs;
65814
65932
  return attachConfidence(head.finding, state.pool).andThen(
@@ -65907,7 +66025,7 @@ function runPipeline(input, context) {
65907
66025
  }
65908
66026
  function runConsolidator(input, config2) {
65909
66027
  if (input.metadataFindings.length === 0 && input.visualFindings.length === 0) {
65910
- return (0, import_neverthrow14.okAsync)({ findings: [], dismissed: [] });
66028
+ return (0, import_neverthrow15.okAsync)({ findings: [], dismissed: [] });
65911
66029
  }
65912
66030
  const start = Date.now();
65913
66031
  config2?.onEvent?.({ type: "STAGE_START", agent: "consolidator" });
@@ -65915,39 +66033,39 @@ function runConsolidator(input, config2) {
65915
66033
  }
65916
66034
 
65917
66035
  // ../../packages/pipeline/dist/index.js
65918
- var import_neverthrow36 = __toESM(require_index_cjs(), 1);
65919
66036
  var import_neverthrow37 = __toESM(require_index_cjs(), 1);
65920
- var import_promises18 = require("node:timers/promises");
66037
+ var import_neverthrow38 = __toESM(require_index_cjs(), 1);
66038
+ var import_promises19 = require("node:timers/promises");
65921
66039
 
65922
66040
  // ../../agents/explorer/dist/index.js
65923
- var import_neverthrow17 = __toESM(require_index_cjs(), 1);
65924
- var import_promises10 = require("node:timers/promises");
65925
66041
  var import_neverthrow18 = __toESM(require_index_cjs(), 1);
66042
+ var import_promises11 = require("node:timers/promises");
65926
66043
  var import_neverthrow19 = __toESM(require_index_cjs(), 1);
65927
- var import_promises11 = require("node:fs/promises");
65928
- var import_node_path4 = __toESM(require("node:path"), 1);
65929
66044
  var import_neverthrow20 = __toESM(require_index_cjs(), 1);
65930
- var import_node_path5 = __toESM(require("node:path"), 1);
65931
66045
  var import_promises12 = require("node:fs/promises");
65932
- var import_node_path6 = __toESM(require("node:path"), 1);
66046
+ var import_node_path4 = __toESM(require("node:path"), 1);
65933
66047
  var import_neverthrow21 = __toESM(require_index_cjs(), 1);
65934
- var import_node_child_process3 = require("node:child_process");
66048
+ var import_node_path5 = __toESM(require("node:path"), 1);
65935
66049
  var import_promises13 = require("node:fs/promises");
66050
+ var import_node_path6 = __toESM(require("node:path"), 1);
65936
66051
  var import_neverthrow22 = __toESM(require_index_cjs(), 1);
66052
+ var import_node_child_process3 = require("node:child_process");
66053
+ var import_promises14 = require("node:fs/promises");
65937
66054
  var import_neverthrow23 = __toESM(require_index_cjs(), 1);
66055
+ var import_neverthrow24 = __toESM(require_index_cjs(), 1);
65938
66056
  var import_node_child_process4 = require("node:child_process");
65939
66057
  var import_node_fs = require("node:fs");
65940
66058
  var import_node_path7 = __toESM(require("node:path"), 1);
65941
- var import_neverthrow24 = __toESM(require_index_cjs(), 1);
65942
66059
  var import_neverthrow25 = __toESM(require_index_cjs(), 1);
65943
- var import_promises14 = require("node:fs/promises");
65944
- var import_node_path8 = __toESM(require("node:path"), 1);
65945
66060
  var import_neverthrow26 = __toESM(require_index_cjs(), 1);
66061
+ var import_promises15 = require("node:fs/promises");
66062
+ var import_node_path8 = __toESM(require("node:path"), 1);
66063
+ var import_neverthrow27 = __toESM(require_index_cjs(), 1);
65946
66064
  var INTERRUPT_DRAIN_TIMEOUT_MS = 1e4;
65947
66065
  async function interruptOrTimeout(queryRunner) {
65948
- await Promise.race([queryRunner.interrupt(), (0, import_promises10.setTimeout)(INTERRUPT_DRAIN_TIMEOUT_MS)]);
66066
+ await Promise.race([queryRunner.interrupt(), (0, import_promises11.setTimeout)(INTERRUPT_DRAIN_TIMEOUT_MS)]);
65949
66067
  }
65950
- var safeInterruptOrTimeout = import_neverthrow18.ResultAsync.fromThrowable(
66068
+ var safeInterruptOrTimeout = import_neverthrow19.ResultAsync.fromThrowable(
65951
66069
  interruptOrTimeout,
65952
66070
  (error48) => error48
65953
66071
  );
@@ -66077,8 +66195,8 @@ function buildFinding({
66077
66195
  }
66078
66196
  var REPORT_FINDING_TOOL_NAME = "mcp__mobile-ios__report_finding";
66079
66197
  var REPORT_FINDING_DESCRIPTION = `Report a single finding the moment you observe it. Call this immediately when a finding condition is triggered \u2014 before taking any further actions. The current screen is captured automatically and attached to the finding. Do not pass screenshot paths. Do not batch findings for the end of the run.`;
66080
- var safeWriteFile = (0, import_neverthrow20.fromAsyncThrowable)(
66081
- import_promises11.writeFile,
66198
+ var safeWriteFile = (0, import_neverthrow21.fromAsyncThrowable)(
66199
+ import_promises12.writeFile,
66082
66200
  (cause) => ({ type: "WRITE_FAILED", cause })
66083
66201
  );
66084
66202
  async function persistScreenshot(params) {
@@ -66183,8 +66301,8 @@ function maybeEmitVisualStep({
66183
66301
  });
66184
66302
  return structuralHash;
66185
66303
  }
66186
- var safeWriteFile2 = (0, import_neverthrow21.fromAsyncThrowable)(
66187
- import_promises12.writeFile,
66304
+ var safeWriteFile2 = (0, import_neverthrow22.fromAsyncThrowable)(
66305
+ import_promises13.writeFile,
66188
66306
  (cause) => ({ type: "WRITE_FAILED", cause })
66189
66307
  );
66190
66308
  async function persistScreenshot2(params) {
@@ -66430,23 +66548,23 @@ function processMessage(message, state) {
66430
66548
  }
66431
66549
  if (message.type === "result") {
66432
66550
  if (message.subtype !== "success" && !state.timedOut.value && !state.aborted.value) {
66433
- return (0, import_neverthrow19.err)(message.errors.join("; "));
66551
+ return (0, import_neverthrow20.err)(message.errors.join("; "));
66434
66552
  }
66435
- return (0, import_neverthrow19.ok)(true);
66553
+ return (0, import_neverthrow20.ok)(true);
66436
66554
  }
66437
- return (0, import_neverthrow19.ok)(false);
66555
+ return (0, import_neverthrow20.ok)(false);
66438
66556
  }
66439
66557
  async function processMessages(queryRunner, state) {
66440
66558
  for await (const message of queryRunner) {
66441
66559
  const result = processMessage(message, state);
66442
66560
  if (result.isErr()) {
66443
- return (0, import_neverthrow19.err)(result.error);
66561
+ return (0, import_neverthrow20.err)(result.error);
66444
66562
  }
66445
66563
  if (result.value) {
66446
66564
  break;
66447
66565
  }
66448
66566
  }
66449
- return (0, import_neverthrow19.ok)(null);
66567
+ return (0, import_neverthrow20.ok)(null);
66450
66568
  }
66451
66569
  var MessageQueue = class {
66452
66570
  pending = [];
@@ -66602,18 +66720,18 @@ function setupQuery(config2) {
66602
66720
  }
66603
66721
  function awaitMessagesAndResolve({ queryRunner, state }, { cleanup: cleanup2, getOutput }) {
66604
66722
  const messagesPromise = processMessages(queryRunner, state);
66605
- return import_neverthrow17.ResultAsync.fromPromise(messagesPromise, String).andThen((innerResult) => {
66723
+ return import_neverthrow18.ResultAsync.fromPromise(messagesPromise, String).andThen((innerResult) => {
66606
66724
  cleanup2();
66607
66725
  if (innerResult.isErr()) {
66608
- return (0, import_neverthrow17.err)(innerResult.error);
66726
+ return (0, import_neverthrow18.err)(innerResult.error);
66609
66727
  }
66610
- return (0, import_neverthrow17.ok)(getOutput());
66728
+ return (0, import_neverthrow18.ok)(getOutput());
66611
66729
  }).orElse((sdkError) => {
66612
66730
  cleanup2();
66613
66731
  if (!state.timedOut.value && !state.aborted.value) {
66614
- return (0, import_neverthrow17.err)(sdkError);
66732
+ return (0, import_neverthrow18.err)(sdkError);
66615
66733
  }
66616
- return (0, import_neverthrow17.ok)(getOutput());
66734
+ return (0, import_neverthrow18.ok)(getOutput());
66617
66735
  });
66618
66736
  }
66619
66737
  function primeAndStartQuery({
@@ -66625,14 +66743,14 @@ function primeAndStartQuery({
66625
66743
  message: { role: "user", content: prompt },
66626
66744
  parent_tool_use_id: null
66627
66745
  });
66628
- return (0, import_neverthrow17.fromThrowable)(Qs, String)({ prompt: inputQueue, options: options2 });
66746
+ return (0, import_neverthrow18.fromThrowable)(Qs, String)({ prompt: inputQueue, options: options2 });
66629
66747
  }
66630
66748
  function executeQuery(context) {
66631
66749
  const { config: config2, setup } = context;
66632
66750
  const { inputQueue, state, linkedController } = setup;
66633
66751
  const queryRunnerResult = primeAndStartQuery(context);
66634
66752
  if (queryRunnerResult.isErr()) {
66635
- return (0, import_neverthrow17.errAsync)(queryRunnerResult.error);
66753
+ return (0, import_neverthrow18.errAsync)(queryRunnerResult.error);
66636
66754
  }
66637
66755
  const queryRunner = queryRunnerResult.value;
66638
66756
  const cleanup2 = startQueryLifecycle(config2, {
@@ -66655,8 +66773,8 @@ function collectAgentOutput(prompt, config2) {
66655
66773
  return runQuery(prompt, config2).mapErr((cause) => ({ type: "QUERY_FAILED", cause }));
66656
66774
  }
66657
66775
  function spawnRecorder(outputPath) {
66658
- const safeMkdirSync = (0, import_neverthrow24.fromThrowable)(import_node_fs.mkdirSync, (cause) => cause);
66659
- const safeSpawn2 = (0, import_neverthrow24.fromThrowable)(
66776
+ const safeMkdirSync = (0, import_neverthrow25.fromThrowable)(import_node_fs.mkdirSync, (cause) => cause);
66777
+ const safeSpawn2 = (0, import_neverthrow25.fromThrowable)(
66660
66778
  (command, arguments_) => (0, import_node_child_process4.spawn)(command, arguments_),
66661
66779
  (cause) => cause
66662
66780
  );
@@ -66683,7 +66801,7 @@ function earlyExitError(code) {
66683
66801
  function waitForRecordingStart(proc) {
66684
66802
  const { stderr } = proc;
66685
66803
  if (!stderr) {
66686
- return (0, import_neverthrow24.errAsync)({ type: "SPAWN_FAILED", cause: new RangeError("proc has no stderr pipe") });
66804
+ return (0, import_neverthrow25.errAsync)({ type: "SPAWN_FAILED", cause: new RangeError("proc has no stderr pipe") });
66687
66805
  }
66688
66806
  const { promise: promise2, resolve, reject } = Promise.withResolvers();
66689
66807
  proc.once("error", reject);
@@ -66699,7 +66817,7 @@ function waitForRecordingStart(proc) {
66699
66817
  resolve({ process: proc, startedAt: Date.now() });
66700
66818
  }
66701
66819
  });
66702
- return import_neverthrow24.ResultAsync.fromPromise(
66820
+ return import_neverthrow25.ResultAsync.fromPromise(
66703
66821
  promise2,
66704
66822
  (cause) => ({ type: "SPAWN_FAILED", cause })
66705
66823
  );
@@ -66707,7 +66825,7 @@ function waitForRecordingStart(proc) {
66707
66825
  function startRecording(outputPath) {
66708
66826
  const procOrError = spawnRecorder(outputPath);
66709
66827
  if (procOrError instanceof Error) {
66710
- return (0, import_neverthrow24.errAsync)({ type: "SPAWN_FAILED", cause: procOrError });
66828
+ return (0, import_neverthrow25.errAsync)({ type: "SPAWN_FAILED", cause: procOrError });
66711
66829
  }
66712
66830
  return waitForRecordingStart(procOrError);
66713
66831
  }
@@ -66722,7 +66840,7 @@ function stopRecording(handle) {
66722
66840
  } else {
66723
66841
  resolve(true);
66724
66842
  }
66725
- return import_neverthrow24.ResultAsync.fromPromise(
66843
+ return import_neverthrow25.ResultAsync.fromPromise(
66726
66844
  promise2,
66727
66845
  (cause) => ({ type: "STOP_FAILED", cause })
66728
66846
  );
@@ -66735,7 +66853,7 @@ function runWithRecording(handle, collectOutput) {
66735
66853
  return collectOutput().andThen(
66736
66854
  ({ findings, snapshots }) => stopRecording(handle).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
66737
66855
  ).orElse(
66738
- (error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0, import_neverthrow23.errAsync)(error48)).orElse(() => (0, import_neverthrow23.errAsync)(error48))
66856
+ (error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0, import_neverthrow24.errAsync)(error48)).orElse(() => (0, import_neverthrow24.errAsync)(error48))
66739
66857
  );
66740
66858
  }
66741
66859
  function startAndRun(params) {
@@ -67093,29 +67211,29 @@ var INLINE_ASSERTION_DELIMITER = " \u2192 ";
67093
67211
  var NUMBERED_STEP_PREFIX = /^\d+\.\s+/;
67094
67212
  function parseTagsValue(value) {
67095
67213
  if (!value.startsWith("[") || !value.endsWith("]")) {
67096
- return (0, import_neverthrow25.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
67214
+ return (0, import_neverthrow26.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
67097
67215
  }
67098
- return (0, import_neverthrow25.ok)(
67216
+ return (0, import_neverthrow26.ok)(
67099
67217
  value.slice(1, -1).split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0)
67100
67218
  );
67101
67219
  }
67102
67220
  function parseTimeoutValue(value) {
67103
67221
  const parsed = Number(value);
67104
67222
  if (Number.isNaN(parsed) || parsed <= 0) {
67105
- return (0, import_neverthrow25.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
67223
+ return (0, import_neverthrow26.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
67106
67224
  }
67107
- return (0, import_neverthrow25.ok)(parsed);
67225
+ return (0, import_neverthrow26.ok)(parsed);
67108
67226
  }
67109
67227
  function parseFrontmatterLine(line) {
67110
67228
  const colonIndex = line.indexOf(":");
67111
67229
  if (colonIndex === -1) {
67112
- return (0, import_neverthrow25.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
67230
+ return (0, import_neverthrow26.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
67113
67231
  }
67114
67232
  const key = line.slice(0, colonIndex).trim();
67115
67233
  const value = line.slice(colonIndex + 1).trim();
67116
67234
  switch (key) {
67117
67235
  case "description": {
67118
- return (0, import_neverthrow25.ok)({ description: value });
67236
+ return (0, import_neverthrow26.ok)({ description: value });
67119
67237
  }
67120
67238
  case "tags": {
67121
67239
  return parseTagsValue(value).map((tags) => ({ tags }));
@@ -67124,10 +67242,10 @@ function parseFrontmatterLine(line) {
67124
67242
  return parseTimeoutValue(value).map((timeout) => ({ timeout }));
67125
67243
  }
67126
67244
  case "scenarioId": {
67127
- return (0, import_neverthrow25.ok)(value.length > 0 ? { scenarioId: value } : {});
67245
+ return (0, import_neverthrow26.ok)(value.length > 0 ? { scenarioId: value } : {});
67128
67246
  }
67129
67247
  default: {
67130
- return (0, import_neverthrow25.ok)({});
67248
+ return (0, import_neverthrow26.ok)({});
67131
67249
  }
67132
67250
  }
67133
67251
  }
@@ -67150,18 +67268,18 @@ function mergePartials(partials) {
67150
67268
  }
67151
67269
  function combineFrontmatterLines(lines) {
67152
67270
  const lineResults = lines.filter((line) => line.trim().length > 0).map((line) => parseFrontmatterLine(line));
67153
- return import_neverthrow25.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
67271
+ return import_neverthrow26.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
67154
67272
  }
67155
67273
  function extractFrontmatter(content) {
67156
67274
  const trimmed = content.trimStart();
67157
67275
  if (!trimmed.startsWith(FRONTMATTER_FENCE)) {
67158
- return (0, import_neverthrow25.ok)({ frontmatter: emptyFrontmatter(), body: content });
67276
+ return (0, import_neverthrow26.ok)({ frontmatter: emptyFrontmatter(), body: content });
67159
67277
  }
67160
67278
  const afterOpenFence = trimmed.slice(FRONTMATTER_FENCE.length);
67161
67279
  const closeIndex = afterOpenFence.indexOf(`
67162
67280
  ${FRONTMATTER_FENCE}`);
67163
67281
  if (closeIndex === -1) {
67164
- return (0, import_neverthrow25.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
67282
+ return (0, import_neverthrow26.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
67165
67283
  }
67166
67284
  const rawFrontmatter = afterOpenFence.slice(0, closeIndex);
67167
67285
  const body = afterOpenFence.slice(closeIndex + FRONTMATTER_FENCE.length + 1);
@@ -67203,13 +67321,13 @@ function parseTestSpec(name, content) {
67203
67321
  const sections = splitIntoSections(body);
67204
67322
  const setup = sections.Setup;
67205
67323
  if (setup === void 0) {
67206
- return (0, import_neverthrow25.err)({ type: "MISSING_SETUP_SECTION" });
67324
+ return (0, import_neverthrow26.err)({ type: "MISSING_SETUP_SECTION" });
67207
67325
  }
67208
67326
  const stepsSection = sections.Steps;
67209
67327
  if (stepsSection === void 0) {
67210
- return (0, import_neverthrow25.err)({ type: "MISSING_STEPS_SECTION" });
67328
+ return (0, import_neverthrow26.err)({ type: "MISSING_STEPS_SECTION" });
67211
67329
  }
67212
- return (0, import_neverthrow25.ok)({
67330
+ return (0, import_neverthrow26.ok)({
67213
67331
  name,
67214
67332
  frontmatter,
67215
67333
  setup,
@@ -67254,25 +67372,25 @@ function direntToSpecEntry(directory, entry) {
67254
67372
  return [];
67255
67373
  }
67256
67374
  function scanDirectory(directory) {
67257
- const safeReaddir3 = (0, import_neverthrow26.fromAsyncThrowable)(
67258
- async () => (0, import_promises14.readdir)(directory, { withFileTypes: true }),
67375
+ const safeReaddir3 = (0, import_neverthrow27.fromAsyncThrowable)(
67376
+ async () => (0, import_promises15.readdir)(directory, { withFileTypes: true }),
67259
67377
  (cause) => ({ type: "DIR_READ_FAILED", dir: directory, cause })
67260
67378
  );
67261
- return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow26.okAsync)([]) : (0, import_neverthrow26.errAsync)(error48)).map(
67379
+ return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow27.okAsync)([]) : (0, import_neverthrow27.errAsync)(error48)).map(
67262
67380
  (entries) => entries.flatMap((entry) => direntToSpecEntry(directory, entry))
67263
67381
  );
67264
67382
  }
67265
67383
  function readEntries(entries) {
67266
- return import_neverthrow26.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
67384
+ return import_neverthrow27.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
67267
67385
  (results) => results.flat()
67268
67386
  );
67269
67387
  }
67270
67388
  function readEntry(entry) {
67271
- const safeReadFile6 = (0, import_neverthrow26.fromAsyncThrowable)(
67272
- async () => (0, import_promises14.readFile)(entry.path, "utf8"),
67389
+ const safeReadFile6 = (0, import_neverthrow27.fromAsyncThrowable)(
67390
+ async () => (0, import_promises15.readFile)(entry.path, "utf8"),
67273
67391
  (cause) => ({ type: "FILE_READ_FAILED", path: entry.path, cause })
67274
67392
  );
67275
- return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow26.errAsync)(error48) : (0, import_neverthrow26.okAsync)([]));
67393
+ return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow27.errAsync)(error48) : (0, import_neverthrow27.okAsync)([]));
67276
67394
  }
67277
67395
  function specNameFromPath(filePath) {
67278
67396
  const parts = filePath.split("/");
@@ -67304,7 +67422,7 @@ function buildPrompt2(safeConfig, specs) {
67304
67422
  });
67305
67423
  }
67306
67424
  function parseSpecs(resolvedSpecs) {
67307
- return import_neverthrow22.Result.combine(
67425
+ return import_neverthrow23.Result.combine(
67308
67426
  resolvedSpecs.map(
67309
67427
  (spec) => parseTestSpec(spec.name, spec.content).mapErr(
67310
67428
  (cause) => ({ type: "SPEC_PARSE_FAILED", specName: spec.name, cause })
@@ -67362,7 +67480,7 @@ function collectAndFinalize({
67362
67480
  }
67363
67481
  function resolveAndParseSpecs(safeConfig) {
67364
67482
  if (safeConfig.mode === "freestyle") {
67365
- return (0, import_neverthrow22.okAsync)([]);
67483
+ return (0, import_neverthrow23.okAsync)([]);
67366
67484
  }
67367
67485
  return resolveSpecs(safeConfig).mapErr((cause) => ({ type: "SPEC_RESOLVE_FAILED", cause })).andThen((specs) => parseSpecs(specs));
67368
67486
  }
@@ -67393,33 +67511,33 @@ function runExplorer(config2) {
67393
67511
  date: date5
67394
67512
  });
67395
67513
  if (runPathsResult.isErr()) {
67396
- return (0, import_neverthrow22.errAsync)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
67514
+ return (0, import_neverthrow23.errAsync)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
67397
67515
  }
67398
67516
  const runPaths = runPathsResult.value;
67399
67517
  if (config2.signal?.aborted) {
67400
- return (0, import_neverthrow22.okAsync)(toArtifacts({ findings: [], snapshots: [] }, runPaths));
67518
+ return (0, import_neverthrow23.okAsync)(toArtifacts({ findings: [], snapshots: [] }, runPaths));
67401
67519
  }
67402
67520
  const safeConfig = buildSafeConfig(config2, runPaths);
67403
67521
  safeConfig.onEvent?.({ type: "STAGE_START", agent: "explorer" });
67404
- return import_neverthrow22.ResultAsync.fromSafePromise(
67405
- (0, import_promises13.mkdir)(runPaths.screenshotsDir, { recursive: true }).catch(() => null)
67522
+ return import_neverthrow23.ResultAsync.fromSafePromise(
67523
+ (0, import_promises14.mkdir)(runPaths.screenshotsDir, { recursive: true }).catch(() => null)
67406
67524
  ).andThen(() => runPipeline2({ safeConfig, runPaths, start }));
67407
67525
  }
67408
67526
 
67409
67527
  // ../../packages/pipeline/dist/index.js
67410
- var import_neverthrow38 = __toESM(require_index_cjs(), 1);
67528
+ var import_neverthrow39 = __toESM(require_index_cjs(), 1);
67411
67529
 
67412
67530
  // ../../agents/inspector/dist/index.js
67413
- var import_neverthrow27 = __toESM(require_index_cjs(), 1);
67414
- var import_promises15 = require("node:fs/promises");
67415
67531
  var import_neverthrow28 = __toESM(require_index_cjs(), 1);
67532
+ var import_promises16 = require("node:fs/promises");
67416
67533
  var import_neverthrow29 = __toESM(require_index_cjs(), 1);
67417
67534
  var import_neverthrow30 = __toESM(require_index_cjs(), 1);
67418
67535
  var import_neverthrow31 = __toESM(require_index_cjs(), 1);
67419
- var import_sharp2 = __toESM(require("sharp"), 1);
67420
67536
  var import_neverthrow32 = __toESM(require_index_cjs(), 1);
67537
+ var import_sharp2 = __toESM(require("sharp"), 1);
67421
67538
  var import_neverthrow33 = __toESM(require_index_cjs(), 1);
67422
- var import_promises16 = require("node:fs/promises");
67539
+ var import_neverthrow34 = __toESM(require_index_cjs(), 1);
67540
+ var import_promises17 = require("node:fs/promises");
67423
67541
  var import_node_path9 = __toESM(require("node:path"), 1);
67424
67542
 
67425
67543
  // ../../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs
@@ -70047,7 +70165,7 @@ var jsYaml = {
70047
70165
  };
70048
70166
 
70049
70167
  // ../../agents/inspector/dist/index.js
70050
- var import_neverthrow34 = __toESM(require_index_cjs(), 1);
70168
+ var import_neverthrow35 = __toESM(require_index_cjs(), 1);
70051
70169
  var MS_PER_DAY = 864e5;
70052
70170
  function dequeue(context, current) {
70053
70171
  if (current.remainingQueue.length === 0 || context.activeCount + current.events.length >= context.maxConcurrency) {
@@ -70163,7 +70281,7 @@ function matchArtboardName(name, artboardNames) {
70163
70281
  const lower = name.toLowerCase();
70164
70282
  return artboardNames.find((artboard) => artboard.toLowerCase() === lower);
70165
70283
  }
70166
- var safeJsonParse3 = (0, import_neverthrow30.fromThrowable)(JSON.parse, (cause) => ({ cause }));
70284
+ var safeJsonParse3 = (0, import_neverthrow31.fromThrowable)(JSON.parse, (cause) => ({ cause }));
70167
70285
  function isRawFindingShape(value, isValidSeverity2) {
70168
70286
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
70169
70287
  return false;
@@ -70184,15 +70302,15 @@ function mapRawFinding(item, mappers) {
70184
70302
  }
70185
70303
  function validateFindingArray(parsed, context) {
70186
70304
  if (!Array.isArray(parsed)) {
70187
- return (0, import_neverthrow30.err)({ type: "NOT_AN_ARRAY", raw: context.raw });
70305
+ return (0, import_neverthrow31.err)({ type: "NOT_AN_ARRAY", raw: context.raw });
70188
70306
  }
70189
70307
  const invalidIndex = parsed.findIndex(
70190
70308
  (item) => !isRawFindingShape(item, context.isValidSeverity)
70191
70309
  );
70192
70310
  if (invalidIndex !== -1) {
70193
- return (0, import_neverthrow30.err)({ type: "INVALID_FINDING", raw: context.raw, index: invalidIndex });
70311
+ return (0, import_neverthrow31.err)({ type: "INVALID_FINDING", raw: context.raw, index: invalidIndex });
70194
70312
  }
70195
- return (0, import_neverthrow30.ok)(parsed);
70313
+ return (0, import_neverthrow31.ok)(parsed);
70196
70314
  }
70197
70315
  function parseFindings({
70198
70316
  raw,
@@ -70236,7 +70354,7 @@ async function downscaleBuffer(buffer) {
70236
70354
  return (0, import_sharp2.default)(buffer).resize({ width: targetWidth }).toBuffer();
70237
70355
  }
70238
70356
  function downscale(buffer) {
70239
- return (0, import_neverthrow31.fromAsyncThrowable)(
70357
+ return (0, import_neverthrow32.fromAsyncThrowable)(
70240
70358
  downscaleBuffer,
70241
70359
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70242
70360
  )(buffer);
@@ -70262,7 +70380,7 @@ async function fetchClaudeText({
70262
70380
  return block?.type === "text" ? block.text : "";
70263
70381
  }
70264
70382
  function callClaude(options2) {
70265
- return (0, import_neverthrow29.fromAsyncThrowable)(
70383
+ return (0, import_neverthrow30.fromAsyncThrowable)(
70266
70384
  fetchClaudeText,
70267
70385
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70268
70386
  )(options2);
@@ -70289,12 +70407,12 @@ async function fetchResolveName({
70289
70407
  }
70290
70408
  function resolveArtboard(screenshot, artboardNames) {
70291
70409
  if (artboardNames.length === 0) {
70292
- return (0, import_neverthrow29.okAsync)(void 0);
70410
+ return (0, import_neverthrow30.okAsync)(void 0);
70293
70411
  }
70294
70412
  const anthropic = new Anthropic();
70295
70413
  return downscale(screenshot).andThen((scaled) => {
70296
70414
  const screenshotBase64 = scaled.toString("base64");
70297
- return (0, import_neverthrow29.fromAsyncThrowable)(
70415
+ return (0, import_neverthrow30.fromAsyncThrowable)(
70298
70416
  fetchResolveName,
70299
70417
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70300
70418
  )({ anthropic, screenshotBase64, artboardNames }).map(
@@ -70407,7 +70525,7 @@ Artboards: ${artboardNames.join(", ")}`
70407
70525
  }
70408
70526
  ];
70409
70527
  }
70410
- var safeJsonParse22 = (0, import_neverthrow33.fromThrowable)(JSON.parse, (cause) => ({ cause }));
70528
+ var safeJsonParse22 = (0, import_neverthrow34.fromThrowable)(JSON.parse, (cause) => ({ cause }));
70411
70529
  function resolveCandidateNames(parsed, artboardNames) {
70412
70530
  const matched = parsed.filter((name) => typeof name === "string").map((name) => {
70413
70531
  const lower = name.toLowerCase();
@@ -70419,7 +70537,7 @@ function parseCandidateNames(raw, artboardNames) {
70419
70537
  return safeJsonParse22(raw).mapErr(
70420
70538
  ({ cause }) => ({ type: "CANDIDATES_MALFORMED_JSON", raw, cause })
70421
70539
  ).andThen(
70422
- (parsed) => Array.isArray(parsed) ? (0, import_neverthrow33.ok)(resolveCandidateNames(parsed, artboardNames)) : (0, import_neverthrow33.err)({ type: "CANDIDATES_NOT_AN_ARRAY", raw })
70540
+ (parsed) => Array.isArray(parsed) ? (0, import_neverthrow34.ok)(resolveCandidateNames(parsed, artboardNames)) : (0, import_neverthrow34.err)({ type: "CANDIDATES_NOT_AN_ARRAY", raw })
70423
70541
  );
70424
70542
  }
70425
70543
  var MODEL22 = "claude-sonnet-4-6";
@@ -70471,18 +70589,18 @@ function toCandidateNames(text, artboardNames) {
70471
70589
  async function downscaleAll(buffers) {
70472
70590
  return Promise.all(buffers.map(async (buf) => downscaleBuffer(buf)));
70473
70591
  }
70474
- var downscaleAllBuffers = (0, import_neverthrow32.fromAsyncThrowable)(
70592
+ var downscaleAllBuffers = (0, import_neverthrow33.fromAsyncThrowable)(
70475
70593
  downscaleAll,
70476
70594
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70477
70595
  );
70478
70596
  function findCandidates(screenshot, artboardNames) {
70479
70597
  if (artboardNames.length === 0) {
70480
- return (0, import_neverthrow32.okAsync)([]);
70598
+ return (0, import_neverthrow33.okAsync)([]);
70481
70599
  }
70482
70600
  const anthropic = new Anthropic();
70483
70601
  return downscale(screenshot).andThen((scaled) => {
70484
70602
  const screenshotBase64 = scaled.toString("base64");
70485
- return (0, import_neverthrow32.fromAsyncThrowable)(
70603
+ return (0, import_neverthrow33.fromAsyncThrowable)(
70486
70604
  fetchCandidatesText,
70487
70605
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70488
70606
  )({ anthropic, screenshotBase64, artboardNames }).andThen(
@@ -70496,7 +70614,7 @@ function compareWithDesignContext(screenshot, artboards) {
70496
70614
  const screenshotBase64 = scaledScreenshot.toString("base64");
70497
70615
  return downscaleAllBuffers(artboards).andThen((scaledArtboards) => {
70498
70616
  const artboardBase64s = scaledArtboards.map((buf) => buf.toString("base64"));
70499
- return (0, import_neverthrow32.fromAsyncThrowable)(
70617
+ return (0, import_neverthrow33.fromAsyncThrowable)(
70500
70618
  fetchDesignContextText,
70501
70619
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
70502
70620
  )({ anthropic, screenshotBase64, artboardBase64s }).andThen(toDesignContextFindings);
@@ -70730,8 +70848,8 @@ async function initArtboardNames({ designStore, config: config2, state }) {
70730
70848
  );
70731
70849
  }
70732
70850
  function readScreenshot(screenshotPath, stepIndex) {
70733
- return import_neverthrow28.ResultAsync.fromThrowable(
70734
- import_promises15.readFile,
70851
+ return import_neverthrow29.ResultAsync.fromThrowable(
70852
+ import_promises16.readFile,
70735
70853
  (cause) => ({ type: "SCREENSHOT_READ_FAILED", stepIndex, cause })
70736
70854
  )(screenshotPath);
70737
70855
  }
@@ -70803,7 +70921,7 @@ function buildInspector(state, context) {
70803
70921
  const { promise: promise2, resolve } = Promise.withResolvers();
70804
70922
  state.setResolve(resolve);
70805
70923
  applyTryResolve(state);
70806
- return (0, import_neverthrow27.fromSafePromise)(promise2);
70924
+ return (0, import_neverthrow28.fromSafePromise)(promise2);
70807
70925
  }
70808
70926
  };
70809
70927
  }
@@ -70852,14 +70970,14 @@ function parseMeta(raw) {
70852
70970
  return {};
70853
70971
  }
70854
70972
  async function readAndParseSidecar(sidecarPath) {
70855
- const raw = await (0, import_promises16.readFile)(sidecarPath, "utf8");
70973
+ const raw = await (0, import_promises17.readFile)(sidecarPath, "utf8");
70856
70974
  return parseMeta(raw);
70857
70975
  }
70858
70976
  function readSidecarFile(sidecarPath) {
70859
- return (0, import_neverthrow34.fromAsyncThrowable)(
70977
+ return (0, import_neverthrow35.fromAsyncThrowable)(
70860
70978
  readAndParseSidecar,
70861
70979
  () => ({})
70862
- )(sidecarPath).orElse(() => (0, import_neverthrow34.okAsync)({}));
70980
+ )(sidecarPath).orElse(() => (0, import_neverthrow35.okAsync)({}));
70863
70981
  }
70864
70982
  function isEnoent(error48) {
70865
70983
  return error48?.code === "ENOENT";
@@ -70868,13 +70986,13 @@ function wrapFsError(cause) {
70868
70986
  return { type: "FS_ERROR", cause };
70869
70987
  }
70870
70988
  function toFsError(fsError) {
70871
- return (0, import_neverthrow34.errAsync)(fsError);
70989
+ return (0, import_neverthrow35.errAsync)(fsError);
70872
70990
  }
70873
70991
  function missingBuffer() {
70874
- return (0, import_neverthrow34.okAsync)(void 0);
70992
+ return (0, import_neverthrow35.okAsync)(void 0);
70875
70993
  }
70876
70994
  function missingArtboard() {
70877
- return (0, import_neverthrow34.okAsync)(void 0);
70995
+ return (0, import_neverthrow35.okAsync)(void 0);
70878
70996
  }
70879
70997
  var FsDesignStore = class {
70880
70998
  designsDirectory;
@@ -70882,12 +71000,12 @@ var FsDesignStore = class {
70882
71000
  this.designsDirectory = designsDirectory;
70883
71001
  }
70884
71002
  listArtboards() {
70885
- return (0, import_neverthrow34.fromAsyncThrowable)(
70886
- import_promises16.readdir,
71003
+ return (0, import_neverthrow35.fromAsyncThrowable)(
71004
+ import_promises17.readdir,
70887
71005
  wrapFsError
70888
71006
  )(this.designsDirectory).orElse((fsError) => {
70889
71007
  if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
70890
- return (0, import_neverthrow34.okAsync)([]);
71008
+ return (0, import_neverthrow35.okAsync)([]);
70891
71009
  }
70892
71010
  return toFsError(fsError);
70893
71011
  }).map(
@@ -70897,8 +71015,8 @@ var FsDesignStore = class {
70897
71015
  getArtboard(filename) {
70898
71016
  const pngPath = import_node_path9.default.join(this.designsDirectory, `${filename}.png`);
70899
71017
  const sidecarPath = import_node_path9.default.join(this.designsDirectory, `${filename}.meta.yaml`);
70900
- return (0, import_neverthrow34.fromAsyncThrowable)(
70901
- import_promises16.readFile,
71018
+ return (0, import_neverthrow35.fromAsyncThrowable)(
71019
+ import_promises17.readFile,
70902
71020
  wrapFsError
70903
71021
  )(pngPath).orElse((fsError) => {
70904
71022
  if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
@@ -70918,13 +71036,13 @@ var FsDesignStore = class {
70918
71036
 
70919
71037
  // ../../packages/pipeline/dist/index.js
70920
71038
  var import_node_fs2 = require("node:fs");
70921
- var import_neverthrow39 = __toESM(require_index_cjs(), 1);
70922
71039
  var import_neverthrow40 = __toESM(require_index_cjs(), 1);
70923
71040
  var import_neverthrow41 = __toESM(require_index_cjs(), 1);
70924
- var import_node_fs3 = require("node:fs");
70925
71041
  var import_neverthrow42 = __toESM(require_index_cjs(), 1);
70926
- var import_node_fs4 = require("node:fs");
71042
+ var import_node_fs3 = require("node:fs");
70927
71043
  var import_neverthrow43 = __toESM(require_index_cjs(), 1);
71044
+ var import_node_fs4 = require("node:fs");
71045
+ var import_neverthrow44 = __toESM(require_index_cjs(), 1);
70928
71046
  function createDefaultMcpServers(udid) {
70929
71047
  return {
70930
71048
  "mobile-ios": createMobileIosServer(udid)
@@ -70940,10 +71058,10 @@ function attemptRetry(options2) {
70940
71058
  const { factory, config: config2, delayFunction, onRetry, attempt } = options2;
70941
71059
  return factory().orElse((error48) => {
70942
71060
  if (attempt >= config2.maxAttempts) {
70943
- return (0, import_neverthrow37.errAsync)(error48);
71061
+ return (0, import_neverthrow38.errAsync)(error48);
70944
71062
  }
70945
71063
  const delay = config2.baseDelayMs * Math.pow(2, attempt - 1);
70946
- return import_neverthrow37.ResultAsync.fromPromise(
71064
+ return import_neverthrow38.ResultAsync.fromPromise(
70947
71065
  (onRetry?.({ attempt, maxAttempts: config2.maxAttempts, delayMs: delay, error: error48 }), delayFunction(delay)),
70948
71066
  () => error48
70949
71067
  ).andThen(
@@ -70963,7 +71081,7 @@ function withRetry(factory, options2) {
70963
71081
  var CONSOLIDATOR_AGENT = "consolidator";
70964
71082
  function analyserFallback(artifacts, onEvent) {
70965
71083
  onEvent?.({ type: "AGENT_FAILED_NON_CRITICAL", agent: "analyser", attempts: RETRY_MAX_ATTEMPTS });
70966
- return (0, import_neverthrow36.okAsync)(artifacts.findings);
71084
+ return (0, import_neverthrow37.okAsync)(artifacts.findings);
70967
71085
  }
70968
71086
  function runAnalyserWithRetry(params) {
70969
71087
  const { artifacts, config: config2, onEvent } = params;
@@ -70973,7 +71091,7 @@ function runAnalyserWithRetry(params) {
70973
71091
  ),
70974
71092
  {
70975
71093
  config: { maxAttempts: RETRY_MAX_ATTEMPTS, baseDelayMs: RETRY_BASE_DELAY_MS },
70976
- delayFunction: import_promises17.setTimeout,
71094
+ delayFunction: import_promises18.setTimeout,
70977
71095
  onRetry: ({ attempt, maxAttempts, delayMs, error: error48 }) => {
70978
71096
  onEvent?.({
70979
71097
  type: "AGENT_RETRY",
@@ -70993,7 +71111,7 @@ function resolveVisualFindings({
70993
71111
  onEvent
70994
71112
  }) {
70995
71113
  if (config2.analyser === void 0 || config2.signal?.aborted) {
70996
- return (0, import_neverthrow36.okAsync)(artifacts.findings);
71114
+ return (0, import_neverthrow37.okAsync)(artifacts.findings);
70997
71115
  }
70998
71116
  return runAnalyserWithRetry({ artifacts, config: config2, onEvent });
70999
71117
  }
@@ -71003,7 +71121,7 @@ function unmergedFallback(allFindings, onEvent) {
71003
71121
  agent: CONSOLIDATOR_AGENT,
71004
71122
  message: "Consolidation failed, returning unmerged findings"
71005
71123
  });
71006
- return (0, import_neverthrow36.okAsync)({ findings: allFindings, dismissed: [] });
71124
+ return (0, import_neverthrow37.okAsync)({ findings: allFindings, dismissed: [] });
71007
71125
  }
71008
71126
  function mergeWithFallback(options2) {
71009
71127
  const {
@@ -71030,7 +71148,7 @@ function consolidate(options2) {
71030
71148
  const { artifacts, inspectorFindings, runId, dismissals, config: config2, consolidatorConfig, onEvent } = options2;
71031
71149
  return resolveVisualFindings({ artifacts, config: config2, onEvent }).andThen((visualFindings) => {
71032
71150
  if (config2.signal?.aborted) {
71033
- return (0, import_neverthrow36.okAsync)({ findings: artifacts.findings, dismissed: [] });
71151
+ return (0, import_neverthrow37.okAsync)({ findings: artifacts.findings, dismissed: [] });
71034
71152
  }
71035
71153
  return mergeWithFallback({
71036
71154
  artifacts,
@@ -71127,14 +71245,14 @@ function runExplorerWithTeardown(explorerConfig, udid) {
71127
71245
  return runExplorer(explorerConfig).mapErr((cause) => ({ type: "EXPLORER_FAILED", cause })).andThen(
71128
71246
  (artifacts) => disableTouchIndicators(udid).mapErr(toSimulatorError).map(() => artifacts)
71129
71247
  ).orElse(
71130
- (error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow38.errAsync)(error48)).orElse(() => (0, import_neverthrow38.errAsync)(error48))
71248
+ (error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow39.errAsync)(error48)).orElse(() => (0, import_neverthrow39.errAsync)(error48))
71131
71249
  );
71132
71250
  }
71133
71251
  function runExplorerWithRetry(options2) {
71134
71252
  const { explorerConfig, udid, onEvent } = options2;
71135
71253
  return withRetry(() => runExplorerWithTeardown(explorerConfig, udid), {
71136
71254
  config: { maxAttempts: RETRY_MAX_ATTEMPTS, baseDelayMs: RETRY_BASE_DELAY_MS },
71137
- delayFunction: import_promises18.setTimeout,
71255
+ delayFunction: import_promises19.setTimeout,
71138
71256
  onRetry: ({ attempt, maxAttempts, delayMs, error: error48 }) => {
71139
71257
  onEvent?.({
71140
71258
  type: "AGENT_RETRY",
@@ -71153,12 +71271,12 @@ async function drainAfterExplorer(options2) {
71153
71271
  inspector?.close();
71154
71272
  const inspectorFindings = inspector ? await collectInspectorFindings({ inspector, onEvent, totalSteps: enqueuedCount.value }) : [];
71155
71273
  if (explorerResult.isErr()) {
71156
- return (0, import_neverthrow38.err)(explorerResult.error);
71274
+ return (0, import_neverthrow39.err)(explorerResult.error);
71157
71275
  }
71158
- return (0, import_neverthrow38.ok)({ artifacts: explorerResult.value, inspectorFindings });
71276
+ return (0, import_neverthrow39.ok)({ artifacts: explorerResult.value, inspectorFindings });
71159
71277
  }
71160
71278
  function runExplorerAndDrain(options2) {
71161
- return import_neverthrow38.ResultAsync.fromSafePromise(drainAfterExplorer(options2)).andThen((result) => result);
71279
+ return import_neverthrow39.ResultAsync.fromSafePromise(drainAfterExplorer(options2)).andThen((result) => result);
71162
71280
  }
71163
71281
  function filterByConfidence(findings, threshold) {
71164
71282
  return {
@@ -71166,7 +71284,7 @@ function filterByConfidence(findings, threshold) {
71166
71284
  dropped: findings.filter((finding) => !meetsConfidenceThreshold(finding.confidence, threshold)).map((finding) => ({ finding, reason: "low-confidence" }))
71167
71285
  };
71168
71286
  }
71169
- var writeOutputFile = (0, import_neverthrow39.fromThrowable)(
71287
+ var writeOutputFile = (0, import_neverthrow40.fromThrowable)(
71170
71288
  (params) => {
71171
71289
  const { findingsPath, outputDirectory, json: json3 } = params;
71172
71290
  (0, import_node_fs2.mkdirSync)(outputDirectory, { recursive: true });
@@ -71212,8 +71330,8 @@ function buildExplorerConfig({
71212
71330
  function getDismissalsPathOverride() {
71213
71331
  return process.env.QA_DISMISSALS_PATH;
71214
71332
  }
71215
- var safeReadFile = (0, import_neverthrow42.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
71216
- var safeParseJson2 = (0, import_neverthrow42.fromThrowable)(JSON.parse);
71333
+ var safeReadFile = (0, import_neverthrow43.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
71334
+ var safeParseJson2 = (0, import_neverthrow43.fromThrowable)(JSON.parse);
71217
71335
  function isEnoent2(error48) {
71218
71336
  if (!(error48 instanceof Error)) {
71219
71337
  return false;
@@ -71225,19 +71343,19 @@ function loadDismissals(filePath) {
71225
71343
  const readResult = safeReadFile(filePath);
71226
71344
  if (readResult.isErr()) {
71227
71345
  if (isEnoent2(readResult.error)) {
71228
- return (0, import_neverthrow42.ok)([]);
71346
+ return (0, import_neverthrow43.ok)([]);
71229
71347
  }
71230
- return (0, import_neverthrow42.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
71348
+ return (0, import_neverthrow43.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
71231
71349
  }
71232
71350
  return safeParseJson2(readResult.value).mapErr((cause) => ({ type: "DISMISSALS_LOAD_FAILED", cause })).andThen((data) => {
71233
71351
  const store = data;
71234
71352
  if (!Array.isArray(store.dismissed)) {
71235
- return (0, import_neverthrow42.err)({
71353
+ return (0, import_neverthrow43.err)({
71236
71354
  type: "DISMISSALS_LOAD_FAILED",
71237
71355
  cause: "invalid shape: dismissed is not an array"
71238
71356
  });
71239
71357
  }
71240
- return (0, import_neverthrow42.ok)(store.dismissed);
71358
+ return (0, import_neverthrow43.ok)(store.dismissed);
71241
71359
  });
71242
71360
  }
71243
71361
  var ISO_DATE_LENGTH2 = 10;
@@ -71247,7 +71365,7 @@ function computeNextRunId(entries) {
71247
71365
  const max = parsed.length === 0 ? 0 : Math.max(...parsed);
71248
71366
  return String(max + 1).padStart(RUN_ID_PAD_LENGTH, "0");
71249
71367
  }
71250
- var safeReaddirSync = (0, import_neverthrow43.fromThrowable)((directory) => (0, import_node_fs4.readdirSync)(directory));
71368
+ var safeReaddirSync = (0, import_neverthrow44.fromThrowable)((directory) => (0, import_node_fs4.readdirSync)(directory));
71251
71369
  function nextRunId(outputDirectory, date5) {
71252
71370
  const entries = safeReaddirSync(`${outputDirectory}/${date5}`).unwrapOr([]);
71253
71371
  return computeNextRunId(entries);
@@ -71259,15 +71377,15 @@ function resolvePipelineConfig({
71259
71377
  const runId = config2.runId ?? nextRunId(config2.outputDir, date5);
71260
71378
  const runPathsResult = resolveRunPaths({ outputDirectory: config2.outputDir, runId, date: date5 });
71261
71379
  if (runPathsResult.isErr()) {
71262
- return (0, import_neverthrow41.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
71380
+ return (0, import_neverthrow42.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
71263
71381
  }
71264
71382
  const dismissalsResult = loadDismissals(
71265
71383
  dismissalsPath(config2.outputDir, getDismissalsPathOverride())
71266
71384
  );
71267
71385
  if (dismissalsResult.isErr()) {
71268
- return (0, import_neverthrow41.err)(dismissalsResult.error);
71386
+ return (0, import_neverthrow42.err)(dismissalsResult.error);
71269
71387
  }
71270
- return (0, import_neverthrow41.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
71388
+ return (0, import_neverthrow42.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
71271
71389
  }
71272
71390
  function assemblePipelineSetup({
71273
71391
  config: config2,
@@ -71300,10 +71418,10 @@ function buildPipelineSetup({
71300
71418
  }) {
71301
71419
  const resolvedResult = resolvePipelineConfig({ config: config2, date: date5 });
71302
71420
  if (resolvedResult.isErr()) {
71303
- return (0, import_neverthrow40.err)(resolvedResult.error);
71421
+ return (0, import_neverthrow41.err)(resolvedResult.error);
71304
71422
  }
71305
71423
  const { runId, runPaths, dismissals } = resolvedResult.value;
71306
- return (0, import_neverthrow40.ok)(assemblePipelineSetup({ config: config2, date: date5, runId, runPaths, dismissals }));
71424
+ return (0, import_neverthrow41.ok)(assemblePipelineSetup({ config: config2, date: date5, runId, runPaths, dismissals }));
71307
71425
  }
71308
71426
  function runAgentPhases(setup, config2) {
71309
71427
  const { onEvent } = config2;
@@ -71340,50 +71458,18 @@ function runPipeline3(config2) {
71340
71458
  const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, ISO_DATE_LENGTH2);
71341
71459
  const setupResult = buildPipelineSetup({ config: config2, date: date5 });
71342
71460
  if (setupResult.isErr()) {
71343
- return (0, import_neverthrow35.errAsync)(setupResult.error);
71461
+ return (0, import_neverthrow36.errAsync)(setupResult.error);
71344
71462
  }
71345
71463
  return executePipeline(setupResult.value, config2);
71346
71464
  }
71347
71465
 
71348
- // src/commands/analyse-command.ts
71349
- var import_neverthrow45 = __toESM(require_index_cjs(), 1);
71350
-
71351
- // src/commands/item-events.ts
71352
- function emitItemStart(identity, at) {
71353
- const { display, itemId, itemName, simulatorUdid } = identity;
71354
- display.onEvent({ type: "ITEM_QUEUED", item: { id: itemId, name: itemName } });
71355
- display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid, at });
71356
- }
71357
- function emitItemCompleted(input) {
71358
- const { identity, startedAt, findingsCount, dismissedCount } = input;
71359
- const { display, itemId, itemName } = identity;
71360
- const at = Date.now();
71361
- display.onEvent({
71362
- type: "ITEM_COMPLETED",
71363
- itemId,
71364
- itemName,
71365
- findingsCount,
71366
- dismissedCount,
71367
- durationMs: at - startedAt,
71368
- at
71369
- });
71370
- }
71371
- function emitItemFailed(input) {
71372
- const { identity, startedAt, error: error48 } = input;
71373
- const { display, itemId, itemName } = identity;
71374
- const at = Date.now();
71375
- display.onEvent({
71376
- type: "ITEM_FAILED",
71377
- itemId,
71378
- itemName,
71379
- error: error48,
71380
- durationMs: at - startedAt,
71381
- at
71382
- });
71466
+ // src/commands/analyse/artifacts.ts
71467
+ function buildArtifacts(videoPath) {
71468
+ return { videoPath, findings: [], snapshots: [] };
71383
71469
  }
71384
71470
 
71385
71471
  // src/shell/debug-agent-events.ts
71386
- var import_neverthrow44 = __toESM(require_index_cjs(), 1);
71472
+ var import_neverthrow45 = __toESM(require_index_cjs(), 1);
71387
71473
 
71388
71474
  // src/constants.ts
71389
71475
  var MOBILE_IOS_TOOLS = [
@@ -71467,7 +71553,7 @@ function tryStringify(value) {
71467
71553
  const result = JSON.stringify(value);
71468
71554
  return result ?? UNSERIALIZABLE;
71469
71555
  }
71470
- var safeStringify = (0, import_neverthrow44.fromThrowable)(tryStringify, () => ({
71556
+ var safeStringify = (0, import_neverthrow45.fromThrowable)(tryStringify, () => ({
71471
71557
  type: "STRINGIFY_FAILED"
71472
71558
  }));
71473
71559
  function toolKey(scope, event) {
@@ -71592,6 +71678,12 @@ function handleItemFailed(logger, event) {
71592
71678
  function handleItemTimeout(logger, event) {
71593
71679
  logger.log("ITEM_TIMEOUT", `id=${event.itemId} duration=${String(event.durationMs)}ms`);
71594
71680
  }
71681
+ function handleItemAborted(logger, event) {
71682
+ logger.log(
71683
+ "ITEM_ABORTED",
71684
+ `id=${event.itemId} reason=${event.reason} duration=${String(event.durationMs)}ms`
71685
+ );
71686
+ }
71595
71687
  function handleSimulatorUnhealthy(logger, event) {
71596
71688
  logger.log(
71597
71689
  "SIMULATOR_UNHEALTHY",
@@ -71610,6 +71702,7 @@ var SUITE_EVENT_HANDLERS = {
71610
71702
  ITEM_COMPLETED: handleItemCompleted,
71611
71703
  ITEM_FAILED: handleItemFailed,
71612
71704
  ITEM_TIMEOUT: handleItemTimeout,
71705
+ ITEM_ABORTED: handleItemAborted,
71613
71706
  SIMULATOR_UNHEALTHY: handleSimulatorUnhealthy,
71614
71707
  SUITE_COMPLETED: handleSuiteCompleted
71615
71708
  };
@@ -71680,36 +71773,9 @@ function createSuiteDisplay() {
71680
71773
  });
71681
71774
  }
71682
71775
 
71683
- // src/commands/analyse-command.ts
71684
- var JSON_INDENT = 2;
71776
+ // src/commands/analyse/run-state.ts
71685
71777
  var ITEM_ID = "analyse";
71686
71778
  var ITEM_NAME = "analyse";
71687
- function buildArtifacts(videoPath) {
71688
- return { videoPath, findings: [], snapshots: [] };
71689
- }
71690
- async function checkVideoPathExists(videoPath) {
71691
- const safeAccess = (0, import_neverthrow45.fromAsyncThrowable)(import_promises19.access, () => ({ type: "FILE_NOT_FOUND" }));
71692
- const result = await safeAccess(videoPath);
71693
- return result.isOk();
71694
- }
71695
- function handleAnalyseSuccess(state, findings) {
71696
- emitItemCompleted({
71697
- identity: state.identity,
71698
- startedAt: state.startedAt,
71699
- findingsCount: findings.length,
71700
- dismissedCount: 0
71701
- });
71702
- state.identity.display.cleanup();
71703
- process.stdout.write(JSON.stringify(findings, void 0, JSON_INDENT));
71704
- process.exit(0);
71705
- }
71706
- function handleAnalyseError(state, errorType) {
71707
- emitItemFailed({ identity: state.identity, startedAt: state.startedAt, error: errorType });
71708
- state.identity.display.cleanup();
71709
- process.stderr.write(`Analysis failed: ${errorType}
71710
- `);
71711
- process.exit(1);
71712
- }
71713
71779
  function buildAnalyseIdentity() {
71714
71780
  return {
71715
71781
  display: createSoloDisplay(),
@@ -71725,62 +71791,36 @@ function buildAnalyseEventHandler(identity, isDebug) {
71725
71791
  };
71726
71792
  return debugLogger.wrapAgentHandler(baseHandler);
71727
71793
  }
71728
- async function runAnalysisAndExit(input) {
71794
+ function buildAnalyseRunState(isDebug) {
71729
71795
  const identity = buildAnalyseIdentity();
71730
71796
  const startedAt = Date.now();
71731
- emitItemStart(identity, startedAt);
71732
- const onEvent = buildAnalyseEventHandler(identity, input.debug);
71733
- const state = { identity, startedAt };
71734
- const result = await runAnalysis(input.artifacts, {
71735
- apiKey: input.apiKey,
71736
- onEvent
71797
+ const onEvent = buildAnalyseEventHandler(identity, isDebug);
71798
+ return { identity, startedAt, onEvent };
71799
+ }
71800
+
71801
+ // src/commands/analyse/runner.ts
71802
+ async function runValidatedAnalysis(validated) {
71803
+ const state = buildAnalyseRunState(validated.debug);
71804
+ emitItemStart(state.identity, state.startedAt);
71805
+ const onSuccess = buildSuccessHandler(state);
71806
+ const onError = buildErrorHandler(state);
71807
+ const result = await runAnalysis(buildArtifacts(validated.videoPath), {
71808
+ apiKey: validated.apiKey,
71809
+ onEvent: state.onEvent
71810
+ });
71811
+ result.match(onSuccess, (error48) => {
71812
+ onError(error48.type);
71737
71813
  });
71738
- result.match(
71739
- (findings) => {
71740
- handleAnalyseSuccess(state, findings);
71741
- },
71742
- (error48) => {
71743
- handleAnalyseError(state, error48.type);
71744
- }
71745
- );
71746
- }
71747
- function ensureApiKey(config2) {
71748
- const apiKey = config2.GOOGLE_GENERATIVE_AI_API_KEY ?? "";
71749
- if (!apiKey) {
71750
- process.stderr.write("GOOGLE_GENERATIVE_AI_API_KEY is not set\n");
71751
- process.exit(1);
71752
- return;
71753
- }
71754
- return apiKey;
71755
- }
71756
- async function resolveVideoPath(videoPath) {
71757
- if (videoPath === void 0) {
71758
- process.stderr.write('A video path is required. Pass the path printed by "xqa explore".\n');
71759
- process.exit(1);
71760
- return;
71761
- }
71762
- if (!await checkVideoPathExists(videoPath)) {
71763
- process.stderr.write(`Video file not found: ${videoPath}
71764
- `);
71765
- process.exit(1);
71766
- return;
71767
- }
71768
- return videoPath;
71769
71814
  }
71815
+
71816
+ // src/commands/analyse-command.ts
71770
71817
  async function runAnalyseCommand(input) {
71771
- const apiKey = ensureApiKey(input.config);
71772
- if (apiKey === void 0) {
71818
+ const validated = await validateAnalyseInput(input);
71819
+ if (validated.isErr()) {
71820
+ handleInputError(validated.error);
71773
71821
  return;
71774
71822
  }
71775
- const videoPath = await resolveVideoPath(input.videoPath);
71776
- if (videoPath === void 0) {
71777
- return;
71778
- }
71779
- await runAnalysisAndExit({
71780
- artifacts: buildArtifacts(videoPath),
71781
- apiKey,
71782
- debug: input.debug
71783
- });
71823
+ await runValidatedAnalysis(validated.value);
71784
71824
  }
71785
71825
 
71786
71826
  // src/commands/register/analyse.ts
@@ -72067,7 +72107,7 @@ function buildSuccessMessage(output) {
72067
72107
  return `${base}${String(output.findings.length)} finding${output.findings.length === 1 ? "" : "s"} \u2014 run \`xqa review\` to triage.
72068
72108
  `;
72069
72109
  }
72070
- function buildSuccessHandler({
72110
+ function buildSuccessHandler2({
72071
72111
  input,
72072
72112
  xqaDirectory,
72073
72113
  identity,
@@ -72089,7 +72129,7 @@ function buildSuccessHandler({
72089
72129
  process.exit(0);
72090
72130
  };
72091
72131
  }
72092
- function buildErrorHandler(identity, startedAt) {
72132
+ function buildErrorHandler2(identity, startedAt) {
72093
72133
  return (error48) => {
72094
72134
  emitItemFailed({ identity, startedAt, error: error48.type });
72095
72135
  identity.display.cleanup();
@@ -72165,8 +72205,8 @@ function buildExploreRunState({
72165
72205
  identity.display.onEvent({ ...event, itemId: ITEM_ID2 });
72166
72206
  };
72167
72207
  const onEvent = debugLogger.wrapAgentHandler(baseHandler);
72168
- const onSuccess = buildSuccessHandler({ input, xqaDirectory, identity, startedAt });
72169
- const onError = buildErrorHandler(identity, startedAt);
72208
+ const onSuccess = buildSuccessHandler2({ input, xqaDirectory, identity, startedAt });
72209
+ const onError = buildErrorHandler2(identity, startedAt);
72170
72210
  return { input, config: config2, xqaDirectory, onEvent, onSuccess, onError, simulatorUdid };
72171
72211
  }
72172
72212
 
@@ -79460,6 +79500,7 @@ var PriorityQueue = class {
79460
79500
  };
79461
79501
 
79462
79502
  // src/suite/shell/item-result-builder.ts
79503
+ var ABORTED_ITEM_ERROR_MESSAGE = "aborted by suite shutdown";
79463
79504
  function getSpecPath(item) {
79464
79505
  if (item.type === "spec") {
79465
79506
  return item.specPath;
@@ -79516,21 +79557,82 @@ function buildTimedOutItem(context) {
79516
79557
  error: "timeout"
79517
79558
  };
79518
79559
  }
79519
- function buildAbortedItem(item, simulatorUdid) {
79560
+ function buildAbortedItem(context) {
79520
79561
  return {
79521
- id: item.id,
79522
- type: item.type,
79523
- name: item.name,
79562
+ id: context.item.id,
79563
+ type: context.item.type,
79564
+ name: context.item.name,
79524
79565
  status: "aborted",
79525
- simulatorUdid,
79526
- specPath: getSpecPath(item),
79527
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
79566
+ simulatorUdid: context.simulatorUdid,
79567
+ specPath: getSpecPath(context.item),
79568
+ startedAt: context.startedAt,
79528
79569
  findingsPath: null,
79529
79570
  findings: [],
79530
- durationMs: 0
79571
+ durationMs: context.durationMs
79531
79572
  };
79532
79573
  }
79533
79574
 
79575
+ // src/suite/shell/aborted-item-drainer.ts
79576
+ function emitAbortedTerminal(input) {
79577
+ input.observer({
79578
+ type: "ITEM_ABORTED",
79579
+ itemId: input.item.id,
79580
+ itemName: input.item.name,
79581
+ reason: ABORTED_ITEM_ERROR_MESSAGE,
79582
+ durationMs: input.durationMs,
79583
+ at: Date.now()
79584
+ });
79585
+ }
79586
+ function recordAbortedEntry(context, itemContext) {
79587
+ if (context.recordedIds.has(itemContext.item.id)) {
79588
+ return;
79589
+ }
79590
+ context.results.push(buildAbortedItem(itemContext));
79591
+ context.recordedIds.add(itemContext.item.id);
79592
+ emitAbortedTerminal({
79593
+ observer: context.observer,
79594
+ item: itemContext.item,
79595
+ durationMs: itemContext.durationMs
79596
+ });
79597
+ }
79598
+ function drainQueuedItems(input, context) {
79599
+ const { queue, fallbackUdid } = input;
79600
+ while (!queue.isEmpty) {
79601
+ const item = queue.dequeue();
79602
+ if (item === void 0) {
79603
+ break;
79604
+ }
79605
+ recordAbortedEntry(context, {
79606
+ item,
79607
+ simulatorUdid: fallbackUdid,
79608
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
79609
+ durationMs: 0
79610
+ });
79611
+ }
79612
+ }
79613
+ function drainInFlightItems(input, context) {
79614
+ const { inFlight } = input;
79615
+ for (const entry of inFlight.values()) {
79616
+ recordAbortedEntry(context, {
79617
+ item: entry.item,
79618
+ simulatorUdid: entry.simulatorUdid,
79619
+ startedAt: entry.startedAt,
79620
+ durationMs: Date.now() - entry.startMs
79621
+ });
79622
+ }
79623
+ inFlight.clear();
79624
+ }
79625
+ function drainAbortedItems(input) {
79626
+ const recordedIds = new Set(input.results.map((item) => item.id));
79627
+ const context = {
79628
+ results: input.results,
79629
+ observer: input.observer,
79630
+ recordedIds
79631
+ };
79632
+ drainInFlightItems(input, context);
79633
+ drainQueuedItems(input, context);
79634
+ }
79635
+
79534
79636
  // src/suite/shell/item-result-recorder.ts
79535
79637
  function isTimeoutError(error48) {
79536
79638
  return error48.type.toUpperCase().includes("TIMEOUT");
@@ -79833,6 +79935,14 @@ function handleHookFailure(state, error48) {
79833
79935
  observer: workerContext.config.observer
79834
79936
  });
79835
79937
  }
79938
+ function trackInFlight(workerContext, state) {
79939
+ workerContext.inFlight.set(state.item.id, {
79940
+ item: state.item,
79941
+ simulatorUdid: workerContext.simulatorUdid,
79942
+ startedAt: state.startedAt,
79943
+ startMs: state.startMs
79944
+ });
79945
+ }
79836
79946
  async function processItem(workerContext, item) {
79837
79947
  const state = {
79838
79948
  workerContext,
@@ -79840,13 +79950,25 @@ async function processItem(workerContext, item) {
79840
79950
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
79841
79951
  startMs: Date.now()
79842
79952
  };
79953
+ trackInFlight(workerContext, state);
79843
79954
  emitItemStarted(state);
79844
79955
  const hookOutcome = await maybeInvokeHook(buildHookInvokeInput(workerContext, item));
79845
79956
  if (hookOutcome.isErr()) {
79846
- return handleHookFailure(state, hookOutcome.error);
79957
+ const failCount2 = handleHookFailure(state, hookOutcome.error);
79958
+ workerContext.inFlight.delete(item.id);
79959
+ return failCount2;
79847
79960
  }
79848
- return runAndRecordItem(state);
79961
+ const failCount = await runAndRecordItem(state);
79962
+ workerContext.inFlight.delete(item.id);
79963
+ return failCount;
79849
79964
  }
79965
+ var safeProcessItem = import_neverthrow59.ResultAsync.fromThrowable(
79966
+ processItem,
79967
+ (cause) => ({
79968
+ type: "PROCESS_ITEM_FAILED",
79969
+ cause
79970
+ })
79971
+ );
79850
79972
  async function runWorker(workerContext) {
79851
79973
  const { simulatorUdid, queue, config: config2 } = workerContext;
79852
79974
  let consecutiveFailures = 0;
@@ -79855,7 +79977,11 @@ async function runWorker(workerContext) {
79855
79977
  if (item === void 0) {
79856
79978
  break;
79857
79979
  }
79858
- const failCount = await processItem(workerContext, item);
79980
+ const outcome = await safeProcessItem(workerContext, item);
79981
+ const failCount = outcome.match(
79982
+ (value) => value,
79983
+ () => 1
79984
+ );
79859
79985
  consecutiveFailures = failCount === 0 ? 0 : consecutiveFailures + 1;
79860
79986
  if (consecutiveFailures >= CONSECUTIVE_FAILURES_THRESHOLD) {
79861
79987
  config2.observer({ type: "SIMULATOR_UNHEALTHY", simulatorUdid, consecutiveFailures });
@@ -79871,25 +79997,20 @@ function setupQueue(config2) {
79871
79997
  }
79872
79998
  return queue;
79873
79999
  }
79874
- function drainAbortedItems(runContext) {
79875
- const { queue, results, config: config2 } = runContext;
79876
- const fallbackUdid = config2.simulatorUdids[0] ?? "";
79877
- while (!queue.isEmpty) {
79878
- const item = queue.dequeue();
79879
- if (item === void 0) {
79880
- break;
79881
- }
79882
- results.push(buildAbortedItem(item, fallbackUdid));
79883
- }
79884
- }
79885
80000
  async function runAllWorkers(runContext) {
79886
- const { config: config2, queue, results, suiteStartMs } = runContext;
80001
+ const { config: config2, queue, results, suiteStartMs, inFlight } = runContext;
79887
80002
  const workerPromises = config2.simulatorUdids.map(
79888
- async (udid) => runWorker({ simulatorUdid: udid, queue, results, config: config2 })
80003
+ async (udid) => runWorker({ simulatorUdid: udid, queue, results, config: config2, inFlight })
79889
80004
  );
79890
80005
  await Promise.allSettled(workerPromises);
79891
- if (config2.signal.aborted) {
79892
- drainAbortedItems(runContext);
80006
+ if (config2.signal.aborted || inFlight.size > 0 || !queue.isEmpty) {
80007
+ drainAbortedItems({
80008
+ queue,
80009
+ results,
80010
+ observer: config2.observer,
80011
+ inFlight,
80012
+ fallbackUdid: config2.simulatorUdids[0] ?? ""
80013
+ });
79893
80014
  }
79894
80015
  const totalFindings = results.reduce((sum, item) => sum + item.findings.length, 0);
79895
80016
  config2.observer({
@@ -79904,9 +80025,10 @@ async function runAllWorkers(runContext) {
79904
80025
  function runWorkerPool(config2) {
79905
80026
  const queue = setupQueue(config2);
79906
80027
  const results = [];
80028
+ const inFlight = /* @__PURE__ */ new Map();
79907
80029
  const suiteStartMs = Date.now();
79908
80030
  const safeRun = import_neverthrow59.ResultAsync.fromThrowable(
79909
- async () => runAllWorkers({ config: config2, queue, results, suiteStartMs }),
80031
+ async () => runAllWorkers({ config: config2, queue, results, suiteStartMs, inFlight }),
79910
80032
  (cause) => ({ type: "WORKER_POOL_FAILED", cause })
79911
80033
  );
79912
80034
  return safeRun();
@@ -82413,8 +82535,6 @@ function buildDecision(input) {
82413
82535
  metaPr: input.metaPr
82414
82536
  };
82415
82537
  }
82416
- var HIGH_MATCH_RATIO = 0.7;
82417
- var MEDIUM_MATCH_RATIO = 0.3;
82418
82538
  var REASON_SAMPLE_LIMIT = 3;
82419
82539
  function matchesAnyGlob(path29, patterns) {
82420
82540
  return patterns.some((pattern) => minimatch(path29, pattern));
@@ -82422,38 +82542,24 @@ function matchesAnyGlob(path29, patterns) {
82422
82542
  function collectMatchingPaths(diff, covers) {
82423
82543
  return diff.files.filter((file2) => matchesAnyGlob(file2.path, covers)).map((file2) => file2.path);
82424
82544
  }
82425
- function formatReason(parts) {
82426
- const sample = parts.paths.slice(0, REASON_SAMPLE_LIMIT).join(", ");
82427
- return `matched ${String(parts.matches)}/${String(parts.total)} files: ${sample}`;
82428
- }
82429
- function resolvePickConfidence(matches, total) {
82430
- if (total === 0 || matches === 0) {
82431
- return void 0;
82432
- }
82433
- const ratio = matches / total;
82434
- if (ratio >= HIGH_MATCH_RATIO) {
82435
- return "HIGH";
82436
- }
82437
- if (ratio >= MEDIUM_MATCH_RATIO) {
82438
- return "MEDIUM";
82439
- }
82440
- return "LOW";
82545
+ function formatReason(paths) {
82546
+ const sample = paths.slice(0, REASON_SAMPLE_LIMIT).join(", ");
82547
+ const overflow = paths.length > REASON_SAMPLE_LIMIT ? ", \u2026" : "";
82548
+ const suffix = paths.length === 1 ? "" : "s";
82549
+ return `touched ${String(paths.length)} covered file${suffix}: ${sample}${overflow}`;
82441
82550
  }
82442
82551
  function scoreGroup(diff, group) {
82443
82552
  if (!group.covers || group.covers.length === 0) {
82444
82553
  return void 0;
82445
82554
  }
82446
- const total = diff.files.length;
82447
82555
  const matchingPaths = collectMatchingPaths(diff, group.covers);
82448
- const matches = matchingPaths.length;
82449
- const confidence = resolvePickConfidence(matches, total);
82450
- if (confidence === void 0) {
82556
+ if (matchingPaths.length === 0) {
82451
82557
  return void 0;
82452
82558
  }
82453
82559
  return {
82454
82560
  groupId: group.id,
82455
- confidence,
82456
- reason: formatReason({ matches, total, paths: matchingPaths }),
82561
+ confidence: "HIGH",
82562
+ reason: formatReason(matchingPaths),
82457
82563
  evidence: matchingPaths.map((matchPath) => `diff:${matchPath}`)
82458
82564
  };
82459
82565
  }
@@ -83131,7 +83237,7 @@ function buildBootstrap(options2) {
83131
83237
  function selectGroups(options2) {
83132
83238
  return runPipeline4(buildBootstrap(options2));
83133
83239
  }
83134
- var DEFAULT_MODEL2 = "claude-opus-4-6";
83240
+ var DEFAULT_MODEL2 = "claude-sonnet-4-6";
83135
83241
  var CONFIDENCE_RANK = {
83136
83242
  HIGH: 2,
83137
83243
  MEDIUM: 1,
@@ -83194,19 +83300,10 @@ function toSuitePromptInput(group, context) {
83194
83300
  function buildSuitePromptInputs(context) {
83195
83301
  return context.groups.map((group) => toSuitePromptInput(group, context));
83196
83302
  }
83197
- var MATCH_COUNT_PATTERN = /matched (\d+)/;
83198
- var COUNT_GROUP_INDEX = 1;
83199
- function extractMatchCount(reason) {
83200
- const match2 = MATCH_COUNT_PATTERN.exec(reason);
83201
- if (match2 === null) {
83202
- return 0;
83203
- }
83204
- return Number.parseInt(match2[COUNT_GROUP_INDEX] ?? "0", 10);
83205
- }
83206
83303
  function buildGlobHits(diff, groups) {
83207
83304
  return scoreGroups(diff, groups).map((pick2) => ({
83208
83305
  groupId: pick2.groupId,
83209
- fileCount: extractMatchCount(pick2.reason)
83306
+ fileCount: pick2.evidence.length
83210
83307
  }));
83211
83308
  }
83212
83309
  function mergePickPair(existing, incoming) {
@@ -83281,12 +83378,6 @@ function combineAiOutcome(staticPicks, aiResult) {
83281
83378
  function runAiTiebreaker(context, staticPicks) {
83282
83379
  return selectGroups(buildSelectGroupsOptions(context)).mapErr(mapAiError).map((aiResult) => combineAiOutcome(staticPicks, aiResult));
83283
83380
  }
83284
- function shouldSkipAi(context, decision) {
83285
- if (!context.useAi) {
83286
- return true;
83287
- }
83288
- return decision.confidence === "high";
83289
- }
83290
83381
  function runTriager(options2) {
83291
83382
  const { groups, config: config2 } = options2;
83292
83383
  if (groups.length === 0) {
@@ -83297,9 +83388,8 @@ function runTriager(options2) {
83297
83388
  }
83298
83389
  const context = buildContext2(options2);
83299
83390
  const staticPicks = scoreGroups(context.diff, context.groups);
83300
- const initial = buildDecision({ picks: staticPicks, metaPr: false });
83301
- if (shouldSkipAi(context, initial)) {
83302
- return (0, import_neverthrow65.okAsync)(initial);
83391
+ if (!context.useAi) {
83392
+ return (0, import_neverthrow65.okAsync)(buildDecision({ picks: staticPicks, metaPr: false }));
83303
83393
  }
83304
83394
  return runAiTiebreaker(context, staticPicks);
83305
83395
  }
@@ -87935,7 +88025,7 @@ function buildProgram(options2) {
87935
88025
 
87936
88026
  // src/index.ts
87937
88027
  process.title = "xqa";
87938
- var version2 = `${"3.0.0"}${false ? ` (dev build +${"76b2340"})` : ""}`;
88028
+ var version2 = `${"3.0.1"}${false ? ` (dev build +${"c388107"})` : ""}`;
87939
88029
  var programResult = buildProgram({ version: version2 });
87940
88030
  if (programResult.isErr()) {
87941
88031
  process.stderr.write(programResult.error.message + "\n");