@exodus/xqa 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/xqa.cjs +255 -209
  2. package/package.json +2 -2
package/dist/xqa.cjs CHANGED
@@ -3719,7 +3719,7 @@ var require_index_cjs = __commonJS({
3719
3719
  return __asyncGenerator2(this, arguments, function* _a3() {
3720
3720
  const result = yield __await2(this._promise);
3721
3721
  if (result.isErr()) {
3722
- yield yield __await2(errAsync7(result.error));
3722
+ yield yield __await2(errAsync8(result.error));
3723
3723
  }
3724
3724
  return yield __await2(result.value);
3725
3725
  });
@@ -3728,7 +3728,7 @@ var require_index_cjs = __commonJS({
3728
3728
  function okAsync8(value) {
3729
3729
  return new ResultAsync12(Promise.resolve(new Ok(value)));
3730
3730
  }
3731
- function errAsync7(err19) {
3731
+ function errAsync8(err19) {
3732
3732
  return new ResultAsync12(Promise.resolve(new Err(err19)));
3733
3733
  }
3734
3734
  var fromPromise = ResultAsync12.fromPromise;
@@ -3910,14 +3910,14 @@ var require_index_cjs = __commonJS({
3910
3910
  }
3911
3911
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3912
3912
  asyncAndThen(_f) {
3913
- return errAsync7(this.error);
3913
+ return errAsync8(this.error);
3914
3914
  }
3915
3915
  asyncAndThrough(_f) {
3916
- return errAsync7(this.error);
3916
+ return errAsync8(this.error);
3917
3917
  }
3918
3918
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
3919
3919
  asyncMap(_f) {
3920
- return errAsync7(this.error);
3920
+ return errAsync8(this.error);
3921
3921
  }
3922
3922
  unwrapOr(v2) {
3923
3923
  return v2;
@@ -3949,7 +3949,7 @@ var require_index_cjs = __commonJS({
3949
3949
  exports2.Ok = Ok;
3950
3950
  exports2.ResultAsync = ResultAsync12;
3951
3951
  exports2.err = err18;
3952
- exports2.errAsync = errAsync7;
3952
+ exports2.errAsync = errAsync8;
3953
3953
  exports2.fromAsyncThrowable = fromAsyncThrowable10;
3954
3954
  exports2.fromPromise = fromPromise;
3955
3955
  exports2.fromSafePromise = fromSafePromise2;
@@ -52810,7 +52810,7 @@ function dismissalsPath(baseDirectory, override) {
52810
52810
  }
52811
52811
 
52812
52812
  // ../../packages/pipeline/dist/index.js
52813
- var import_neverthrow29 = __toESM(require_index_cjs(), 1);
52813
+ var import_neverthrow30 = __toESM(require_index_cjs(), 1);
52814
52814
  var import_promises14 = require("node:timers/promises");
52815
52815
 
52816
52816
  // ../../agents/analyser/dist/index.js
@@ -62129,10 +62129,10 @@ function runConsolidator(input, config3) {
62129
62129
  }
62130
62130
 
62131
62131
  // ../../packages/pipeline/dist/index.js
62132
- var import_neverthrow30 = __toESM(require_index_cjs(), 1);
62133
62132
  var import_neverthrow31 = __toESM(require_index_cjs(), 1);
62134
- var import_node_fs3 = require("node:fs");
62135
62133
  var import_neverthrow32 = __toESM(require_index_cjs(), 1);
62134
+ var import_node_fs3 = require("node:fs");
62135
+ var import_neverthrow33 = __toESM(require_index_cjs(), 1);
62136
62136
  var import_promises15 = require("node:timers/promises");
62137
62137
 
62138
62138
  // ../../agents/explorer/dist/index.js
@@ -62150,9 +62150,10 @@ var import_node_child_process4 = require("node:child_process");
62150
62150
  var import_promises10 = require("node:fs/promises");
62151
62151
  var import_neverthrow19 = __toESM(require_index_cjs(), 1);
62152
62152
  var import_neverthrow20 = __toESM(require_index_cjs(), 1);
62153
+ var import_neverthrow21 = __toESM(require_index_cjs(), 1);
62153
62154
  var import_promises11 = require("node:fs/promises");
62154
62155
  var import_node_path6 = __toESM(require("node:path"), 1);
62155
- var import_neverthrow21 = __toESM(require_index_cjs(), 1);
62156
+ var import_neverthrow22 = __toESM(require_index_cjs(), 1);
62156
62157
  async function runFfmpeg(arguments_) {
62157
62158
  const { promise: promise2, resolve, reject } = Promise.withResolvers();
62158
62159
  (0, import_node_child_process3.execFile)("ffmpeg", arguments_, (error48) => {
@@ -62846,6 +62847,53 @@ function runQuery(prompt, config3) {
62846
62847
  function collectAgentOutput(prompt, config3) {
62847
62848
  return runQuery(prompt, config3).mapErr((cause) => ({ type: "QUERY_FAILED", cause }));
62848
62849
  }
62850
+ var SPEED_2X = 2;
62851
+ var SPEED_4X = 4;
62852
+ function applySpeedUpVariants({
62853
+ result,
62854
+ params,
62855
+ toRecordingError
62856
+ }) {
62857
+ const { findings, snapshots } = result;
62858
+ const { videoPath, videoPath2x, videoPath4x, signal } = params;
62859
+ if (signal?.aborted) {
62860
+ return (0, import_neverthrow20.okAsync)({ findings, snapshots });
62861
+ }
62862
+ return speedUpVideo({ inputPath: videoPath, factor: SPEED_2X, outputPath: videoPath2x }).mapErr(toRecordingError).andThen(
62863
+ () => speedUpVideo({ inputPath: videoPath, factor: SPEED_4X, outputPath: videoPath4x }).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
62864
+ );
62865
+ }
62866
+ function runWithRecording(handle, collectOutput) {
62867
+ const toRecordingError = (cause) => ({
62868
+ type: "RECORDING_FAILED",
62869
+ cause
62870
+ });
62871
+ return collectOutput().andThen(
62872
+ ({ findings, snapshots }) => stopRecording(handle).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
62873
+ ).orElse(
62874
+ (error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0, import_neverthrow20.errAsync)(error48)).orElse(() => (0, import_neverthrow20.errAsync)(error48))
62875
+ );
62876
+ }
62877
+ function startAndRun(params) {
62878
+ const { videoPath, signal, collectOutput } = params;
62879
+ const toRecordingError = (cause) => ({
62880
+ type: "RECORDING_FAILED",
62881
+ cause
62882
+ });
62883
+ return startRecording(videoPath).mapErr(toRecordingError).andThen((handle) => {
62884
+ const onAbort = () => {
62885
+ void stopRecording(handle).unwrapOr(null);
62886
+ };
62887
+ signal?.addEventListener("abort", onAbort, { once: true });
62888
+ return runWithRecording(handle, collectOutput).map((result) => {
62889
+ signal?.removeEventListener("abort", onAbort);
62890
+ return result;
62891
+ }).mapErr((error48) => {
62892
+ signal?.removeEventListener("abort", onAbort);
62893
+ return error48;
62894
+ }).andThen((result) => applySpeedUpVariants({ result, params, toRecordingError }));
62895
+ });
62896
+ }
62849
62897
  var DEV_ENVIRONMENT_SECTION = `## Environment
62850
62898
 
62851
62899
  This is a development build. Debug overlays and internal messages are expected artifacts \u2014 do not report them as findings.`;
@@ -63057,29 +63105,29 @@ var INLINE_ASSERTION_DELIMITER = " \u2192 ";
63057
63105
  var NUMBERED_STEP_PREFIX = /^\d+\.\s+/;
63058
63106
  function parseTagsValue(value) {
63059
63107
  if (!value.startsWith("[") || !value.endsWith("]")) {
63060
- return (0, import_neverthrow20.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
63108
+ return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
63061
63109
  }
63062
- return (0, import_neverthrow20.ok)(
63110
+ return (0, import_neverthrow21.ok)(
63063
63111
  value.slice(1, -1).split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0)
63064
63112
  );
63065
63113
  }
63066
63114
  function parseTimeoutValue(value) {
63067
63115
  const parsed = Number(value);
63068
63116
  if (Number.isNaN(parsed) || parsed <= 0) {
63069
- return (0, import_neverthrow20.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
63117
+ return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
63070
63118
  }
63071
- return (0, import_neverthrow20.ok)(parsed);
63119
+ return (0, import_neverthrow21.ok)(parsed);
63072
63120
  }
63073
63121
  function parseFrontmatterLine(line) {
63074
63122
  const colonIndex = line.indexOf(":");
63075
63123
  if (colonIndex === -1) {
63076
- return (0, import_neverthrow20.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
63124
+ return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
63077
63125
  }
63078
63126
  const key = line.slice(0, colonIndex).trim();
63079
63127
  const value = line.slice(colonIndex + 1).trim();
63080
63128
  switch (key) {
63081
63129
  case "description": {
63082
- return (0, import_neverthrow20.ok)({ description: value });
63130
+ return (0, import_neverthrow21.ok)({ description: value });
63083
63131
  }
63084
63132
  case "tags": {
63085
63133
  return parseTagsValue(value).map((tags) => ({ tags }));
@@ -63088,7 +63136,7 @@ function parseFrontmatterLine(line) {
63088
63136
  return parseTimeoutValue(value).map((timeout) => ({ timeout }));
63089
63137
  }
63090
63138
  default: {
63091
- return (0, import_neverthrow20.ok)({});
63139
+ return (0, import_neverthrow21.ok)({});
63092
63140
  }
63093
63141
  }
63094
63142
  }
@@ -63107,18 +63155,18 @@ function mergePartials(partials) {
63107
63155
  }
63108
63156
  function combineFrontmatterLines(lines) {
63109
63157
  const lineResults = lines.filter((line) => line.trim().length > 0).map((line) => parseFrontmatterLine(line));
63110
- return import_neverthrow20.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
63158
+ return import_neverthrow21.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
63111
63159
  }
63112
63160
  function extractFrontmatter(content) {
63113
63161
  const trimmed = content.trimStart();
63114
63162
  if (!trimmed.startsWith(FRONTMATTER_FENCE)) {
63115
- return (0, import_neverthrow20.ok)({ frontmatter: emptyFrontmatter(), body: content });
63163
+ return (0, import_neverthrow21.ok)({ frontmatter: emptyFrontmatter(), body: content });
63116
63164
  }
63117
63165
  const afterOpenFence = trimmed.slice(FRONTMATTER_FENCE.length);
63118
63166
  const closeIndex = afterOpenFence.indexOf(`
63119
63167
  ${FRONTMATTER_FENCE}`);
63120
63168
  if (closeIndex === -1) {
63121
- return (0, import_neverthrow20.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
63169
+ return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
63122
63170
  }
63123
63171
  const rawFrontmatter = afterOpenFence.slice(0, closeIndex);
63124
63172
  const body = afterOpenFence.slice(closeIndex + FRONTMATTER_FENCE.length + 1);
@@ -63160,13 +63208,13 @@ function parseTestSpec(name, content) {
63160
63208
  const sections = splitIntoSections(body);
63161
63209
  const setup = sections.Setup;
63162
63210
  if (setup === void 0) {
63163
- return (0, import_neverthrow20.err)({ type: "MISSING_SETUP_SECTION" });
63211
+ return (0, import_neverthrow21.err)({ type: "MISSING_SETUP_SECTION" });
63164
63212
  }
63165
63213
  const stepsSection = sections.Steps;
63166
63214
  if (stepsSection === void 0) {
63167
- return (0, import_neverthrow20.err)({ type: "MISSING_STEPS_SECTION" });
63215
+ return (0, import_neverthrow21.err)({ type: "MISSING_STEPS_SECTION" });
63168
63216
  }
63169
- return (0, import_neverthrow20.ok)({
63217
+ return (0, import_neverthrow21.ok)({
63170
63218
  name,
63171
63219
  frontmatter,
63172
63220
  setup,
@@ -63215,25 +63263,25 @@ function direntToSpecEntry(directory, entry) {
63215
63263
  return [];
63216
63264
  }
63217
63265
  function scanDirectory(directory) {
63218
- const safeReaddir3 = (0, import_neverthrow21.fromAsyncThrowable)(
63266
+ const safeReaddir3 = (0, import_neverthrow22.fromAsyncThrowable)(
63219
63267
  async () => (0, import_promises11.readdir)(directory, { withFileTypes: true }),
63220
63268
  (cause) => ({ type: "DIR_READ_FAILED", dir: directory, cause })
63221
63269
  );
63222
- return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow21.okAsync)([]) : (0, import_neverthrow21.errAsync)(error48)).map(
63270
+ return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow22.okAsync)([]) : (0, import_neverthrow22.errAsync)(error48)).map(
63223
63271
  (entries) => entries.flatMap((entry) => direntToSpecEntry(directory, entry))
63224
63272
  );
63225
63273
  }
63226
63274
  function readEntries(entries) {
63227
- return import_neverthrow21.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
63275
+ return import_neverthrow22.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
63228
63276
  (results) => results.flat()
63229
63277
  );
63230
63278
  }
63231
63279
  function readEntry(entry) {
63232
- const safeReadFile6 = (0, import_neverthrow21.fromAsyncThrowable)(
63280
+ const safeReadFile6 = (0, import_neverthrow22.fromAsyncThrowable)(
63233
63281
  async () => (0, import_promises11.readFile)(entry.path, "utf8"),
63234
63282
  (cause) => ({ type: "FILE_READ_FAILED", path: entry.path, cause })
63235
63283
  );
63236
- return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow21.errAsync)(error48) : (0, import_neverthrow21.okAsync)([]));
63284
+ return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow22.errAsync)(error48) : (0, import_neverthrow22.okAsync)([]));
63237
63285
  }
63238
63286
  function specNameFromPath(filePath) {
63239
63287
  const parts = filePath.split("/");
@@ -63249,8 +63297,6 @@ function filterByNames(specs, specNames) {
63249
63297
  }
63250
63298
  return specs.filter((spec) => specNames.includes(spec.name));
63251
63299
  }
63252
- var SPEED_2X = 2;
63253
- var SPEED_4X = 4;
63254
63300
  var ISO_DATE_LENGTH = 10;
63255
63301
  function buildPrompt(safeConfig, specs) {
63256
63302
  return generateExplorerPrompt({
@@ -63282,12 +63328,29 @@ function toArtifacts(result, runPaths) {
63282
63328
  function emitStageEnd3(safeConfig, start) {
63283
63329
  safeConfig.onEvent?.({ type: "STAGE_END", agent: "explorer", durationMs: Date.now() - start });
63284
63330
  }
63331
+ var EMPTY_RUN_PATHS = { videoPath: "", videoPath2x: "", videoPath4x: "" };
63332
+ function collectWithoutRecording({
63333
+ safeConfig,
63334
+ prompt,
63335
+ start
63336
+ }) {
63337
+ return collectAgentOutput(prompt, safeConfig).map((result) => {
63338
+ emitStageEnd3(safeConfig, start);
63339
+ return toArtifacts(result, EMPTY_RUN_PATHS);
63340
+ }).mapErr((error48) => {
63341
+ emitStageEnd3(safeConfig, start);
63342
+ return error48;
63343
+ });
63344
+ }
63285
63345
  function collectAndFinalize({
63286
63346
  safeConfig,
63287
63347
  prompt,
63288
63348
  runPaths,
63289
63349
  start
63290
63350
  }) {
63351
+ if (safeConfig.record === false) {
63352
+ return collectWithoutRecording({ safeConfig, prompt, start });
63353
+ }
63291
63354
  return startAndRun({
63292
63355
  videoPath: runPaths.videoPath,
63293
63356
  videoPath2x: runPaths.videoPath2x,
@@ -63343,71 +63406,19 @@ function runExplorer(config3) {
63343
63406
  (0, import_promises10.mkdir)(runPaths.screenshotsDir, { recursive: true }).catch(() => null)
63344
63407
  ).andThen(() => runPipeline({ safeConfig, runPaths, start }));
63345
63408
  }
63346
- function applySpeedUpVariants({
63347
- result,
63348
- params,
63349
- toRecordingError
63350
- }) {
63351
- const { findings, snapshots } = result;
63352
- const { videoPath, videoPath2x, videoPath4x, signal } = params;
63353
- if (signal?.aborted) {
63354
- return (0, import_neverthrow19.okAsync)({ findings, snapshots });
63355
- }
63356
- return speedUpVideo({ inputPath: videoPath, factor: SPEED_2X, outputPath: videoPath2x }).mapErr(toRecordingError).andThen(
63357
- () => speedUpVideo({ inputPath: videoPath, factor: SPEED_4X, outputPath: videoPath4x }).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
63358
- );
63359
- }
63360
- function applyPostProcessing({
63361
- result,
63362
- params,
63363
- toRecordingError
63364
- }) {
63365
- return applySpeedUpVariants({ result, params, toRecordingError });
63366
- }
63367
- function startAndRun(params) {
63368
- const { videoPath, signal, collectOutput } = params;
63369
- const toRecordingError = (cause) => ({
63370
- type: "RECORDING_FAILED",
63371
- cause
63372
- });
63373
- return startRecording(videoPath).mapErr(toRecordingError).andThen((handle) => {
63374
- const onAbort = () => {
63375
- void stopRecording(handle).unwrapOr(null);
63376
- };
63377
- signal?.addEventListener("abort", onAbort, { once: true });
63378
- return runWithRecording(handle, collectOutput).map((result) => {
63379
- signal?.removeEventListener("abort", onAbort);
63380
- return result;
63381
- }).mapErr((error48) => {
63382
- signal?.removeEventListener("abort", onAbort);
63383
- return error48;
63384
- }).andThen((result) => applyPostProcessing({ result, params, toRecordingError }));
63385
- });
63386
- }
63387
- function runWithRecording(handle, collectOutput) {
63388
- const toRecordingError = (cause) => ({
63389
- type: "RECORDING_FAILED",
63390
- cause
63391
- });
63392
- return collectOutput().andThen(
63393
- ({ findings, snapshots }) => stopRecording(handle).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
63394
- ).orElse(
63395
- (error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0, import_neverthrow19.errAsync)(error48)).orElse(() => (0, import_neverthrow19.errAsync)(error48))
63396
- );
63397
- }
63398
63409
 
63399
63410
  // ../../packages/pipeline/dist/index.js
63400
- var import_neverthrow33 = __toESM(require_index_cjs(), 1);
63411
+ var import_neverthrow34 = __toESM(require_index_cjs(), 1);
63401
63412
 
63402
63413
  // ../../agents/inspector/dist/index.js
63403
- var import_neverthrow22 = __toESM(require_index_cjs(), 1);
63404
- var import_promises12 = require("node:fs/promises");
63405
63414
  var import_neverthrow23 = __toESM(require_index_cjs(), 1);
63415
+ var import_promises12 = require("node:fs/promises");
63406
63416
  var import_neverthrow24 = __toESM(require_index_cjs(), 1);
63407
63417
  var import_neverthrow25 = __toESM(require_index_cjs(), 1);
63408
63418
  var import_neverthrow26 = __toESM(require_index_cjs(), 1);
63409
- var import_sharp2 = __toESM(require("sharp"), 1);
63410
63419
  var import_neverthrow27 = __toESM(require_index_cjs(), 1);
63420
+ var import_sharp2 = __toESM(require("sharp"), 1);
63421
+ var import_neverthrow28 = __toESM(require_index_cjs(), 1);
63411
63422
  var import_promises13 = require("node:fs/promises");
63412
63423
  var import_node_path7 = __toESM(require("node:path"), 1);
63413
63424
 
@@ -66036,7 +66047,7 @@ var jsYaml = {
66036
66047
  };
66037
66048
 
66038
66049
  // ../../agents/inspector/dist/index.js
66039
- var import_neverthrow28 = __toESM(require_index_cjs(), 1);
66050
+ var import_neverthrow29 = __toESM(require_index_cjs(), 1);
66040
66051
  var MS_PER_DAY = 864e5;
66041
66052
  function checkStaleness({ lastUpdated, thresholdDays, now }) {
66042
66053
  if (!lastUpdated) {
@@ -66113,7 +66124,7 @@ function mapRawFinding(item) {
66113
66124
  function parseJson(raw) {
66114
66125
  return JSON.parse(raw);
66115
66126
  }
66116
- var safeJsonParse3 = (0, import_neverthrow25.fromThrowable)(parseJson);
66127
+ var safeJsonParse3 = (0, import_neverthrow26.fromThrowable)(parseJson);
66117
66128
  function parseClaudeResponse(raw) {
66118
66129
  const parseResult = safeJsonParse3(raw);
66119
66130
  if (parseResult.isErr()) {
@@ -66140,7 +66151,7 @@ async function downscaleBuffer(buffer) {
66140
66151
  return (0, import_sharp2.default)(buffer).resize({ width: targetWidth }).toBuffer();
66141
66152
  }
66142
66153
  function downscale(buffer) {
66143
- return (0, import_neverthrow26.fromAsyncThrowable)(
66154
+ return (0, import_neverthrow27.fromAsyncThrowable)(
66144
66155
  downscaleBuffer,
66145
66156
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66146
66157
  )(buffer);
@@ -66215,7 +66226,7 @@ async function fetchClaudeText({
66215
66226
  return block?.type === "text" ? block.text : "";
66216
66227
  }
66217
66228
  function callClaude(options) {
66218
- return (0, import_neverthrow24.fromAsyncThrowable)(
66229
+ return (0, import_neverthrow25.fromAsyncThrowable)(
66219
66230
  fetchClaudeText,
66220
66231
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66221
66232
  )(options);
@@ -66227,9 +66238,9 @@ function toFindings(text) {
66227
66238
  const cleaned = stripCodeFences(text);
66228
66239
  const findings = parseClaudeResponse(cleaned);
66229
66240
  if (!findings) {
66230
- return (0, import_neverthrow24.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: cleaned });
66241
+ return (0, import_neverthrow25.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: cleaned });
66231
66242
  }
66232
- return (0, import_neverthrow24.okAsync)(findings);
66243
+ return (0, import_neverthrow25.okAsync)(findings);
66233
66244
  }
66234
66245
  function buildResolveMessages(screenshotBase64, artboardNames) {
66235
66246
  return [
@@ -66266,12 +66277,12 @@ async function fetchResolveName({
66266
66277
  }
66267
66278
  function resolveArtboard(screenshot, artboardNames) {
66268
66279
  if (artboardNames.length === 0) {
66269
- return (0, import_neverthrow24.okAsync)(void 0);
66280
+ return (0, import_neverthrow25.okAsync)(void 0);
66270
66281
  }
66271
66282
  const anthropic = new Anthropic();
66272
66283
  return downscale(screenshot).andThen((scaled) => {
66273
66284
  const screenshotBase64 = scaled.toString("base64");
66274
- return (0, import_neverthrow24.fromAsyncThrowable)(
66285
+ return (0, import_neverthrow25.fromAsyncThrowable)(
66275
66286
  fetchResolveName,
66276
66287
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66277
66288
  )({ anthropic, screenshotBase64, artboardNames }).map((name) => {
@@ -66334,7 +66345,7 @@ var SEVERITY_CONFIDENCE = {
66334
66345
  medium: CONFIDENCE_MEDIUM2,
66335
66346
  low: CONFIDENCE_LOW2
66336
66347
  };
66337
- var safeJsonParse22 = (0, import_neverthrow27.fromThrowable)(JSON.parse);
66348
+ var safeJsonParse22 = (0, import_neverthrow28.fromThrowable)(JSON.parse);
66338
66349
  function buildFindCandidatesMessages(screenshotBase64, artboardNames) {
66339
66350
  return [
66340
66351
  {
@@ -66381,12 +66392,12 @@ async function fetchCandidateNames({
66381
66392
  }
66382
66393
  function findCandidates(screenshot, artboardNames) {
66383
66394
  if (artboardNames.length === 0) {
66384
- return (0, import_neverthrow27.okAsync)([]);
66395
+ return (0, import_neverthrow28.okAsync)([]);
66385
66396
  }
66386
66397
  const anthropic = new Anthropic();
66387
66398
  return downscale(screenshot).andThen((scaled) => {
66388
66399
  const screenshotBase64 = scaled.toString("base64");
66389
- return (0, import_neverthrow27.fromAsyncThrowable)(
66400
+ return (0, import_neverthrow28.fromAsyncThrowable)(
66390
66401
  fetchCandidateNames,
66391
66402
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66392
66403
  )({ anthropic, screenshotBase64, artboardNames });
@@ -66473,14 +66484,14 @@ async function fetchDesignContextText({
66473
66484
  function toDesignContextFindings(text) {
66474
66485
  const findings = parseConservativeResponse(text);
66475
66486
  if (!findings) {
66476
- return (0, import_neverthrow27.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: text });
66487
+ return (0, import_neverthrow28.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: text });
66477
66488
  }
66478
- return (0, import_neverthrow27.okAsync)(findings);
66489
+ return (0, import_neverthrow28.okAsync)(findings);
66479
66490
  }
66480
66491
  async function downscaleAll(buffers) {
66481
66492
  return Promise.all(buffers.map(async (buf) => downscaleBuffer(buf)));
66482
66493
  }
66483
- var downscaleAllBuffers = (0, import_neverthrow27.fromAsyncThrowable)(
66494
+ var downscaleAllBuffers = (0, import_neverthrow28.fromAsyncThrowable)(
66484
66495
  downscaleAll,
66485
66496
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66486
66497
  );
@@ -66490,7 +66501,7 @@ function compareWithDesignContext(screenshot, artboards) {
66490
66501
  const screenshotBase64 = scaledScreenshot.toString("base64");
66491
66502
  return downscaleAllBuffers(artboards).andThen((scaledArtboards) => {
66492
66503
  const artboardBase64s = scaledArtboards.map((buf) => buf.toString("base64"));
66493
- return (0, import_neverthrow27.fromAsyncThrowable)(
66504
+ return (0, import_neverthrow28.fromAsyncThrowable)(
66494
66505
  fetchDesignContextText,
66495
66506
  (cause) => ({ type: "CLAUDE_API_FAILED", cause })
66496
66507
  )({ anthropic, screenshotBase64, artboardBase64s }).andThen(toDesignContextFindings);
@@ -66723,7 +66734,7 @@ async function initArtboardNames({ designStore, config: config3, state }) {
66723
66734
  return state.artboardNamesPromise;
66724
66735
  }
66725
66736
  function readScreenshot(screenshotPath, stepIndex) {
66726
- return import_neverthrow23.ResultAsync.fromThrowable(
66737
+ return import_neverthrow24.ResultAsync.fromThrowable(
66727
66738
  import_promises12.readFile,
66728
66739
  (cause) => ({ type: "SCREENSHOT_READ_FAILED", stepIndex, cause })
66729
66740
  )(screenshotPath);
@@ -66799,7 +66810,7 @@ function buildInspector(state, context) {
66799
66810
  const { promise: promise2, resolve } = Promise.withResolvers();
66800
66811
  state.resolve = resolve;
66801
66812
  applyTryResolve(state);
66802
- return (0, import_neverthrow22.fromSafePromise)(promise2);
66813
+ return (0, import_neverthrow23.fromSafePromise)(promise2);
66803
66814
  }
66804
66815
  };
66805
66816
  }
@@ -66823,10 +66834,10 @@ async function readAndParseSidecar(sidecarPath) {
66823
66834
  return parseMeta(raw);
66824
66835
  }
66825
66836
  function readSidecarFile(sidecarPath) {
66826
- return (0, import_neverthrow28.fromAsyncThrowable)(
66837
+ return (0, import_neverthrow29.fromAsyncThrowable)(
66827
66838
  readAndParseSidecar,
66828
66839
  () => ({})
66829
- )(sidecarPath).orElse(() => (0, import_neverthrow28.okAsync)({}));
66840
+ )(sidecarPath).orElse(() => (0, import_neverthrow29.okAsync)({}));
66830
66841
  }
66831
66842
  function isEnoent(error48) {
66832
66843
  return error48?.code === "ENOENT";
@@ -66835,13 +66846,13 @@ function wrapFsError(cause) {
66835
66846
  return { type: "FS_ERROR", cause };
66836
66847
  }
66837
66848
  function toFsError(fsError) {
66838
- return (0, import_neverthrow28.errAsync)(fsError);
66849
+ return (0, import_neverthrow29.errAsync)(fsError);
66839
66850
  }
66840
66851
  function missingBuffer() {
66841
- return (0, import_neverthrow28.okAsync)(void 0);
66852
+ return (0, import_neverthrow29.okAsync)(void 0);
66842
66853
  }
66843
66854
  function missingArtboard() {
66844
- return (0, import_neverthrow28.okAsync)(void 0);
66855
+ return (0, import_neverthrow29.okAsync)(void 0);
66845
66856
  }
66846
66857
  var FsDesignStore = class {
66847
66858
  designsDirectory;
@@ -66849,12 +66860,12 @@ var FsDesignStore = class {
66849
66860
  this.designsDirectory = designsDirectory;
66850
66861
  }
66851
66862
  listArtboards() {
66852
- return (0, import_neverthrow28.fromAsyncThrowable)(
66863
+ return (0, import_neverthrow29.fromAsyncThrowable)(
66853
66864
  import_promises13.readdir,
66854
66865
  wrapFsError
66855
66866
  )(this.designsDirectory).orElse((fsError) => {
66856
66867
  if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
66857
- return (0, import_neverthrow28.okAsync)([]);
66868
+ return (0, import_neverthrow29.okAsync)([]);
66858
66869
  }
66859
66870
  return toFsError(fsError);
66860
66871
  }).map(
@@ -66864,7 +66875,7 @@ var FsDesignStore = class {
66864
66875
  getArtboard(filename) {
66865
66876
  const pngPath = import_node_path7.default.join(this.designsDirectory, `${filename}.png`);
66866
66877
  const sidecarPath = import_node_path7.default.join(this.designsDirectory, `${filename}.meta.yaml`);
66867
- return (0, import_neverthrow28.fromAsyncThrowable)(
66878
+ return (0, import_neverthrow29.fromAsyncThrowable)(
66868
66879
  import_promises13.readFile,
66869
66880
  wrapFsError
66870
66881
  )(pngPath).orElse((fsError) => {
@@ -66890,10 +66901,10 @@ function attemptRetry(options) {
66890
66901
  const { factory, config: config3, delayFunction, onRetry, attempt } = options;
66891
66902
  return factory().orElse((error48) => {
66892
66903
  if (attempt >= config3.maxAttempts) {
66893
- return (0, import_neverthrow31.errAsync)(error48);
66904
+ return (0, import_neverthrow32.errAsync)(error48);
66894
66905
  }
66895
66906
  const delay = config3.baseDelayMs * Math.pow(2, attempt - 1);
66896
- return import_neverthrow31.ResultAsync.fromPromise(
66907
+ return import_neverthrow32.ResultAsync.fromPromise(
66897
66908
  (onRetry?.({ attempt, maxAttempts: config3.maxAttempts, delayMs: delay, error: error48 }), delayFunction(delay)),
66898
66909
  () => error48
66899
66910
  ).andThen(
@@ -66913,7 +66924,7 @@ function withRetry(factory, options) {
66913
66924
  var CONSOLIDATOR_AGENT = "consolidator";
66914
66925
  function analyserFallback(artifacts, onEvent) {
66915
66926
  onEvent?.({ type: "AGENT_FAILED_NON_CRITICAL", agent: "analyser", attempts: RETRY_MAX_ATTEMPTS });
66916
- return (0, import_neverthrow30.okAsync)(artifacts.findings);
66927
+ return (0, import_neverthrow31.okAsync)(artifacts.findings);
66917
66928
  }
66918
66929
  function runAnalyserWithRetry(params) {
66919
66930
  const { artifacts, config: config3, onEvent } = params;
@@ -66943,7 +66954,7 @@ function resolveVisualFindings({
66943
66954
  onEvent
66944
66955
  }) {
66945
66956
  if (config3.analyser === void 0 || config3.signal?.aborted) {
66946
- return (0, import_neverthrow30.okAsync)(artifacts.findings);
66957
+ return (0, import_neverthrow31.okAsync)(artifacts.findings);
66947
66958
  }
66948
66959
  return runAnalyserWithRetry({ artifacts, config: config3, onEvent });
66949
66960
  }
@@ -66953,7 +66964,7 @@ function unmergedFallback(allFindings, onEvent) {
66953
66964
  agent: CONSOLIDATOR_AGENT,
66954
66965
  message: "Consolidation failed, returning unmerged findings"
66955
66966
  });
66956
- return (0, import_neverthrow30.okAsync)({ findings: allFindings, dismissed: [] });
66967
+ return (0, import_neverthrow31.okAsync)({ findings: allFindings, dismissed: [] });
66957
66968
  }
66958
66969
  function mergeWithFallback(options) {
66959
66970
  const {
@@ -66980,7 +66991,7 @@ function consolidate(options) {
66980
66991
  const { artifacts, inspectorFindings, runId, dismissals, config: config3, consolidatorConfig, onEvent } = options;
66981
66992
  return resolveVisualFindings({ artifacts, config: config3, onEvent }).andThen((visualFindings) => {
66982
66993
  if (config3.signal?.aborted) {
66983
- return (0, import_neverthrow30.okAsync)({ findings: artifacts.findings, dismissed: [] });
66994
+ return (0, import_neverthrow31.okAsync)({ findings: artifacts.findings, dismissed: [] });
66984
66995
  }
66985
66996
  return mergeWithFallback({
66986
66997
  artifacts,
@@ -66993,8 +67004,8 @@ function consolidate(options) {
66993
67004
  });
66994
67005
  });
66995
67006
  }
66996
- var safeReadFile = (0, import_neverthrow32.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
66997
- var safeParseJson2 = (0, import_neverthrow32.fromThrowable)(JSON.parse);
67007
+ var safeReadFile = (0, import_neverthrow33.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
67008
+ var safeParseJson2 = (0, import_neverthrow33.fromThrowable)(JSON.parse);
66998
67009
  function isEnoent2(error48) {
66999
67010
  if (!(error48 instanceof Error)) {
67000
67011
  return false;
@@ -67006,19 +67017,19 @@ function loadDismissals(filePath) {
67006
67017
  const readResult = safeReadFile(filePath);
67007
67018
  if (readResult.isErr()) {
67008
67019
  if (isEnoent2(readResult.error)) {
67009
- return (0, import_neverthrow32.ok)([]);
67020
+ return (0, import_neverthrow33.ok)([]);
67010
67021
  }
67011
- return (0, import_neverthrow32.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
67022
+ return (0, import_neverthrow33.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
67012
67023
  }
67013
67024
  return safeParseJson2(readResult.value).mapErr((cause) => ({ type: "DISMISSALS_LOAD_FAILED", cause })).andThen((data) => {
67014
67025
  const store = data;
67015
67026
  if (!Array.isArray(store.dismissed)) {
67016
- return (0, import_neverthrow32.err)({
67027
+ return (0, import_neverthrow33.err)({
67017
67028
  type: "DISMISSALS_LOAD_FAILED",
67018
67029
  cause: "invalid shape: dismissed is not an array"
67019
67030
  });
67020
67031
  }
67021
- return (0, import_neverthrow32.ok)(store.dismissed);
67032
+ return (0, import_neverthrow33.ok)(store.dismissed);
67022
67033
  });
67023
67034
  }
67024
67035
  function toInspectorStepEvent(event) {
@@ -67105,7 +67116,7 @@ function runExplorerWithTeardown(explorerConfig, udid) {
67105
67116
  return runExplorer(explorerConfig).mapErr((cause) => ({ type: "EXPLORER_FAILED", cause })).andThen(
67106
67117
  (artifacts) => disableTouchIndicators(udid).mapErr(toSimulatorError).map(() => artifacts)
67107
67118
  ).orElse(
67108
- (error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow33.errAsync)(error48)).orElse(() => (0, import_neverthrow33.errAsync)(error48))
67119
+ (error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow34.errAsync)(error48)).orElse(() => (0, import_neverthrow34.errAsync)(error48))
67109
67120
  );
67110
67121
  }
67111
67122
  function runExplorerWithRetry(options) {
@@ -67131,12 +67142,12 @@ async function drainAfterExplorer(options) {
67131
67142
  inspector?.close();
67132
67143
  const inspectorFindings = inspector ? await collectInspectorFindings({ inspector, onEvent, totalSteps: enqueuedCount.value }) : [];
67133
67144
  if (explorerResult.isErr()) {
67134
- return (0, import_neverthrow33.err)(explorerResult.error);
67145
+ return (0, import_neverthrow34.err)(explorerResult.error);
67135
67146
  }
67136
- return (0, import_neverthrow33.ok)({ artifacts: explorerResult.value, inspectorFindings });
67147
+ return (0, import_neverthrow34.ok)({ artifacts: explorerResult.value, inspectorFindings });
67137
67148
  }
67138
67149
  function runExplorerAndDrain(options) {
67139
- return new import_neverthrow33.ResultAsync(drainAfterExplorer(options));
67150
+ return new import_neverthrow34.ResultAsync(drainAfterExplorer(options));
67140
67151
  }
67141
67152
  function createDefaultMcpServers(udid) {
67142
67153
  return {
@@ -67148,7 +67159,7 @@ function runAnalysis(artifacts, config3) {
67148
67159
  }
67149
67160
  var ISO_DATE_LENGTH2 = 10;
67150
67161
  var RUN_ID_PAD_LENGTH = 4;
67151
- var safeReaddirSync = (0, import_neverthrow29.fromThrowable)((directory) => (0, import_node_fs2.readdirSync)(directory));
67162
+ var safeReaddirSync = (0, import_neverthrow30.fromThrowable)((directory) => (0, import_node_fs2.readdirSync)(directory));
67152
67163
  function nextRunId(outputDirectory, date5) {
67153
67164
  const entries = safeReaddirSync(`${outputDirectory}/${date5}`).unwrapOr([]);
67154
67165
  let max = 0;
@@ -67160,7 +67171,7 @@ function nextRunId(outputDirectory, date5) {
67160
67171
  }
67161
67172
  return String(max + 1).padStart(RUN_ID_PAD_LENGTH, "0");
67162
67173
  }
67163
- var writeOutputFile = (0, import_neverthrow29.fromThrowable)(
67174
+ var writeOutputFile = (0, import_neverthrow30.fromThrowable)(
67164
67175
  (params) => {
67165
67176
  const { findingsPath, outputDirectory, json: json3 } = params;
67166
67177
  (0, import_node_fs2.mkdirSync)(outputDirectory, { recursive: true });
@@ -67173,15 +67184,15 @@ function validatePipelineConfig(config3) {
67173
67184
  const runId = config3.runId ?? nextRunId(config3.outputDir, date5);
67174
67185
  const runPathsResult = resolveRunPaths({ outputDirectory: config3.outputDir, runId, date: date5 });
67175
67186
  if (runPathsResult.isErr()) {
67176
- return (0, import_neverthrow29.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
67187
+ return (0, import_neverthrow30.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
67177
67188
  }
67178
67189
  const dismissalsResult = loadDismissals(
67179
67190
  dismissalsPath(config3.outputDir, process.env.QA_DISMISSALS_PATH)
67180
67191
  );
67181
67192
  if (dismissalsResult.isErr()) {
67182
- return (0, import_neverthrow29.err)(dismissalsResult.error);
67193
+ return (0, import_neverthrow30.err)(dismissalsResult.error);
67183
67194
  }
67184
- return (0, import_neverthrow29.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
67195
+ return (0, import_neverthrow30.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
67185
67196
  }
67186
67197
  function buildExplorerConfig({
67187
67198
  config: config3,
@@ -67196,7 +67207,8 @@ function buildExplorerConfig({
67196
67207
  date: date5,
67197
67208
  onEvent,
67198
67209
  signal: config3.signal,
67199
- udid: config3.simulatorUdid ?? "booted"
67210
+ udid: config3.simulatorUdid ?? "booted",
67211
+ record: config3.explorer.record ?? config3.analyser !== void 0
67200
67212
  };
67201
67213
  }
67202
67214
  function buildOutput(consolidationResult, options) {
@@ -67217,11 +67229,11 @@ function buildOutput(consolidationResult, options) {
67217
67229
  function buildPipelineSetup(config3) {
67218
67230
  const validatedResult = validatePipelineConfig(config3);
67219
67231
  if (validatedResult.isErr()) {
67220
- return (0, import_neverthrow29.err)(validatedResult.error);
67232
+ return (0, import_neverthrow30.err)(validatedResult.error);
67221
67233
  }
67222
67234
  const { runId, date: date5, runPaths, dismissals } = validatedResult.value;
67223
67235
  const { inspector, explorerOnEvent, enqueuedCount } = buildInspectorSetup(config3);
67224
- return (0, import_neverthrow29.ok)({
67236
+ return (0, import_neverthrow30.ok)({
67225
67237
  runId,
67226
67238
  udid: config3.simulatorUdid ?? "booted",
67227
67239
  runPaths,
@@ -67265,19 +67277,19 @@ function executePipeline(setup, config3) {
67265
67277
  function runPipeline2(config3) {
67266
67278
  const setupResult = buildPipelineSetup(config3);
67267
67279
  if (setupResult.isErr()) {
67268
- return (0, import_neverthrow29.errAsync)(setupResult.error);
67280
+ return (0, import_neverthrow30.errAsync)(setupResult.error);
67269
67281
  }
67270
67282
  return executePipeline(setupResult.value, config3);
67271
67283
  }
67272
67284
 
67273
67285
  // src/commands/analyse-command.ts
67274
- var import_neverthrow34 = __toESM(require_index_cjs(), 1);
67286
+ var import_neverthrow35 = __toESM(require_index_cjs(), 1);
67275
67287
 
67276
67288
  // src/commands/item-events.ts
67277
67289
  function emitItemStart(identity, at) {
67278
- const { display, itemId, itemName } = identity;
67290
+ const { display, itemId, itemName, simulatorUdid } = identity;
67279
67291
  display.onEvent({ type: "ITEM_QUEUED", item: { id: itemId, name: itemName } });
67280
- display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid: "", at });
67292
+ display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid, at });
67281
67293
  }
67282
67294
  function emitItemCompleted(input) {
67283
67295
  const { identity, startedAt, findingsCount } = input;
@@ -67346,7 +67358,7 @@ function buildArtifacts(videoPath) {
67346
67358
  return { videoPath, videoPath2x: "", videoPath4x: videoPath, findings: [], snapshots: [] };
67347
67359
  }
67348
67360
  async function checkVideoPathExists(videoPath) {
67349
- const safeAccess = (0, import_neverthrow34.fromAsyncThrowable)(import_promises16.access, () => ({ type: "FILE_NOT_FOUND" }));
67361
+ const safeAccess = (0, import_neverthrow35.fromAsyncThrowable)(import_promises16.access, () => ({ type: "FILE_NOT_FOUND" }));
67350
67362
  const result = await safeAccess(videoPath);
67351
67363
  return result.isOk();
67352
67364
  }
@@ -67371,7 +67383,8 @@ async function runAnalysisAndExit(artifacts, apiKey) {
67371
67383
  const identity = {
67372
67384
  display: createSoloDisplay(),
67373
67385
  itemId: ITEM_ID,
67374
- itemName: ITEM_NAME
67386
+ itemName: ITEM_NAME,
67387
+ simulatorUdid: ""
67375
67388
  };
67376
67389
  const startedAt = Date.now();
67377
67390
  emitItemStart(identity, startedAt);
@@ -67411,7 +67424,7 @@ async function runAnalyseCommand(videoPath, config3) {
67411
67424
  }
67412
67425
 
67413
67426
  // src/core/completion-generator.ts
67414
- var import_neverthrow35 = __toESM(require_index_cjs(), 1);
67427
+ var import_neverthrow36 = __toESM(require_index_cjs(), 1);
67415
67428
  function extractLongFlags(flags) {
67416
67429
  return flags.split(/[\s,]+/).filter((token) => token.startsWith("--"));
67417
67430
  }
@@ -67501,9 +67514,9 @@ complete -F _xqa_completion xqa`;
67501
67514
  }
67502
67515
  function generateCompletion(commands, shell) {
67503
67516
  if (shell !== "bash" && shell !== "zsh") {
67504
- return (0, import_neverthrow35.err)({ type: "UNSUPPORTED_SHELL", shell });
67517
+ return (0, import_neverthrow36.err)({ type: "UNSUPPORTED_SHELL", shell });
67505
67518
  }
67506
- return (0, import_neverthrow35.ok)(shell === "zsh" ? generateZshCompletion(commands) : generateBashCompletion(commands));
67519
+ return (0, import_neverthrow36.ok)(shell === "zsh" ? generateZshCompletion(commands) : generateBashCompletion(commands));
67507
67520
  }
67508
67521
 
67509
67522
  // src/commands/completion-command.ts
@@ -67561,16 +67574,16 @@ var FFMPEG_INSTALL_MESSAGE = "ffmpeg is not installed. Run:\n brew install ffmp
67561
67574
  // src/core/last-path.ts
67562
67575
  var import_node_fs4 = require("node:fs");
67563
67576
  var import_node_path8 = __toESM(require("node:path"), 1);
67564
- var import_neverthrow36 = __toESM(require_index_cjs(), 1);
67577
+ var import_neverthrow37 = __toESM(require_index_cjs(), 1);
67565
67578
  function resolveLastPath(argument, stateContent) {
67566
67579
  if (argument !== void 0) {
67567
- return (0, import_neverthrow36.ok)(argument);
67580
+ return (0, import_neverthrow37.ok)(argument);
67568
67581
  }
67569
67582
  const trimmed = stateContent?.trim();
67570
67583
  if (trimmed) {
67571
- return (0, import_neverthrow36.ok)(trimmed);
67584
+ return (0, import_neverthrow37.ok)(trimmed);
67572
67585
  }
67573
- return (0, import_neverthrow36.err)({ type: "NO_ARG_AND_NO_STATE" });
67586
+ return (0, import_neverthrow37.err)({ type: "NO_ARG_AND_NO_STATE" });
67574
67587
  }
67575
67588
  function lastPathFilePath(xqaDirectoryectory) {
67576
67589
  return import_node_path8.default.join(xqaDirectoryectory, "last-findings-path");
@@ -67582,7 +67595,7 @@ function writeLastPath(xqaDirectory, findingsPath) {
67582
67595
  // src/shell/app-context.ts
67583
67596
  var import_promises17 = require("node:fs/promises");
67584
67597
  var import_node_path9 = __toESM(require("node:path"), 1);
67585
- var import_neverthrow37 = __toESM(require_index_cjs(), 1);
67598
+ var import_neverthrow38 = __toESM(require_index_cjs(), 1);
67586
67599
  var HTML_COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
67587
67600
  function isEnoentError(value) {
67588
67601
  return value !== null && typeof value === "object" && "code" in value && value.code === "ENOENT";
@@ -67592,9 +67605,9 @@ function toAppContextError(cause) {
67592
67605
  }
67593
67606
  function absentContext() {
67594
67607
  const absent = void 0;
67595
- return (0, import_neverthrow37.ok)(absent);
67608
+ return (0, import_neverthrow38.ok)(absent);
67596
67609
  }
67597
- var safeReadFile2 = import_neverthrow37.ResultAsync.fromThrowable(
67610
+ var safeReadFile2 = import_neverthrow38.ResultAsync.fromThrowable(
67598
67611
  async (filePath) => (0, import_promises17.readFile)(filePath, "utf8"),
67599
67612
  toAppContextError
67600
67613
  );
@@ -67608,7 +67621,7 @@ function readContextFile(xqaDirectory, filename) {
67608
67621
  if (isEnoentError(error48.cause)) {
67609
67622
  return absentContext();
67610
67623
  }
67611
- return (0, import_neverthrow37.err)(error48);
67624
+ return (0, import_neverthrow38.err)(error48);
67612
67625
  });
67613
67626
  }
67614
67627
  function readAppContext(xqaDirectory) {
@@ -67620,7 +67633,7 @@ function readExploreContext(xqaDirectory) {
67620
67633
 
67621
67634
  // src/shell/ffmpeg-check.ts
67622
67635
  var import_node_child_process5 = require("node:child_process");
67623
- var import_neverthrow38 = __toESM(require_index_cjs(), 1);
67636
+ var import_neverthrow39 = __toESM(require_index_cjs(), 1);
67624
67637
  async function whichFfmpeg() {
67625
67638
  const { promise: promise2, resolve, reject } = Promise.withResolvers();
67626
67639
  (0, import_node_child_process5.execFile)("which", ["ffmpeg"], (error48, stdout) => {
@@ -67632,7 +67645,7 @@ async function whichFfmpeg() {
67632
67645
  });
67633
67646
  return promise2;
67634
67647
  }
67635
- var safeWhichFfmpeg = (0, import_neverthrow38.fromAsyncThrowable)(
67648
+ var safeWhichFfmpeg = (0, import_neverthrow39.fromAsyncThrowable)(
67636
67649
  whichFfmpeg,
67637
67650
  () => ({ type: "FFMPEG_NOT_FOUND" })
67638
67651
  );
@@ -67680,11 +67693,13 @@ function buildPipelineConfig({
67680
67693
  config: config3,
67681
67694
  xqaDirectory,
67682
67695
  explorer,
67683
- onEvent
67696
+ onEvent,
67697
+ simulatorUdid
67684
67698
  }) {
67685
67699
  const base = {
67686
67700
  outputDir: import_node_path10.default.join(xqaDirectory, "output"),
67687
67701
  runId: config3.QA_RUN_ID,
67702
+ simulatorUdid,
67688
67703
  onEvent,
67689
67704
  signal: input.signal,
67690
67705
  inspector: { designsDirectory: import_node_path10.default.join(xqaDirectory, "designs") },
@@ -67705,7 +67720,9 @@ function buildSuccessMessage(output) {
67705
67720
  `;
67706
67721
  }
67707
67722
  var ITEM_ID2 = "explore";
67708
- var ITEM_NAME2 = "explore";
67723
+ function buildItemName(simulatorUdid) {
67724
+ return `${simulatorUdid} - explorer`;
67725
+ }
67709
67726
  function buildSuccessHandler({ input, xqaDirectory, identity, startedAt }) {
67710
67727
  return (output) => {
67711
67728
  emitItemCompleted({ identity, startedAt, findingsCount: output.findings.length });
@@ -67740,7 +67757,7 @@ ${cause}
67740
67757
  };
67741
67758
  }
67742
67759
  function runExplorePipeline(state, contexts) {
67743
- const { input, config: config3, xqaDirectory, onEvent, onSuccess, onError } = state;
67760
+ const { input, config: config3, xqaDirectory, onEvent, onSuccess, onError, simulatorUdid } = state;
67744
67761
  const explorerConfig = buildExplorerConfig2({
67745
67762
  input,
67746
67763
  config: config3,
@@ -67748,14 +67765,22 @@ function runExplorePipeline(state, contexts) {
67748
67765
  initialState: contexts.exploreContext
67749
67766
  });
67750
67767
  void runPipeline2(
67751
- buildPipelineConfig({ input, config: config3, xqaDirectory, explorer: explorerConfig, onEvent })
67768
+ buildPipelineConfig({
67769
+ input,
67770
+ config: config3,
67771
+ xqaDirectory,
67772
+ explorer: explorerConfig,
67773
+ onEvent,
67774
+ simulatorUdid
67775
+ })
67752
67776
  ).match(onSuccess, onError);
67753
67777
  }
67754
67778
  function buildExploreRunState({
67755
67779
  input,
67756
67780
  options,
67757
67781
  identity,
67758
- startedAt
67782
+ startedAt,
67783
+ simulatorUdid
67759
67784
  }) {
67760
67785
  const { config: config3, xqaDirectory } = options;
67761
67786
  const onEvent = (event) => {
@@ -67763,17 +67788,32 @@ function buildExploreRunState({
67763
67788
  };
67764
67789
  const onSuccess = buildSuccessHandler({ input, xqaDirectory, identity, startedAt });
67765
67790
  const onError = buildErrorHandler(identity, startedAt);
67766
- return { input, config: config3, xqaDirectory, onEvent, onSuccess, onError };
67791
+ return { input, config: config3, xqaDirectory, onEvent, onSuccess, onError, simulatorUdid };
67767
67792
  }
67768
- function runPipelineAfterPreflight({ input, options }) {
67793
+ async function resolveSimulatorUdid() {
67794
+ const result = await discoverBootedSimulators();
67795
+ if (result.isErr()) {
67796
+ process.stderr.write(`Failed to discover simulators: ${String(result.error.cause)}
67797
+ `);
67798
+ return;
67799
+ }
67800
+ const first = result.value[0];
67801
+ if (!first) {
67802
+ process.stderr.write("No booted simulators found\n");
67803
+ return;
67804
+ }
67805
+ return first.udid;
67806
+ }
67807
+ function runPipelineAfterPreflight({ input, options }, simulatorUdid) {
67769
67808
  const identity = {
67770
67809
  display: createSoloDisplay(input.verbose),
67771
67810
  itemId: ITEM_ID2,
67772
- itemName: ITEM_NAME2
67811
+ itemName: buildItemName(simulatorUdid),
67812
+ simulatorUdid
67773
67813
  };
67774
67814
  const startedAt = Date.now();
67775
67815
  emitItemStart(identity, startedAt);
67776
- const state = buildExploreRunState({ input, options, identity, startedAt });
67816
+ const state = buildExploreRunState({ input, options, identity, startedAt, simulatorUdid });
67777
67817
  void readAppContext(options.xqaDirectory).andThen(
67778
67818
  (appContext) => readExploreContext(options.xqaDirectory).map((exploreContext) => ({
67779
67819
  appContext,
@@ -67789,7 +67829,12 @@ async function runExploreAfterPreflight(context) {
67789
67829
  process.exit(preflightExit);
67790
67830
  return;
67791
67831
  }
67792
- runPipelineAfterPreflight(context);
67832
+ const simulatorUdid = await resolveSimulatorUdid();
67833
+ if (simulatorUdid === void 0) {
67834
+ process.exit(2);
67835
+ return;
67836
+ }
67837
+ runPipelineAfterPreflight(context, simulatorUdid);
67793
67838
  }
67794
67839
  function runExploreCommand(input, options) {
67795
67840
  void runExploreAfterPreflight({ input, options });
@@ -67889,7 +67934,7 @@ function runInitCommand() {
67889
67934
  // src/commands/review-command.ts
67890
67935
  var import_node_fs7 = require("node:fs");
67891
67936
  var import_node_path14 = __toESM(require("node:path"), 1);
67892
- var import_neverthrow40 = __toESM(require_index_cjs(), 1);
67937
+ var import_neverthrow41 = __toESM(require_index_cjs(), 1);
67893
67938
 
67894
67939
  // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@22.19.15/node_modules/@inquirer/core/dist/esm/lib/key.js
67895
67940
  var isUpKey = (key, keybindings = []) => (
@@ -70294,7 +70339,7 @@ var esm_default11 = createPrompt((config3, done) => {
70294
70339
  });
70295
70340
 
70296
70341
  // src/review-session.ts
70297
- var import_neverthrow39 = __toESM(require_index_cjs(), 1);
70342
+ var import_neverthrow40 = __toESM(require_index_cjs(), 1);
70298
70343
  var CONFIDENCE_PERCENT = 100;
70299
70344
  var FLOW_COL_WIDTH = 35;
70300
70345
  var TRIGGER_COL_WIDTH = 16;
@@ -70447,15 +70492,15 @@ async function runInteractiveLoop(findings, existing) {
70447
70492
  }
70448
70493
  return { staged: state.staged, undoneKeys: state.undoneKeys };
70449
70494
  }
70450
- var safeRunInteractiveLoop = (0, import_neverthrow39.fromAsyncThrowable)(
70495
+ var safeRunInteractiveLoop = (0, import_neverthrow40.fromAsyncThrowable)(
70451
70496
  runInteractiveLoop,
70452
70497
  (error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "exit-prompt" : "unexpected"
70453
70498
  );
70454
70499
 
70455
70500
  // src/commands/review-command.ts
70456
- var safeReadFile3 = (0, import_neverthrow40.fromThrowable)((filePath) => (0, import_node_fs7.readFileSync)(filePath, "utf8"));
70457
- var safeParseJson3 = (0, import_neverthrow40.fromThrowable)(JSON.parse);
70458
- var safeWrite = (0, import_neverthrow40.fromThrowable)((filePath, content) => {
70501
+ var safeReadFile3 = (0, import_neverthrow41.fromThrowable)((filePath) => (0, import_node_fs7.readFileSync)(filePath, "utf8"));
70502
+ var safeParseJson3 = (0, import_neverthrow41.fromThrowable)(JSON.parse);
70503
+ var safeWrite = (0, import_neverthrow41.fromThrowable)((filePath, content) => {
70459
70504
  (0, import_node_fs7.writeFileSync)(filePath, content);
70460
70505
  });
70461
70506
  function readLastPath(xqaDirectory) {
@@ -70472,13 +70517,13 @@ function isPipelineOutput(data) {
70472
70517
  function readFindings(filePath) {
70473
70518
  const readResult = safeReadFile3(filePath);
70474
70519
  if (readResult.isErr()) {
70475
- return (0, import_neverthrow40.err)("not-found");
70520
+ return (0, import_neverthrow41.err)("not-found");
70476
70521
  }
70477
70522
  return safeParseJson3(readResult.value).mapErr(() => "invalid").andThen((data) => {
70478
70523
  if (!isPipelineOutput(data)) {
70479
- return (0, import_neverthrow40.err)("invalid");
70524
+ return (0, import_neverthrow41.err)("invalid");
70480
70525
  }
70481
- return (0, import_neverthrow40.ok)(data);
70526
+ return (0, import_neverthrow41.ok)(data);
70482
70527
  });
70483
70528
  }
70484
70529
  function loadExistingDismissals(filePath) {
@@ -70551,7 +70596,7 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
70551
70596
  "No findings path provided and no last path found. Run: xqa review <findings-path>\n"
70552
70597
  );
70553
70598
  process.exit(1);
70554
- return (0, import_neverthrow40.err)();
70599
+ return (0, import_neverthrow41.err)();
70555
70600
  }
70556
70601
  const resolvedPath = resolvedPathResult.value;
70557
70602
  const findingsResult = readFindings(resolvedPath);
@@ -70564,9 +70609,9 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
70564
70609
  `);
70565
70610
  }
70566
70611
  process.exit(1);
70567
- return (0, import_neverthrow40.err)();
70612
+ return (0, import_neverthrow41.err)();
70568
70613
  }
70569
- return (0, import_neverthrow40.ok)({ resolvedPath, output: findingsResult.value });
70614
+ return (0, import_neverthrow41.ok)({ resolvedPath, output: findingsResult.value });
70570
70615
  }
70571
70616
  async function runReviewLoop({
70572
70617
  findings,
@@ -70640,40 +70685,40 @@ function stripExtensions(filename) {
70640
70685
  // src/commands/spec-resolver.ts
70641
70686
  var import_node_fs8 = require("node:fs");
70642
70687
  var import_node_path16 = __toESM(require("node:path"), 1);
70643
- var import_neverthrow42 = __toESM(require_index_cjs(), 1);
70688
+ var import_neverthrow43 = __toESM(require_index_cjs(), 1);
70644
70689
 
70645
70690
  // src/spec-frontmatter.ts
70646
- var import_neverthrow41 = __toESM(require_index_cjs(), 1);
70691
+ var import_neverthrow42 = __toESM(require_index_cjs(), 1);
70647
70692
  var FRONTMATTER_OPEN_LEN = 4;
70648
70693
  var FRONTMATTER_MARKER_LEN = 3;
70649
70694
  function extractFrontmatterBlock(content) {
70650
70695
  const normalized = content.replaceAll("\r\n", "\n");
70651
70696
  if (!normalized.startsWith("---")) {
70652
- return (0, import_neverthrow41.err)({ type: "MISSING_FRONTMATTER" });
70697
+ return (0, import_neverthrow42.err)({ type: "MISSING_FRONTMATTER" });
70653
70698
  }
70654
70699
  const end = normalized.indexOf("\n---", FRONTMATTER_MARKER_LEN);
70655
70700
  if (end === -1) {
70656
- return (0, import_neverthrow41.err)({ type: "MISSING_FRONTMATTER" });
70701
+ return (0, import_neverthrow42.err)({ type: "MISSING_FRONTMATTER" });
70657
70702
  }
70658
- return (0, import_neverthrow41.ok)(normalized.slice(FRONTMATTER_OPEN_LEN, end));
70703
+ return (0, import_neverthrow42.ok)(normalized.slice(FRONTMATTER_OPEN_LEN, end));
70659
70704
  }
70660
70705
  function parseTimeout(fields) {
70661
70706
  const raw = fields.get("timeout");
70662
70707
  if (raw === void 0) {
70663
- return (0, import_neverthrow41.ok)(raw);
70708
+ return (0, import_neverthrow42.ok)(raw);
70664
70709
  }
70665
70710
  const parsed = Number(raw);
70666
70711
  if (Number.isNaN(parsed) || parsed <= 0) {
70667
- return (0, import_neverthrow41.err)({ type: "PARSE_ERROR", cause: `invalid timeout: ${raw}` });
70712
+ return (0, import_neverthrow42.err)({ type: "PARSE_ERROR", cause: `invalid timeout: ${raw}` });
70668
70713
  }
70669
- return (0, import_neverthrow41.ok)(parsed);
70714
+ return (0, import_neverthrow42.ok)(parsed);
70670
70715
  }
70671
70716
  function parseSpecFrontmatter(content) {
70672
70717
  return extractFrontmatterBlock(content).andThen((block) => {
70673
70718
  const fields = parseYamlFields(block);
70674
70719
  const feature = fields.get("feature");
70675
70720
  if (feature === void 0) {
70676
- return (0, import_neverthrow41.err)({ type: "MISSING_FIELD", field: "feature" });
70721
+ return (0, import_neverthrow42.err)({ type: "MISSING_FIELD", field: "feature" });
70677
70722
  }
70678
70723
  return parseTimeout(fields).map((timeout) => ({ feature, timeout }));
70679
70724
  });
@@ -70695,12 +70740,12 @@ function parseYamlFields(block) {
70695
70740
  }
70696
70741
 
70697
70742
  // src/commands/spec-resolver.ts
70698
- var safeReadFile4 = (0, import_neverthrow42.fromThrowable)((filePath) => (0, import_node_fs8.readFileSync)(filePath, "utf8"));
70699
- var safeReaddir = (0, import_neverthrow42.fromThrowable)(
70743
+ var safeReadFile4 = (0, import_neverthrow43.fromThrowable)((filePath) => (0, import_node_fs8.readFileSync)(filePath, "utf8"));
70744
+ var safeReaddir = (0, import_neverthrow43.fromThrowable)(
70700
70745
  (directory) => (0, import_node_fs8.readdirSync)(directory, { recursive: true, encoding: "utf8" })
70701
70746
  );
70702
70747
  var CANCEL = "xqa:cancel";
70703
- var safeSelect = import_neverthrow42.ResultAsync.fromThrowable(
70748
+ var safeSelect = import_neverthrow43.ResultAsync.fromThrowable(
70704
70749
  esm_default11,
70705
70750
  (error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "cancelled" : "failed"
70706
70751
  );
@@ -70819,7 +70864,8 @@ async function executeSpec(input, context) {
70819
70864
  const identity = {
70820
70865
  display: createSoloDisplay(input.verbose),
70821
70866
  itemId: "spec",
70822
- itemName: import_node_path17.default.basename(context.absolutePath, ".test.md")
70867
+ itemName: import_node_path17.default.basename(context.absolutePath, ".test.md"),
70868
+ simulatorUdid: ""
70823
70869
  };
70824
70870
  const startedAt = Date.now();
70825
70871
  emitItemStart(identity, startedAt);
@@ -70887,7 +70933,7 @@ function runUpdateCommand() {
70887
70933
  var import_node_path18 = __toESM(require("node:path"), 1);
70888
70934
  var import_node_url2 = require("node:url");
70889
70935
  var import_dotenv = __toESM(require_main(), 1);
70890
- var import_neverthrow43 = __toESM(require_index_cjs(), 1);
70936
+ var import_neverthrow44 = __toESM(require_index_cjs(), 1);
70891
70937
 
70892
70938
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
70893
70939
  var external_exports2 = {};
@@ -74948,10 +74994,10 @@ function loadConfig() {
74948
74994
  const messages = result.error.issues.map(
74949
74995
  (issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`
74950
74996
  );
74951
- return (0, import_neverthrow43.err)({ type: "INVALID_CONFIG", message: `Configuration error:
74997
+ return (0, import_neverthrow44.err)({ type: "INVALID_CONFIG", message: `Configuration error:
74952
74998
  ${messages.join("\n")}` });
74953
74999
  }
74954
- return (0, import_neverthrow43.ok)(result.data);
75000
+ return (0, import_neverthrow44.ok)(result.data);
74955
75001
  }
74956
75002
 
74957
75003
  // src/core/parse-timeout-seconds.ts
@@ -74984,7 +75030,7 @@ function parseVerboseOption(value) {
74984
75030
 
74985
75031
  // src/pid-lock.ts
74986
75032
  var import_node_fs9 = require("node:fs");
74987
- var import_neverthrow44 = __toESM(require_index_cjs(), 1);
75033
+ var import_neverthrow45 = __toESM(require_index_cjs(), 1);
74988
75034
  var PID_FILE = "/tmp/xqa.pid";
74989
75035
  var SIGINT_EXIT_CODE = 130;
74990
75036
  var SIGTERM_EXIT_CODE = 143;
@@ -74993,7 +75039,7 @@ var HARD_TIMEOUT_MS = 1e4;
74993
75039
  var cleanup = () => {
74994
75040
  (0, import_node_fs9.rmSync)(PID_FILE, { force: true });
74995
75041
  };
74996
- var checkProcessRunning = (0, import_neverthrow44.fromThrowable)(
75042
+ var checkProcessRunning = (0, import_neverthrow45.fromThrowable)(
74997
75043
  (pid) => {
74998
75044
  process.kill(pid, 0);
74999
75045
  return true;
@@ -75059,17 +75105,17 @@ function acquireLock() {
75059
75105
  // src/shell/xqa-directory.ts
75060
75106
  var import_node_fs10 = require("node:fs");
75061
75107
  var import_node_path19 = __toESM(require("node:path"), 1);
75062
- var import_neverthrow45 = __toESM(require_index_cjs(), 1);
75108
+ var import_neverthrow46 = __toESM(require_index_cjs(), 1);
75063
75109
  function findXqaDirectory(startDirectory) {
75064
75110
  let current = startDirectory;
75065
75111
  for (; ; ) {
75066
75112
  const candidate = import_node_path19.default.join(current, ".xqa");
75067
75113
  if ((0, import_node_fs10.existsSync)(candidate)) {
75068
- return (0, import_neverthrow45.ok)(candidate);
75114
+ return (0, import_neverthrow46.ok)(candidate);
75069
75115
  }
75070
75116
  const parent = import_node_path19.default.dirname(current);
75071
75117
  if (parent === current) {
75072
- return (0, import_neverthrow45.err)({ type: "XQA_NOT_INITIALIZED" });
75118
+ return (0, import_neverthrow46.err)({ type: "XQA_NOT_INITIALIZED" });
75073
75119
  }
75074
75120
  current = parent;
75075
75121
  }
@@ -75079,7 +75125,7 @@ function findXqaDirectory(startDirectory) {
75079
75125
  var import_promises19 = __toESM(require("node:fs/promises"), 1);
75080
75126
  var import_node_path22 = __toESM(require("node:path"), 1);
75081
75127
  var import_fast_glob = __toESM(require_out4(), 1);
75082
- var import_neverthrow50 = __toESM(require_index_cjs(), 1);
75128
+ var import_neverthrow51 = __toESM(require_index_cjs(), 1);
75083
75129
 
75084
75130
  // src/suite/core/run-id.ts
75085
75131
  var RUN_ID_PAD_LENGTH2 = 4;
@@ -75102,8 +75148,8 @@ function computeNextRunId(existingDirectories) {
75102
75148
  }
75103
75149
 
75104
75150
  // src/suite/core/suite-config-parser.ts
75105
- var import_neverthrow46 = __toESM(require_index_cjs(), 1);
75106
75151
  var import_neverthrow47 = __toESM(require_index_cjs(), 1);
75152
+ var import_neverthrow48 = __toESM(require_index_cjs(), 1);
75107
75153
  var freestyleEntrySchema = external_exports2.object({
75108
75154
  prompt: external_exports2.string().optional(),
75109
75155
  timeoutSeconds: external_exports2.number().int().positive()
@@ -75122,7 +75168,7 @@ var suiteConfigSchema = external_exports2.object({
75122
75168
  specs: external_exports2.array(external_exports2.string()).nonempty(),
75123
75169
  freestyle: freestyleSchema
75124
75170
  });
75125
- var safeJsonParse4 = (0, import_neverthrow46.fromThrowable)(
75171
+ var safeJsonParse4 = (0, import_neverthrow47.fromThrowable)(
75126
75172
  JSON.parse,
75127
75173
  (cause) => ({
75128
75174
  type: "INVALID_SUITE_CONFIG",
@@ -75133,9 +75179,9 @@ function parseSuiteConfig(raw) {
75133
75179
  return safeJsonParse4(raw).andThen((data) => {
75134
75180
  const parsed = suiteConfigSchema.safeParse(data);
75135
75181
  if (!parsed.success) {
75136
- return (0, import_neverthrow47.err)({ type: "INVALID_SUITE_CONFIG", cause: parsed.error });
75182
+ return (0, import_neverthrow48.err)({ type: "INVALID_SUITE_CONFIG", cause: parsed.error });
75137
75183
  }
75138
- return (0, import_neverthrow47.ok)({ specs: parsed.data.specs, freestyle: parsed.data.freestyle });
75184
+ return (0, import_neverthrow48.ok)({ specs: parsed.data.specs, freestyle: parsed.data.freestyle });
75139
75185
  });
75140
75186
  }
75141
75187
 
@@ -75201,7 +75247,7 @@ function buildFreestyleItems(entries) {
75201
75247
  // src/suite/shell/suite-findings-writer.ts
75202
75248
  var import_promises18 = __toESM(require("node:fs/promises"), 1);
75203
75249
  var import_node_path20 = __toESM(require("node:path"), 1);
75204
- var import_neverthrow48 = __toESM(require_index_cjs(), 1);
75250
+ var import_neverthrow49 = __toESM(require_index_cjs(), 1);
75205
75251
  var INDENT_SPACES = 2;
75206
75252
  function writeSuiteFindings(findings, options) {
75207
75253
  const directory = import_node_path20.default.join(
@@ -75213,7 +75259,7 @@ function writeSuiteFindings(findings, options) {
75213
75259
  );
75214
75260
  const finalPath = import_node_path20.default.join(directory, "findings.json");
75215
75261
  const temporaryPath = `${finalPath}.tmp`;
75216
- const safeWriteAtomically = import_neverthrow48.ResultAsync.fromThrowable(
75262
+ const safeWriteAtomically = import_neverthrow49.ResultAsync.fromThrowable(
75217
75263
  async () => {
75218
75264
  await import_promises18.default.mkdir(directory, { recursive: true });
75219
75265
  await import_promises18.default.writeFile(temporaryPath, JSON.stringify(findings, void 0, INDENT_SPACES));
@@ -75226,7 +75272,7 @@ function writeSuiteFindings(findings, options) {
75226
75272
  }
75227
75273
 
75228
75274
  // src/suite/shell/worker-pool.ts
75229
- var import_neverthrow49 = __toESM(require_index_cjs(), 1);
75275
+ var import_neverthrow50 = __toESM(require_index_cjs(), 1);
75230
75276
 
75231
75277
  // src/suite/shell/item-result-builder.ts
75232
75278
  function getErrorMessage(cause) {
@@ -75454,7 +75500,7 @@ function runWorkerPool(config3) {
75454
75500
  const queue = setupQueue(config3);
75455
75501
  const results = [];
75456
75502
  const suiteStartMs = Date.now();
75457
- const safeRun = import_neverthrow49.ResultAsync.fromThrowable(
75503
+ const safeRun = import_neverthrow50.ResultAsync.fromThrowable(
75458
75504
  async () => runAllWorkers({ config: config3, queue, results, suiteStartMs }),
75459
75505
  (cause) => ({ type: "WORKER_POOL_FAILED", cause })
75460
75506
  );
@@ -75541,14 +75587,14 @@ function makeExecuteItem(context) {
75541
75587
 
75542
75588
  // src/suite/commands/run-command.ts
75543
75589
  var ISO_DATE_LENGTH3 = 10;
75544
- var safeReaddir2 = import_neverthrow50.ResultAsync.fromThrowable(
75590
+ var safeReaddir2 = import_neverthrow51.ResultAsync.fromThrowable(
75545
75591
  async (directoryPath) => {
75546
75592
  const entries = await import_promises19.default.readdir(directoryPath, { withFileTypes: true });
75547
75593
  return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
75548
75594
  },
75549
75595
  () => "READDIR_FAILED"
75550
75596
  );
75551
- var safeReadFile5 = import_neverthrow50.ResultAsync.fromThrowable(
75597
+ var safeReadFile5 = import_neverthrow51.ResultAsync.fromThrowable(
75552
75598
  async (filePath) => import_promises19.default.readFile(filePath, "utf8"),
75553
75599
  () => "READ_FAILED"
75554
75600
  );
@@ -75730,7 +75776,7 @@ function resolveXqaDirectory() {
75730
75776
  return result.value;
75731
75777
  }
75732
75778
  var program2 = new Command();
75733
- program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.6.1"}${false ? ` (dev build +${"6b23ee9"})` : ""}`);
75779
+ program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.7.0"}${false ? ` (dev build +${"a108066"})` : ""}`);
75734
75780
  program2.command("init").description("Initialize a new xqa project in the current directory").action(() => {
75735
75781
  runInitCommand();
75736
75782
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/xqa",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -27,11 +27,11 @@
27
27
  "vitest": "^3.2.1",
28
28
  "zod": "^3.0.0",
29
29
  "@qa-agents/display": "0.0.0",
30
+ "@qa-agents/eslint-config": "0.0.0",
30
31
  "@qa-agents/explorer": "0.0.0",
31
32
  "@qa-agents/mobile-ios": "0.0.0",
32
33
  "@qa-agents/pipeline": "0.0.0",
33
34
  "@qa-agents/shared": "0.0.0",
34
- "@qa-agents/eslint-config": "0.0.0",
35
35
  "@qa-agents/typescript-config": "0.0.0"
36
36
  },
37
37
  "dependencies": {