@exodus/xqa 1.6.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xqa.cjs +255 -211
- 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(
|
|
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
|
|
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
|
|
3913
|
+
return errAsync8(this.error);
|
|
3914
3914
|
}
|
|
3915
3915
|
asyncAndThrough(_f) {
|
|
3916
|
-
return
|
|
3916
|
+
return errAsync8(this.error);
|
|
3917
3917
|
}
|
|
3918
3918
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3919
3919
|
asyncMap(_f) {
|
|
3920
|
-
return
|
|
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 =
|
|
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
|
|
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
|
|
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.`;
|
|
@@ -62915,8 +62963,6 @@ A step MAY be skipped if and only if:
|
|
|
62915
62963
|
- The action's direct target (element, modal, screen) is not present, AND
|
|
62916
62964
|
- The current screen state already satisfies the expected postcondition of this step (i.e. the step's effect has already occurred or was never needed).
|
|
62917
62965
|
|
|
62918
|
-
When skipping, emit a \`step-skipped\` finding with a one-sentence reason explaining what was absent and what already-satisfied condition justified the skip.
|
|
62919
|
-
|
|
62920
62966
|
Do NOT skip if:
|
|
62921
62967
|
- The target is absent but the screen is in an unexpected or intermediate state.
|
|
62922
62968
|
- You are uncertain whether the postcondition is satisfied.
|
|
@@ -63057,29 +63103,29 @@ var INLINE_ASSERTION_DELIMITER = " \u2192 ";
|
|
|
63057
63103
|
var NUMBERED_STEP_PREFIX = /^\d+\.\s+/;
|
|
63058
63104
|
function parseTagsValue(value) {
|
|
63059
63105
|
if (!value.startsWith("[") || !value.endsWith("]")) {
|
|
63060
|
-
return (0,
|
|
63106
|
+
return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
|
|
63061
63107
|
}
|
|
63062
|
-
return (0,
|
|
63108
|
+
return (0, import_neverthrow21.ok)(
|
|
63063
63109
|
value.slice(1, -1).split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0)
|
|
63064
63110
|
);
|
|
63065
63111
|
}
|
|
63066
63112
|
function parseTimeoutValue(value) {
|
|
63067
63113
|
const parsed = Number(value);
|
|
63068
63114
|
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
63069
|
-
return (0,
|
|
63115
|
+
return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
|
|
63070
63116
|
}
|
|
63071
|
-
return (0,
|
|
63117
|
+
return (0, import_neverthrow21.ok)(parsed);
|
|
63072
63118
|
}
|
|
63073
63119
|
function parseFrontmatterLine(line) {
|
|
63074
63120
|
const colonIndex = line.indexOf(":");
|
|
63075
63121
|
if (colonIndex === -1) {
|
|
63076
|
-
return (0,
|
|
63122
|
+
return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
|
|
63077
63123
|
}
|
|
63078
63124
|
const key = line.slice(0, colonIndex).trim();
|
|
63079
63125
|
const value = line.slice(colonIndex + 1).trim();
|
|
63080
63126
|
switch (key) {
|
|
63081
63127
|
case "description": {
|
|
63082
|
-
return (0,
|
|
63128
|
+
return (0, import_neverthrow21.ok)({ description: value });
|
|
63083
63129
|
}
|
|
63084
63130
|
case "tags": {
|
|
63085
63131
|
return parseTagsValue(value).map((tags) => ({ tags }));
|
|
@@ -63088,7 +63134,7 @@ function parseFrontmatterLine(line) {
|
|
|
63088
63134
|
return parseTimeoutValue(value).map((timeout) => ({ timeout }));
|
|
63089
63135
|
}
|
|
63090
63136
|
default: {
|
|
63091
|
-
return (0,
|
|
63137
|
+
return (0, import_neverthrow21.ok)({});
|
|
63092
63138
|
}
|
|
63093
63139
|
}
|
|
63094
63140
|
}
|
|
@@ -63107,18 +63153,18 @@ function mergePartials(partials) {
|
|
|
63107
63153
|
}
|
|
63108
63154
|
function combineFrontmatterLines(lines) {
|
|
63109
63155
|
const lineResults = lines.filter((line) => line.trim().length > 0).map((line) => parseFrontmatterLine(line));
|
|
63110
|
-
return
|
|
63156
|
+
return import_neverthrow21.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
|
|
63111
63157
|
}
|
|
63112
63158
|
function extractFrontmatter(content) {
|
|
63113
63159
|
const trimmed = content.trimStart();
|
|
63114
63160
|
if (!trimmed.startsWith(FRONTMATTER_FENCE)) {
|
|
63115
|
-
return (0,
|
|
63161
|
+
return (0, import_neverthrow21.ok)({ frontmatter: emptyFrontmatter(), body: content });
|
|
63116
63162
|
}
|
|
63117
63163
|
const afterOpenFence = trimmed.slice(FRONTMATTER_FENCE.length);
|
|
63118
63164
|
const closeIndex = afterOpenFence.indexOf(`
|
|
63119
63165
|
${FRONTMATTER_FENCE}`);
|
|
63120
63166
|
if (closeIndex === -1) {
|
|
63121
|
-
return (0,
|
|
63167
|
+
return (0, import_neverthrow21.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
|
|
63122
63168
|
}
|
|
63123
63169
|
const rawFrontmatter = afterOpenFence.slice(0, closeIndex);
|
|
63124
63170
|
const body = afterOpenFence.slice(closeIndex + FRONTMATTER_FENCE.length + 1);
|
|
@@ -63160,13 +63206,13 @@ function parseTestSpec(name, content) {
|
|
|
63160
63206
|
const sections = splitIntoSections(body);
|
|
63161
63207
|
const setup = sections.Setup;
|
|
63162
63208
|
if (setup === void 0) {
|
|
63163
|
-
return (0,
|
|
63209
|
+
return (0, import_neverthrow21.err)({ type: "MISSING_SETUP_SECTION" });
|
|
63164
63210
|
}
|
|
63165
63211
|
const stepsSection = sections.Steps;
|
|
63166
63212
|
if (stepsSection === void 0) {
|
|
63167
|
-
return (0,
|
|
63213
|
+
return (0, import_neverthrow21.err)({ type: "MISSING_STEPS_SECTION" });
|
|
63168
63214
|
}
|
|
63169
|
-
return (0,
|
|
63215
|
+
return (0, import_neverthrow21.ok)({
|
|
63170
63216
|
name,
|
|
63171
63217
|
frontmatter,
|
|
63172
63218
|
setup,
|
|
@@ -63215,25 +63261,25 @@ function direntToSpecEntry(directory, entry) {
|
|
|
63215
63261
|
return [];
|
|
63216
63262
|
}
|
|
63217
63263
|
function scanDirectory(directory) {
|
|
63218
|
-
const safeReaddir3 = (0,
|
|
63264
|
+
const safeReaddir3 = (0, import_neverthrow22.fromAsyncThrowable)(
|
|
63219
63265
|
async () => (0, import_promises11.readdir)(directory, { withFileTypes: true }),
|
|
63220
63266
|
(cause) => ({ type: "DIR_READ_FAILED", dir: directory, cause })
|
|
63221
63267
|
);
|
|
63222
|
-
return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0,
|
|
63268
|
+
return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow22.okAsync)([]) : (0, import_neverthrow22.errAsync)(error48)).map(
|
|
63223
63269
|
(entries) => entries.flatMap((entry) => direntToSpecEntry(directory, entry))
|
|
63224
63270
|
);
|
|
63225
63271
|
}
|
|
63226
63272
|
function readEntries(entries) {
|
|
63227
|
-
return
|
|
63273
|
+
return import_neverthrow22.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
|
|
63228
63274
|
(results) => results.flat()
|
|
63229
63275
|
);
|
|
63230
63276
|
}
|
|
63231
63277
|
function readEntry(entry) {
|
|
63232
|
-
const safeReadFile6 = (0,
|
|
63278
|
+
const safeReadFile6 = (0, import_neverthrow22.fromAsyncThrowable)(
|
|
63233
63279
|
async () => (0, import_promises11.readFile)(entry.path, "utf8"),
|
|
63234
63280
|
(cause) => ({ type: "FILE_READ_FAILED", path: entry.path, cause })
|
|
63235
63281
|
);
|
|
63236
|
-
return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0,
|
|
63282
|
+
return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow22.errAsync)(error48) : (0, import_neverthrow22.okAsync)([]));
|
|
63237
63283
|
}
|
|
63238
63284
|
function specNameFromPath(filePath) {
|
|
63239
63285
|
const parts = filePath.split("/");
|
|
@@ -63249,8 +63295,6 @@ function filterByNames(specs, specNames) {
|
|
|
63249
63295
|
}
|
|
63250
63296
|
return specs.filter((spec) => specNames.includes(spec.name));
|
|
63251
63297
|
}
|
|
63252
|
-
var SPEED_2X = 2;
|
|
63253
|
-
var SPEED_4X = 4;
|
|
63254
63298
|
var ISO_DATE_LENGTH = 10;
|
|
63255
63299
|
function buildPrompt(safeConfig, specs) {
|
|
63256
63300
|
return generateExplorerPrompt({
|
|
@@ -63282,12 +63326,29 @@ function toArtifacts(result, runPaths) {
|
|
|
63282
63326
|
function emitStageEnd3(safeConfig, start) {
|
|
63283
63327
|
safeConfig.onEvent?.({ type: "STAGE_END", agent: "explorer", durationMs: Date.now() - start });
|
|
63284
63328
|
}
|
|
63329
|
+
var EMPTY_RUN_PATHS = { videoPath: "", videoPath2x: "", videoPath4x: "" };
|
|
63330
|
+
function collectWithoutRecording({
|
|
63331
|
+
safeConfig,
|
|
63332
|
+
prompt,
|
|
63333
|
+
start
|
|
63334
|
+
}) {
|
|
63335
|
+
return collectAgentOutput(prompt, safeConfig).map((result) => {
|
|
63336
|
+
emitStageEnd3(safeConfig, start);
|
|
63337
|
+
return toArtifacts(result, EMPTY_RUN_PATHS);
|
|
63338
|
+
}).mapErr((error48) => {
|
|
63339
|
+
emitStageEnd3(safeConfig, start);
|
|
63340
|
+
return error48;
|
|
63341
|
+
});
|
|
63342
|
+
}
|
|
63285
63343
|
function collectAndFinalize({
|
|
63286
63344
|
safeConfig,
|
|
63287
63345
|
prompt,
|
|
63288
63346
|
runPaths,
|
|
63289
63347
|
start
|
|
63290
63348
|
}) {
|
|
63349
|
+
if (safeConfig.record === false) {
|
|
63350
|
+
return collectWithoutRecording({ safeConfig, prompt, start });
|
|
63351
|
+
}
|
|
63291
63352
|
return startAndRun({
|
|
63292
63353
|
videoPath: runPaths.videoPath,
|
|
63293
63354
|
videoPath2x: runPaths.videoPath2x,
|
|
@@ -63343,71 +63404,19 @@ function runExplorer(config3) {
|
|
|
63343
63404
|
(0, import_promises10.mkdir)(runPaths.screenshotsDir, { recursive: true }).catch(() => null)
|
|
63344
63405
|
).andThen(() => runPipeline({ safeConfig, runPaths, start }));
|
|
63345
63406
|
}
|
|
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
63407
|
|
|
63399
63408
|
// ../../packages/pipeline/dist/index.js
|
|
63400
|
-
var
|
|
63409
|
+
var import_neverthrow34 = __toESM(require_index_cjs(), 1);
|
|
63401
63410
|
|
|
63402
63411
|
// ../../agents/inspector/dist/index.js
|
|
63403
|
-
var import_neverthrow22 = __toESM(require_index_cjs(), 1);
|
|
63404
|
-
var import_promises12 = require("node:fs/promises");
|
|
63405
63412
|
var import_neverthrow23 = __toESM(require_index_cjs(), 1);
|
|
63413
|
+
var import_promises12 = require("node:fs/promises");
|
|
63406
63414
|
var import_neverthrow24 = __toESM(require_index_cjs(), 1);
|
|
63407
63415
|
var import_neverthrow25 = __toESM(require_index_cjs(), 1);
|
|
63408
63416
|
var import_neverthrow26 = __toESM(require_index_cjs(), 1);
|
|
63409
|
-
var import_sharp2 = __toESM(require("sharp"), 1);
|
|
63410
63417
|
var import_neverthrow27 = __toESM(require_index_cjs(), 1);
|
|
63418
|
+
var import_sharp2 = __toESM(require("sharp"), 1);
|
|
63419
|
+
var import_neverthrow28 = __toESM(require_index_cjs(), 1);
|
|
63411
63420
|
var import_promises13 = require("node:fs/promises");
|
|
63412
63421
|
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
63413
63422
|
|
|
@@ -66036,7 +66045,7 @@ var jsYaml = {
|
|
|
66036
66045
|
};
|
|
66037
66046
|
|
|
66038
66047
|
// ../../agents/inspector/dist/index.js
|
|
66039
|
-
var
|
|
66048
|
+
var import_neverthrow29 = __toESM(require_index_cjs(), 1);
|
|
66040
66049
|
var MS_PER_DAY = 864e5;
|
|
66041
66050
|
function checkStaleness({ lastUpdated, thresholdDays, now }) {
|
|
66042
66051
|
if (!lastUpdated) {
|
|
@@ -66113,7 +66122,7 @@ function mapRawFinding(item) {
|
|
|
66113
66122
|
function parseJson(raw) {
|
|
66114
66123
|
return JSON.parse(raw);
|
|
66115
66124
|
}
|
|
66116
|
-
var safeJsonParse3 = (0,
|
|
66125
|
+
var safeJsonParse3 = (0, import_neverthrow26.fromThrowable)(parseJson);
|
|
66117
66126
|
function parseClaudeResponse(raw) {
|
|
66118
66127
|
const parseResult = safeJsonParse3(raw);
|
|
66119
66128
|
if (parseResult.isErr()) {
|
|
@@ -66140,7 +66149,7 @@ async function downscaleBuffer(buffer) {
|
|
|
66140
66149
|
return (0, import_sharp2.default)(buffer).resize({ width: targetWidth }).toBuffer();
|
|
66141
66150
|
}
|
|
66142
66151
|
function downscale(buffer) {
|
|
66143
|
-
return (0,
|
|
66152
|
+
return (0, import_neverthrow27.fromAsyncThrowable)(
|
|
66144
66153
|
downscaleBuffer,
|
|
66145
66154
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66146
66155
|
)(buffer);
|
|
@@ -66215,7 +66224,7 @@ async function fetchClaudeText({
|
|
|
66215
66224
|
return block?.type === "text" ? block.text : "";
|
|
66216
66225
|
}
|
|
66217
66226
|
function callClaude(options) {
|
|
66218
|
-
return (0,
|
|
66227
|
+
return (0, import_neverthrow25.fromAsyncThrowable)(
|
|
66219
66228
|
fetchClaudeText,
|
|
66220
66229
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66221
66230
|
)(options);
|
|
@@ -66227,9 +66236,9 @@ function toFindings(text) {
|
|
|
66227
66236
|
const cleaned = stripCodeFences(text);
|
|
66228
66237
|
const findings = parseClaudeResponse(cleaned);
|
|
66229
66238
|
if (!findings) {
|
|
66230
|
-
return (0,
|
|
66239
|
+
return (0, import_neverthrow25.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: cleaned });
|
|
66231
66240
|
}
|
|
66232
|
-
return (0,
|
|
66241
|
+
return (0, import_neverthrow25.okAsync)(findings);
|
|
66233
66242
|
}
|
|
66234
66243
|
function buildResolveMessages(screenshotBase64, artboardNames) {
|
|
66235
66244
|
return [
|
|
@@ -66266,12 +66275,12 @@ async function fetchResolveName({
|
|
|
66266
66275
|
}
|
|
66267
66276
|
function resolveArtboard(screenshot, artboardNames) {
|
|
66268
66277
|
if (artboardNames.length === 0) {
|
|
66269
|
-
return (0,
|
|
66278
|
+
return (0, import_neverthrow25.okAsync)(void 0);
|
|
66270
66279
|
}
|
|
66271
66280
|
const anthropic = new Anthropic();
|
|
66272
66281
|
return downscale(screenshot).andThen((scaled) => {
|
|
66273
66282
|
const screenshotBase64 = scaled.toString("base64");
|
|
66274
|
-
return (0,
|
|
66283
|
+
return (0, import_neverthrow25.fromAsyncThrowable)(
|
|
66275
66284
|
fetchResolveName,
|
|
66276
66285
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66277
66286
|
)({ anthropic, screenshotBase64, artboardNames }).map((name) => {
|
|
@@ -66334,7 +66343,7 @@ var SEVERITY_CONFIDENCE = {
|
|
|
66334
66343
|
medium: CONFIDENCE_MEDIUM2,
|
|
66335
66344
|
low: CONFIDENCE_LOW2
|
|
66336
66345
|
};
|
|
66337
|
-
var safeJsonParse22 = (0,
|
|
66346
|
+
var safeJsonParse22 = (0, import_neverthrow28.fromThrowable)(JSON.parse);
|
|
66338
66347
|
function buildFindCandidatesMessages(screenshotBase64, artboardNames) {
|
|
66339
66348
|
return [
|
|
66340
66349
|
{
|
|
@@ -66381,12 +66390,12 @@ async function fetchCandidateNames({
|
|
|
66381
66390
|
}
|
|
66382
66391
|
function findCandidates(screenshot, artboardNames) {
|
|
66383
66392
|
if (artboardNames.length === 0) {
|
|
66384
|
-
return (0,
|
|
66393
|
+
return (0, import_neverthrow28.okAsync)([]);
|
|
66385
66394
|
}
|
|
66386
66395
|
const anthropic = new Anthropic();
|
|
66387
66396
|
return downscale(screenshot).andThen((scaled) => {
|
|
66388
66397
|
const screenshotBase64 = scaled.toString("base64");
|
|
66389
|
-
return (0,
|
|
66398
|
+
return (0, import_neverthrow28.fromAsyncThrowable)(
|
|
66390
66399
|
fetchCandidateNames,
|
|
66391
66400
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66392
66401
|
)({ anthropic, screenshotBase64, artboardNames });
|
|
@@ -66473,14 +66482,14 @@ async function fetchDesignContextText({
|
|
|
66473
66482
|
function toDesignContextFindings(text) {
|
|
66474
66483
|
const findings = parseConservativeResponse(text);
|
|
66475
66484
|
if (!findings) {
|
|
66476
|
-
return (0,
|
|
66485
|
+
return (0, import_neverthrow28.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: text });
|
|
66477
66486
|
}
|
|
66478
|
-
return (0,
|
|
66487
|
+
return (0, import_neverthrow28.okAsync)(findings);
|
|
66479
66488
|
}
|
|
66480
66489
|
async function downscaleAll(buffers) {
|
|
66481
66490
|
return Promise.all(buffers.map(async (buf) => downscaleBuffer(buf)));
|
|
66482
66491
|
}
|
|
66483
|
-
var downscaleAllBuffers = (0,
|
|
66492
|
+
var downscaleAllBuffers = (0, import_neverthrow28.fromAsyncThrowable)(
|
|
66484
66493
|
downscaleAll,
|
|
66485
66494
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66486
66495
|
);
|
|
@@ -66490,7 +66499,7 @@ function compareWithDesignContext(screenshot, artboards) {
|
|
|
66490
66499
|
const screenshotBase64 = scaledScreenshot.toString("base64");
|
|
66491
66500
|
return downscaleAllBuffers(artboards).andThen((scaledArtboards) => {
|
|
66492
66501
|
const artboardBase64s = scaledArtboards.map((buf) => buf.toString("base64"));
|
|
66493
|
-
return (0,
|
|
66502
|
+
return (0, import_neverthrow28.fromAsyncThrowable)(
|
|
66494
66503
|
fetchDesignContextText,
|
|
66495
66504
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
66496
66505
|
)({ anthropic, screenshotBase64, artboardBase64s }).andThen(toDesignContextFindings);
|
|
@@ -66723,7 +66732,7 @@ async function initArtboardNames({ designStore, config: config3, state }) {
|
|
|
66723
66732
|
return state.artboardNamesPromise;
|
|
66724
66733
|
}
|
|
66725
66734
|
function readScreenshot(screenshotPath, stepIndex) {
|
|
66726
|
-
return
|
|
66735
|
+
return import_neverthrow24.ResultAsync.fromThrowable(
|
|
66727
66736
|
import_promises12.readFile,
|
|
66728
66737
|
(cause) => ({ type: "SCREENSHOT_READ_FAILED", stepIndex, cause })
|
|
66729
66738
|
)(screenshotPath);
|
|
@@ -66799,7 +66808,7 @@ function buildInspector(state, context) {
|
|
|
66799
66808
|
const { promise: promise2, resolve } = Promise.withResolvers();
|
|
66800
66809
|
state.resolve = resolve;
|
|
66801
66810
|
applyTryResolve(state);
|
|
66802
|
-
return (0,
|
|
66811
|
+
return (0, import_neverthrow23.fromSafePromise)(promise2);
|
|
66803
66812
|
}
|
|
66804
66813
|
};
|
|
66805
66814
|
}
|
|
@@ -66823,10 +66832,10 @@ async function readAndParseSidecar(sidecarPath) {
|
|
|
66823
66832
|
return parseMeta(raw);
|
|
66824
66833
|
}
|
|
66825
66834
|
function readSidecarFile(sidecarPath) {
|
|
66826
|
-
return (0,
|
|
66835
|
+
return (0, import_neverthrow29.fromAsyncThrowable)(
|
|
66827
66836
|
readAndParseSidecar,
|
|
66828
66837
|
() => ({})
|
|
66829
|
-
)(sidecarPath).orElse(() => (0,
|
|
66838
|
+
)(sidecarPath).orElse(() => (0, import_neverthrow29.okAsync)({}));
|
|
66830
66839
|
}
|
|
66831
66840
|
function isEnoent(error48) {
|
|
66832
66841
|
return error48?.code === "ENOENT";
|
|
@@ -66835,13 +66844,13 @@ function wrapFsError(cause) {
|
|
|
66835
66844
|
return { type: "FS_ERROR", cause };
|
|
66836
66845
|
}
|
|
66837
66846
|
function toFsError(fsError) {
|
|
66838
|
-
return (0,
|
|
66847
|
+
return (0, import_neverthrow29.errAsync)(fsError);
|
|
66839
66848
|
}
|
|
66840
66849
|
function missingBuffer() {
|
|
66841
|
-
return (0,
|
|
66850
|
+
return (0, import_neverthrow29.okAsync)(void 0);
|
|
66842
66851
|
}
|
|
66843
66852
|
function missingArtboard() {
|
|
66844
|
-
return (0,
|
|
66853
|
+
return (0, import_neverthrow29.okAsync)(void 0);
|
|
66845
66854
|
}
|
|
66846
66855
|
var FsDesignStore = class {
|
|
66847
66856
|
designsDirectory;
|
|
@@ -66849,12 +66858,12 @@ var FsDesignStore = class {
|
|
|
66849
66858
|
this.designsDirectory = designsDirectory;
|
|
66850
66859
|
}
|
|
66851
66860
|
listArtboards() {
|
|
66852
|
-
return (0,
|
|
66861
|
+
return (0, import_neverthrow29.fromAsyncThrowable)(
|
|
66853
66862
|
import_promises13.readdir,
|
|
66854
66863
|
wrapFsError
|
|
66855
66864
|
)(this.designsDirectory).orElse((fsError) => {
|
|
66856
66865
|
if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
|
|
66857
|
-
return (0,
|
|
66866
|
+
return (0, import_neverthrow29.okAsync)([]);
|
|
66858
66867
|
}
|
|
66859
66868
|
return toFsError(fsError);
|
|
66860
66869
|
}).map(
|
|
@@ -66864,7 +66873,7 @@ var FsDesignStore = class {
|
|
|
66864
66873
|
getArtboard(filename) {
|
|
66865
66874
|
const pngPath = import_node_path7.default.join(this.designsDirectory, `${filename}.png`);
|
|
66866
66875
|
const sidecarPath = import_node_path7.default.join(this.designsDirectory, `${filename}.meta.yaml`);
|
|
66867
|
-
return (0,
|
|
66876
|
+
return (0, import_neverthrow29.fromAsyncThrowable)(
|
|
66868
66877
|
import_promises13.readFile,
|
|
66869
66878
|
wrapFsError
|
|
66870
66879
|
)(pngPath).orElse((fsError) => {
|
|
@@ -66890,10 +66899,10 @@ function attemptRetry(options) {
|
|
|
66890
66899
|
const { factory, config: config3, delayFunction, onRetry, attempt } = options;
|
|
66891
66900
|
return factory().orElse((error48) => {
|
|
66892
66901
|
if (attempt >= config3.maxAttempts) {
|
|
66893
|
-
return (0,
|
|
66902
|
+
return (0, import_neverthrow32.errAsync)(error48);
|
|
66894
66903
|
}
|
|
66895
66904
|
const delay = config3.baseDelayMs * Math.pow(2, attempt - 1);
|
|
66896
|
-
return
|
|
66905
|
+
return import_neverthrow32.ResultAsync.fromPromise(
|
|
66897
66906
|
(onRetry?.({ attempt, maxAttempts: config3.maxAttempts, delayMs: delay, error: error48 }), delayFunction(delay)),
|
|
66898
66907
|
() => error48
|
|
66899
66908
|
).andThen(
|
|
@@ -66913,7 +66922,7 @@ function withRetry(factory, options) {
|
|
|
66913
66922
|
var CONSOLIDATOR_AGENT = "consolidator";
|
|
66914
66923
|
function analyserFallback(artifacts, onEvent) {
|
|
66915
66924
|
onEvent?.({ type: "AGENT_FAILED_NON_CRITICAL", agent: "analyser", attempts: RETRY_MAX_ATTEMPTS });
|
|
66916
|
-
return (0,
|
|
66925
|
+
return (0, import_neverthrow31.okAsync)(artifacts.findings);
|
|
66917
66926
|
}
|
|
66918
66927
|
function runAnalyserWithRetry(params) {
|
|
66919
66928
|
const { artifacts, config: config3, onEvent } = params;
|
|
@@ -66943,7 +66952,7 @@ function resolveVisualFindings({
|
|
|
66943
66952
|
onEvent
|
|
66944
66953
|
}) {
|
|
66945
66954
|
if (config3.analyser === void 0 || config3.signal?.aborted) {
|
|
66946
|
-
return (0,
|
|
66955
|
+
return (0, import_neverthrow31.okAsync)(artifacts.findings);
|
|
66947
66956
|
}
|
|
66948
66957
|
return runAnalyserWithRetry({ artifacts, config: config3, onEvent });
|
|
66949
66958
|
}
|
|
@@ -66953,7 +66962,7 @@ function unmergedFallback(allFindings, onEvent) {
|
|
|
66953
66962
|
agent: CONSOLIDATOR_AGENT,
|
|
66954
66963
|
message: "Consolidation failed, returning unmerged findings"
|
|
66955
66964
|
});
|
|
66956
|
-
return (0,
|
|
66965
|
+
return (0, import_neverthrow31.okAsync)({ findings: allFindings, dismissed: [] });
|
|
66957
66966
|
}
|
|
66958
66967
|
function mergeWithFallback(options) {
|
|
66959
66968
|
const {
|
|
@@ -66980,7 +66989,7 @@ function consolidate(options) {
|
|
|
66980
66989
|
const { artifacts, inspectorFindings, runId, dismissals, config: config3, consolidatorConfig, onEvent } = options;
|
|
66981
66990
|
return resolveVisualFindings({ artifacts, config: config3, onEvent }).andThen((visualFindings) => {
|
|
66982
66991
|
if (config3.signal?.aborted) {
|
|
66983
|
-
return (0,
|
|
66992
|
+
return (0, import_neverthrow31.okAsync)({ findings: artifacts.findings, dismissed: [] });
|
|
66984
66993
|
}
|
|
66985
66994
|
return mergeWithFallback({
|
|
66986
66995
|
artifacts,
|
|
@@ -66993,8 +67002,8 @@ function consolidate(options) {
|
|
|
66993
67002
|
});
|
|
66994
67003
|
});
|
|
66995
67004
|
}
|
|
66996
|
-
var safeReadFile = (0,
|
|
66997
|
-
var safeParseJson2 = (0,
|
|
67005
|
+
var safeReadFile = (0, import_neverthrow33.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
|
|
67006
|
+
var safeParseJson2 = (0, import_neverthrow33.fromThrowable)(JSON.parse);
|
|
66998
67007
|
function isEnoent2(error48) {
|
|
66999
67008
|
if (!(error48 instanceof Error)) {
|
|
67000
67009
|
return false;
|
|
@@ -67006,19 +67015,19 @@ function loadDismissals(filePath) {
|
|
|
67006
67015
|
const readResult = safeReadFile(filePath);
|
|
67007
67016
|
if (readResult.isErr()) {
|
|
67008
67017
|
if (isEnoent2(readResult.error)) {
|
|
67009
|
-
return (0,
|
|
67018
|
+
return (0, import_neverthrow33.ok)([]);
|
|
67010
67019
|
}
|
|
67011
|
-
return (0,
|
|
67020
|
+
return (0, import_neverthrow33.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
|
|
67012
67021
|
}
|
|
67013
67022
|
return safeParseJson2(readResult.value).mapErr((cause) => ({ type: "DISMISSALS_LOAD_FAILED", cause })).andThen((data) => {
|
|
67014
67023
|
const store = data;
|
|
67015
67024
|
if (!Array.isArray(store.dismissed)) {
|
|
67016
|
-
return (0,
|
|
67025
|
+
return (0, import_neverthrow33.err)({
|
|
67017
67026
|
type: "DISMISSALS_LOAD_FAILED",
|
|
67018
67027
|
cause: "invalid shape: dismissed is not an array"
|
|
67019
67028
|
});
|
|
67020
67029
|
}
|
|
67021
|
-
return (0,
|
|
67030
|
+
return (0, import_neverthrow33.ok)(store.dismissed);
|
|
67022
67031
|
});
|
|
67023
67032
|
}
|
|
67024
67033
|
function toInspectorStepEvent(event) {
|
|
@@ -67105,7 +67114,7 @@ function runExplorerWithTeardown(explorerConfig, udid) {
|
|
|
67105
67114
|
return runExplorer(explorerConfig).mapErr((cause) => ({ type: "EXPLORER_FAILED", cause })).andThen(
|
|
67106
67115
|
(artifacts) => disableTouchIndicators(udid).mapErr(toSimulatorError).map(() => artifacts)
|
|
67107
67116
|
).orElse(
|
|
67108
|
-
(error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0,
|
|
67117
|
+
(error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow34.errAsync)(error48)).orElse(() => (0, import_neverthrow34.errAsync)(error48))
|
|
67109
67118
|
);
|
|
67110
67119
|
}
|
|
67111
67120
|
function runExplorerWithRetry(options) {
|
|
@@ -67131,12 +67140,12 @@ async function drainAfterExplorer(options) {
|
|
|
67131
67140
|
inspector?.close();
|
|
67132
67141
|
const inspectorFindings = inspector ? await collectInspectorFindings({ inspector, onEvent, totalSteps: enqueuedCount.value }) : [];
|
|
67133
67142
|
if (explorerResult.isErr()) {
|
|
67134
|
-
return (0,
|
|
67143
|
+
return (0, import_neverthrow34.err)(explorerResult.error);
|
|
67135
67144
|
}
|
|
67136
|
-
return (0,
|
|
67145
|
+
return (0, import_neverthrow34.ok)({ artifacts: explorerResult.value, inspectorFindings });
|
|
67137
67146
|
}
|
|
67138
67147
|
function runExplorerAndDrain(options) {
|
|
67139
|
-
return new
|
|
67148
|
+
return new import_neverthrow34.ResultAsync(drainAfterExplorer(options));
|
|
67140
67149
|
}
|
|
67141
67150
|
function createDefaultMcpServers(udid) {
|
|
67142
67151
|
return {
|
|
@@ -67148,7 +67157,7 @@ function runAnalysis(artifacts, config3) {
|
|
|
67148
67157
|
}
|
|
67149
67158
|
var ISO_DATE_LENGTH2 = 10;
|
|
67150
67159
|
var RUN_ID_PAD_LENGTH = 4;
|
|
67151
|
-
var safeReaddirSync = (0,
|
|
67160
|
+
var safeReaddirSync = (0, import_neverthrow30.fromThrowable)((directory) => (0, import_node_fs2.readdirSync)(directory));
|
|
67152
67161
|
function nextRunId(outputDirectory, date5) {
|
|
67153
67162
|
const entries = safeReaddirSync(`${outputDirectory}/${date5}`).unwrapOr([]);
|
|
67154
67163
|
let max = 0;
|
|
@@ -67160,7 +67169,7 @@ function nextRunId(outputDirectory, date5) {
|
|
|
67160
67169
|
}
|
|
67161
67170
|
return String(max + 1).padStart(RUN_ID_PAD_LENGTH, "0");
|
|
67162
67171
|
}
|
|
67163
|
-
var writeOutputFile = (0,
|
|
67172
|
+
var writeOutputFile = (0, import_neverthrow30.fromThrowable)(
|
|
67164
67173
|
(params) => {
|
|
67165
67174
|
const { findingsPath, outputDirectory, json: json3 } = params;
|
|
67166
67175
|
(0, import_node_fs2.mkdirSync)(outputDirectory, { recursive: true });
|
|
@@ -67173,15 +67182,15 @@ function validatePipelineConfig(config3) {
|
|
|
67173
67182
|
const runId = config3.runId ?? nextRunId(config3.outputDir, date5);
|
|
67174
67183
|
const runPathsResult = resolveRunPaths({ outputDirectory: config3.outputDir, runId, date: date5 });
|
|
67175
67184
|
if (runPathsResult.isErr()) {
|
|
67176
|
-
return (0,
|
|
67185
|
+
return (0, import_neverthrow30.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
|
|
67177
67186
|
}
|
|
67178
67187
|
const dismissalsResult = loadDismissals(
|
|
67179
67188
|
dismissalsPath(config3.outputDir, process.env.QA_DISMISSALS_PATH)
|
|
67180
67189
|
);
|
|
67181
67190
|
if (dismissalsResult.isErr()) {
|
|
67182
|
-
return (0,
|
|
67191
|
+
return (0, import_neverthrow30.err)(dismissalsResult.error);
|
|
67183
67192
|
}
|
|
67184
|
-
return (0,
|
|
67193
|
+
return (0, import_neverthrow30.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
|
|
67185
67194
|
}
|
|
67186
67195
|
function buildExplorerConfig({
|
|
67187
67196
|
config: config3,
|
|
@@ -67196,7 +67205,8 @@ function buildExplorerConfig({
|
|
|
67196
67205
|
date: date5,
|
|
67197
67206
|
onEvent,
|
|
67198
67207
|
signal: config3.signal,
|
|
67199
|
-
udid: config3.simulatorUdid ?? "booted"
|
|
67208
|
+
udid: config3.simulatorUdid ?? "booted",
|
|
67209
|
+
record: config3.explorer.record ?? config3.analyser !== void 0
|
|
67200
67210
|
};
|
|
67201
67211
|
}
|
|
67202
67212
|
function buildOutput(consolidationResult, options) {
|
|
@@ -67217,11 +67227,11 @@ function buildOutput(consolidationResult, options) {
|
|
|
67217
67227
|
function buildPipelineSetup(config3) {
|
|
67218
67228
|
const validatedResult = validatePipelineConfig(config3);
|
|
67219
67229
|
if (validatedResult.isErr()) {
|
|
67220
|
-
return (0,
|
|
67230
|
+
return (0, import_neverthrow30.err)(validatedResult.error);
|
|
67221
67231
|
}
|
|
67222
67232
|
const { runId, date: date5, runPaths, dismissals } = validatedResult.value;
|
|
67223
67233
|
const { inspector, explorerOnEvent, enqueuedCount } = buildInspectorSetup(config3);
|
|
67224
|
-
return (0,
|
|
67234
|
+
return (0, import_neverthrow30.ok)({
|
|
67225
67235
|
runId,
|
|
67226
67236
|
udid: config3.simulatorUdid ?? "booted",
|
|
67227
67237
|
runPaths,
|
|
@@ -67265,19 +67275,19 @@ function executePipeline(setup, config3) {
|
|
|
67265
67275
|
function runPipeline2(config3) {
|
|
67266
67276
|
const setupResult = buildPipelineSetup(config3);
|
|
67267
67277
|
if (setupResult.isErr()) {
|
|
67268
|
-
return (0,
|
|
67278
|
+
return (0, import_neverthrow30.errAsync)(setupResult.error);
|
|
67269
67279
|
}
|
|
67270
67280
|
return executePipeline(setupResult.value, config3);
|
|
67271
67281
|
}
|
|
67272
67282
|
|
|
67273
67283
|
// src/commands/analyse-command.ts
|
|
67274
|
-
var
|
|
67284
|
+
var import_neverthrow35 = __toESM(require_index_cjs(), 1);
|
|
67275
67285
|
|
|
67276
67286
|
// src/commands/item-events.ts
|
|
67277
67287
|
function emitItemStart(identity, at) {
|
|
67278
|
-
const { display, itemId, itemName } = identity;
|
|
67288
|
+
const { display, itemId, itemName, simulatorUdid } = identity;
|
|
67279
67289
|
display.onEvent({ type: "ITEM_QUEUED", item: { id: itemId, name: itemName } });
|
|
67280
|
-
display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid
|
|
67290
|
+
display.onEvent({ type: "ITEM_STARTED", itemId, itemName, simulatorUdid, at });
|
|
67281
67291
|
}
|
|
67282
67292
|
function emitItemCompleted(input) {
|
|
67283
67293
|
const { identity, startedAt, findingsCount } = input;
|
|
@@ -67346,7 +67356,7 @@ function buildArtifacts(videoPath) {
|
|
|
67346
67356
|
return { videoPath, videoPath2x: "", videoPath4x: videoPath, findings: [], snapshots: [] };
|
|
67347
67357
|
}
|
|
67348
67358
|
async function checkVideoPathExists(videoPath) {
|
|
67349
|
-
const safeAccess = (0,
|
|
67359
|
+
const safeAccess = (0, import_neverthrow35.fromAsyncThrowable)(import_promises16.access, () => ({ type: "FILE_NOT_FOUND" }));
|
|
67350
67360
|
const result = await safeAccess(videoPath);
|
|
67351
67361
|
return result.isOk();
|
|
67352
67362
|
}
|
|
@@ -67371,7 +67381,8 @@ async function runAnalysisAndExit(artifacts, apiKey) {
|
|
|
67371
67381
|
const identity = {
|
|
67372
67382
|
display: createSoloDisplay(),
|
|
67373
67383
|
itemId: ITEM_ID,
|
|
67374
|
-
itemName: ITEM_NAME
|
|
67384
|
+
itemName: ITEM_NAME,
|
|
67385
|
+
simulatorUdid: ""
|
|
67375
67386
|
};
|
|
67376
67387
|
const startedAt = Date.now();
|
|
67377
67388
|
emitItemStart(identity, startedAt);
|
|
@@ -67411,7 +67422,7 @@ async function runAnalyseCommand(videoPath, config3) {
|
|
|
67411
67422
|
}
|
|
67412
67423
|
|
|
67413
67424
|
// src/core/completion-generator.ts
|
|
67414
|
-
var
|
|
67425
|
+
var import_neverthrow36 = __toESM(require_index_cjs(), 1);
|
|
67415
67426
|
function extractLongFlags(flags) {
|
|
67416
67427
|
return flags.split(/[\s,]+/).filter((token) => token.startsWith("--"));
|
|
67417
67428
|
}
|
|
@@ -67501,9 +67512,9 @@ complete -F _xqa_completion xqa`;
|
|
|
67501
67512
|
}
|
|
67502
67513
|
function generateCompletion(commands, shell) {
|
|
67503
67514
|
if (shell !== "bash" && shell !== "zsh") {
|
|
67504
|
-
return (0,
|
|
67515
|
+
return (0, import_neverthrow36.err)({ type: "UNSUPPORTED_SHELL", shell });
|
|
67505
67516
|
}
|
|
67506
|
-
return (0,
|
|
67517
|
+
return (0, import_neverthrow36.ok)(shell === "zsh" ? generateZshCompletion(commands) : generateBashCompletion(commands));
|
|
67507
67518
|
}
|
|
67508
67519
|
|
|
67509
67520
|
// src/commands/completion-command.ts
|
|
@@ -67561,16 +67572,16 @@ var FFMPEG_INSTALL_MESSAGE = "ffmpeg is not installed. Run:\n brew install ffmp
|
|
|
67561
67572
|
// src/core/last-path.ts
|
|
67562
67573
|
var import_node_fs4 = require("node:fs");
|
|
67563
67574
|
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
67564
|
-
var
|
|
67575
|
+
var import_neverthrow37 = __toESM(require_index_cjs(), 1);
|
|
67565
67576
|
function resolveLastPath(argument, stateContent) {
|
|
67566
67577
|
if (argument !== void 0) {
|
|
67567
|
-
return (0,
|
|
67578
|
+
return (0, import_neverthrow37.ok)(argument);
|
|
67568
67579
|
}
|
|
67569
67580
|
const trimmed = stateContent?.trim();
|
|
67570
67581
|
if (trimmed) {
|
|
67571
|
-
return (0,
|
|
67582
|
+
return (0, import_neverthrow37.ok)(trimmed);
|
|
67572
67583
|
}
|
|
67573
|
-
return (0,
|
|
67584
|
+
return (0, import_neverthrow37.err)({ type: "NO_ARG_AND_NO_STATE" });
|
|
67574
67585
|
}
|
|
67575
67586
|
function lastPathFilePath(xqaDirectoryectory) {
|
|
67576
67587
|
return import_node_path8.default.join(xqaDirectoryectory, "last-findings-path");
|
|
@@ -67582,7 +67593,7 @@ function writeLastPath(xqaDirectory, findingsPath) {
|
|
|
67582
67593
|
// src/shell/app-context.ts
|
|
67583
67594
|
var import_promises17 = require("node:fs/promises");
|
|
67584
67595
|
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
67585
|
-
var
|
|
67596
|
+
var import_neverthrow38 = __toESM(require_index_cjs(), 1);
|
|
67586
67597
|
var HTML_COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
|
|
67587
67598
|
function isEnoentError(value) {
|
|
67588
67599
|
return value !== null && typeof value === "object" && "code" in value && value.code === "ENOENT";
|
|
@@ -67592,9 +67603,9 @@ function toAppContextError(cause) {
|
|
|
67592
67603
|
}
|
|
67593
67604
|
function absentContext() {
|
|
67594
67605
|
const absent = void 0;
|
|
67595
|
-
return (0,
|
|
67606
|
+
return (0, import_neverthrow38.ok)(absent);
|
|
67596
67607
|
}
|
|
67597
|
-
var safeReadFile2 =
|
|
67608
|
+
var safeReadFile2 = import_neverthrow38.ResultAsync.fromThrowable(
|
|
67598
67609
|
async (filePath) => (0, import_promises17.readFile)(filePath, "utf8"),
|
|
67599
67610
|
toAppContextError
|
|
67600
67611
|
);
|
|
@@ -67608,7 +67619,7 @@ function readContextFile(xqaDirectory, filename) {
|
|
|
67608
67619
|
if (isEnoentError(error48.cause)) {
|
|
67609
67620
|
return absentContext();
|
|
67610
67621
|
}
|
|
67611
|
-
return (0,
|
|
67622
|
+
return (0, import_neverthrow38.err)(error48);
|
|
67612
67623
|
});
|
|
67613
67624
|
}
|
|
67614
67625
|
function readAppContext(xqaDirectory) {
|
|
@@ -67620,7 +67631,7 @@ function readExploreContext(xqaDirectory) {
|
|
|
67620
67631
|
|
|
67621
67632
|
// src/shell/ffmpeg-check.ts
|
|
67622
67633
|
var import_node_child_process5 = require("node:child_process");
|
|
67623
|
-
var
|
|
67634
|
+
var import_neverthrow39 = __toESM(require_index_cjs(), 1);
|
|
67624
67635
|
async function whichFfmpeg() {
|
|
67625
67636
|
const { promise: promise2, resolve, reject } = Promise.withResolvers();
|
|
67626
67637
|
(0, import_node_child_process5.execFile)("which", ["ffmpeg"], (error48, stdout) => {
|
|
@@ -67632,7 +67643,7 @@ async function whichFfmpeg() {
|
|
|
67632
67643
|
});
|
|
67633
67644
|
return promise2;
|
|
67634
67645
|
}
|
|
67635
|
-
var safeWhichFfmpeg = (0,
|
|
67646
|
+
var safeWhichFfmpeg = (0, import_neverthrow39.fromAsyncThrowable)(
|
|
67636
67647
|
whichFfmpeg,
|
|
67637
67648
|
() => ({ type: "FFMPEG_NOT_FOUND" })
|
|
67638
67649
|
);
|
|
@@ -67680,11 +67691,13 @@ function buildPipelineConfig({
|
|
|
67680
67691
|
config: config3,
|
|
67681
67692
|
xqaDirectory,
|
|
67682
67693
|
explorer,
|
|
67683
|
-
onEvent
|
|
67694
|
+
onEvent,
|
|
67695
|
+
simulatorUdid
|
|
67684
67696
|
}) {
|
|
67685
67697
|
const base = {
|
|
67686
67698
|
outputDir: import_node_path10.default.join(xqaDirectory, "output"),
|
|
67687
67699
|
runId: config3.QA_RUN_ID,
|
|
67700
|
+
simulatorUdid,
|
|
67688
67701
|
onEvent,
|
|
67689
67702
|
signal: input.signal,
|
|
67690
67703
|
inspector: { designsDirectory: import_node_path10.default.join(xqaDirectory, "designs") },
|
|
@@ -67705,7 +67718,9 @@ function buildSuccessMessage(output) {
|
|
|
67705
67718
|
`;
|
|
67706
67719
|
}
|
|
67707
67720
|
var ITEM_ID2 = "explore";
|
|
67708
|
-
|
|
67721
|
+
function buildItemName(simulatorUdid) {
|
|
67722
|
+
return `${simulatorUdid} - explorer`;
|
|
67723
|
+
}
|
|
67709
67724
|
function buildSuccessHandler({ input, xqaDirectory, identity, startedAt }) {
|
|
67710
67725
|
return (output) => {
|
|
67711
67726
|
emitItemCompleted({ identity, startedAt, findingsCount: output.findings.length });
|
|
@@ -67740,7 +67755,7 @@ ${cause}
|
|
|
67740
67755
|
};
|
|
67741
67756
|
}
|
|
67742
67757
|
function runExplorePipeline(state, contexts) {
|
|
67743
|
-
const { input, config: config3, xqaDirectory, onEvent, onSuccess, onError } = state;
|
|
67758
|
+
const { input, config: config3, xqaDirectory, onEvent, onSuccess, onError, simulatorUdid } = state;
|
|
67744
67759
|
const explorerConfig = buildExplorerConfig2({
|
|
67745
67760
|
input,
|
|
67746
67761
|
config: config3,
|
|
@@ -67748,14 +67763,22 @@ function runExplorePipeline(state, contexts) {
|
|
|
67748
67763
|
initialState: contexts.exploreContext
|
|
67749
67764
|
});
|
|
67750
67765
|
void runPipeline2(
|
|
67751
|
-
buildPipelineConfig({
|
|
67766
|
+
buildPipelineConfig({
|
|
67767
|
+
input,
|
|
67768
|
+
config: config3,
|
|
67769
|
+
xqaDirectory,
|
|
67770
|
+
explorer: explorerConfig,
|
|
67771
|
+
onEvent,
|
|
67772
|
+
simulatorUdid
|
|
67773
|
+
})
|
|
67752
67774
|
).match(onSuccess, onError);
|
|
67753
67775
|
}
|
|
67754
67776
|
function buildExploreRunState({
|
|
67755
67777
|
input,
|
|
67756
67778
|
options,
|
|
67757
67779
|
identity,
|
|
67758
|
-
startedAt
|
|
67780
|
+
startedAt,
|
|
67781
|
+
simulatorUdid
|
|
67759
67782
|
}) {
|
|
67760
67783
|
const { config: config3, xqaDirectory } = options;
|
|
67761
67784
|
const onEvent = (event) => {
|
|
@@ -67763,17 +67786,32 @@ function buildExploreRunState({
|
|
|
67763
67786
|
};
|
|
67764
67787
|
const onSuccess = buildSuccessHandler({ input, xqaDirectory, identity, startedAt });
|
|
67765
67788
|
const onError = buildErrorHandler(identity, startedAt);
|
|
67766
|
-
return { input, config: config3, xqaDirectory, onEvent, onSuccess, onError };
|
|
67789
|
+
return { input, config: config3, xqaDirectory, onEvent, onSuccess, onError, simulatorUdid };
|
|
67767
67790
|
}
|
|
67768
|
-
function
|
|
67791
|
+
async function resolveSimulatorUdid() {
|
|
67792
|
+
const result = await discoverBootedSimulators();
|
|
67793
|
+
if (result.isErr()) {
|
|
67794
|
+
process.stderr.write(`Failed to discover simulators: ${String(result.error.cause)}
|
|
67795
|
+
`);
|
|
67796
|
+
return;
|
|
67797
|
+
}
|
|
67798
|
+
const first = result.value[0];
|
|
67799
|
+
if (!first) {
|
|
67800
|
+
process.stderr.write("No booted simulators found\n");
|
|
67801
|
+
return;
|
|
67802
|
+
}
|
|
67803
|
+
return first.udid;
|
|
67804
|
+
}
|
|
67805
|
+
function runPipelineAfterPreflight({ input, options }, simulatorUdid) {
|
|
67769
67806
|
const identity = {
|
|
67770
67807
|
display: createSoloDisplay(input.verbose),
|
|
67771
67808
|
itemId: ITEM_ID2,
|
|
67772
|
-
itemName:
|
|
67809
|
+
itemName: buildItemName(simulatorUdid),
|
|
67810
|
+
simulatorUdid
|
|
67773
67811
|
};
|
|
67774
67812
|
const startedAt = Date.now();
|
|
67775
67813
|
emitItemStart(identity, startedAt);
|
|
67776
|
-
const state = buildExploreRunState({ input, options, identity, startedAt });
|
|
67814
|
+
const state = buildExploreRunState({ input, options, identity, startedAt, simulatorUdid });
|
|
67777
67815
|
void readAppContext(options.xqaDirectory).andThen(
|
|
67778
67816
|
(appContext) => readExploreContext(options.xqaDirectory).map((exploreContext) => ({
|
|
67779
67817
|
appContext,
|
|
@@ -67789,7 +67827,12 @@ async function runExploreAfterPreflight(context) {
|
|
|
67789
67827
|
process.exit(preflightExit);
|
|
67790
67828
|
return;
|
|
67791
67829
|
}
|
|
67792
|
-
|
|
67830
|
+
const simulatorUdid = await resolveSimulatorUdid();
|
|
67831
|
+
if (simulatorUdid === void 0) {
|
|
67832
|
+
process.exit(2);
|
|
67833
|
+
return;
|
|
67834
|
+
}
|
|
67835
|
+
runPipelineAfterPreflight(context, simulatorUdid);
|
|
67793
67836
|
}
|
|
67794
67837
|
function runExploreCommand(input, options) {
|
|
67795
67838
|
void runExploreAfterPreflight({ input, options });
|
|
@@ -67889,7 +67932,7 @@ function runInitCommand() {
|
|
|
67889
67932
|
// src/commands/review-command.ts
|
|
67890
67933
|
var import_node_fs7 = require("node:fs");
|
|
67891
67934
|
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
67892
|
-
var
|
|
67935
|
+
var import_neverthrow41 = __toESM(require_index_cjs(), 1);
|
|
67893
67936
|
|
|
67894
67937
|
// ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@22.19.15/node_modules/@inquirer/core/dist/esm/lib/key.js
|
|
67895
67938
|
var isUpKey = (key, keybindings = []) => (
|
|
@@ -70294,7 +70337,7 @@ var esm_default11 = createPrompt((config3, done) => {
|
|
|
70294
70337
|
});
|
|
70295
70338
|
|
|
70296
70339
|
// src/review-session.ts
|
|
70297
|
-
var
|
|
70340
|
+
var import_neverthrow40 = __toESM(require_index_cjs(), 1);
|
|
70298
70341
|
var CONFIDENCE_PERCENT = 100;
|
|
70299
70342
|
var FLOW_COL_WIDTH = 35;
|
|
70300
70343
|
var TRIGGER_COL_WIDTH = 16;
|
|
@@ -70447,15 +70490,15 @@ async function runInteractiveLoop(findings, existing) {
|
|
|
70447
70490
|
}
|
|
70448
70491
|
return { staged: state.staged, undoneKeys: state.undoneKeys };
|
|
70449
70492
|
}
|
|
70450
|
-
var safeRunInteractiveLoop = (0,
|
|
70493
|
+
var safeRunInteractiveLoop = (0, import_neverthrow40.fromAsyncThrowable)(
|
|
70451
70494
|
runInteractiveLoop,
|
|
70452
70495
|
(error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "exit-prompt" : "unexpected"
|
|
70453
70496
|
);
|
|
70454
70497
|
|
|
70455
70498
|
// src/commands/review-command.ts
|
|
70456
|
-
var safeReadFile3 = (0,
|
|
70457
|
-
var safeParseJson3 = (0,
|
|
70458
|
-
var safeWrite = (0,
|
|
70499
|
+
var safeReadFile3 = (0, import_neverthrow41.fromThrowable)((filePath) => (0, import_node_fs7.readFileSync)(filePath, "utf8"));
|
|
70500
|
+
var safeParseJson3 = (0, import_neverthrow41.fromThrowable)(JSON.parse);
|
|
70501
|
+
var safeWrite = (0, import_neverthrow41.fromThrowable)((filePath, content) => {
|
|
70459
70502
|
(0, import_node_fs7.writeFileSync)(filePath, content);
|
|
70460
70503
|
});
|
|
70461
70504
|
function readLastPath(xqaDirectory) {
|
|
@@ -70472,13 +70515,13 @@ function isPipelineOutput(data) {
|
|
|
70472
70515
|
function readFindings(filePath) {
|
|
70473
70516
|
const readResult = safeReadFile3(filePath);
|
|
70474
70517
|
if (readResult.isErr()) {
|
|
70475
|
-
return (0,
|
|
70518
|
+
return (0, import_neverthrow41.err)("not-found");
|
|
70476
70519
|
}
|
|
70477
70520
|
return safeParseJson3(readResult.value).mapErr(() => "invalid").andThen((data) => {
|
|
70478
70521
|
if (!isPipelineOutput(data)) {
|
|
70479
|
-
return (0,
|
|
70522
|
+
return (0, import_neverthrow41.err)("invalid");
|
|
70480
70523
|
}
|
|
70481
|
-
return (0,
|
|
70524
|
+
return (0, import_neverthrow41.ok)(data);
|
|
70482
70525
|
});
|
|
70483
70526
|
}
|
|
70484
70527
|
function loadExistingDismissals(filePath) {
|
|
@@ -70551,7 +70594,7 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
|
|
|
70551
70594
|
"No findings path provided and no last path found. Run: xqa review <findings-path>\n"
|
|
70552
70595
|
);
|
|
70553
70596
|
process.exit(1);
|
|
70554
|
-
return (0,
|
|
70597
|
+
return (0, import_neverthrow41.err)();
|
|
70555
70598
|
}
|
|
70556
70599
|
const resolvedPath = resolvedPathResult.value;
|
|
70557
70600
|
const findingsResult = readFindings(resolvedPath);
|
|
@@ -70564,9 +70607,9 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
|
|
|
70564
70607
|
`);
|
|
70565
70608
|
}
|
|
70566
70609
|
process.exit(1);
|
|
70567
|
-
return (0,
|
|
70610
|
+
return (0, import_neverthrow41.err)();
|
|
70568
70611
|
}
|
|
70569
|
-
return (0,
|
|
70612
|
+
return (0, import_neverthrow41.ok)({ resolvedPath, output: findingsResult.value });
|
|
70570
70613
|
}
|
|
70571
70614
|
async function runReviewLoop({
|
|
70572
70615
|
findings,
|
|
@@ -70640,40 +70683,40 @@ function stripExtensions(filename) {
|
|
|
70640
70683
|
// src/commands/spec-resolver.ts
|
|
70641
70684
|
var import_node_fs8 = require("node:fs");
|
|
70642
70685
|
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
70643
|
-
var
|
|
70686
|
+
var import_neverthrow43 = __toESM(require_index_cjs(), 1);
|
|
70644
70687
|
|
|
70645
70688
|
// src/spec-frontmatter.ts
|
|
70646
|
-
var
|
|
70689
|
+
var import_neverthrow42 = __toESM(require_index_cjs(), 1);
|
|
70647
70690
|
var FRONTMATTER_OPEN_LEN = 4;
|
|
70648
70691
|
var FRONTMATTER_MARKER_LEN = 3;
|
|
70649
70692
|
function extractFrontmatterBlock(content) {
|
|
70650
70693
|
const normalized = content.replaceAll("\r\n", "\n");
|
|
70651
70694
|
if (!normalized.startsWith("---")) {
|
|
70652
|
-
return (0,
|
|
70695
|
+
return (0, import_neverthrow42.err)({ type: "MISSING_FRONTMATTER" });
|
|
70653
70696
|
}
|
|
70654
70697
|
const end = normalized.indexOf("\n---", FRONTMATTER_MARKER_LEN);
|
|
70655
70698
|
if (end === -1) {
|
|
70656
|
-
return (0,
|
|
70699
|
+
return (0, import_neverthrow42.err)({ type: "MISSING_FRONTMATTER" });
|
|
70657
70700
|
}
|
|
70658
|
-
return (0,
|
|
70701
|
+
return (0, import_neverthrow42.ok)(normalized.slice(FRONTMATTER_OPEN_LEN, end));
|
|
70659
70702
|
}
|
|
70660
70703
|
function parseTimeout(fields) {
|
|
70661
70704
|
const raw = fields.get("timeout");
|
|
70662
70705
|
if (raw === void 0) {
|
|
70663
|
-
return (0,
|
|
70706
|
+
return (0, import_neverthrow42.ok)(raw);
|
|
70664
70707
|
}
|
|
70665
70708
|
const parsed = Number(raw);
|
|
70666
70709
|
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
70667
|
-
return (0,
|
|
70710
|
+
return (0, import_neverthrow42.err)({ type: "PARSE_ERROR", cause: `invalid timeout: ${raw}` });
|
|
70668
70711
|
}
|
|
70669
|
-
return (0,
|
|
70712
|
+
return (0, import_neverthrow42.ok)(parsed);
|
|
70670
70713
|
}
|
|
70671
70714
|
function parseSpecFrontmatter(content) {
|
|
70672
70715
|
return extractFrontmatterBlock(content).andThen((block) => {
|
|
70673
70716
|
const fields = parseYamlFields(block);
|
|
70674
70717
|
const feature = fields.get("feature");
|
|
70675
70718
|
if (feature === void 0) {
|
|
70676
|
-
return (0,
|
|
70719
|
+
return (0, import_neverthrow42.err)({ type: "MISSING_FIELD", field: "feature" });
|
|
70677
70720
|
}
|
|
70678
70721
|
return parseTimeout(fields).map((timeout) => ({ feature, timeout }));
|
|
70679
70722
|
});
|
|
@@ -70695,12 +70738,12 @@ function parseYamlFields(block) {
|
|
|
70695
70738
|
}
|
|
70696
70739
|
|
|
70697
70740
|
// src/commands/spec-resolver.ts
|
|
70698
|
-
var safeReadFile4 = (0,
|
|
70699
|
-
var safeReaddir = (0,
|
|
70741
|
+
var safeReadFile4 = (0, import_neverthrow43.fromThrowable)((filePath) => (0, import_node_fs8.readFileSync)(filePath, "utf8"));
|
|
70742
|
+
var safeReaddir = (0, import_neverthrow43.fromThrowable)(
|
|
70700
70743
|
(directory) => (0, import_node_fs8.readdirSync)(directory, { recursive: true, encoding: "utf8" })
|
|
70701
70744
|
);
|
|
70702
70745
|
var CANCEL = "xqa:cancel";
|
|
70703
|
-
var safeSelect =
|
|
70746
|
+
var safeSelect = import_neverthrow43.ResultAsync.fromThrowable(
|
|
70704
70747
|
esm_default11,
|
|
70705
70748
|
(error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "cancelled" : "failed"
|
|
70706
70749
|
);
|
|
@@ -70819,7 +70862,8 @@ async function executeSpec(input, context) {
|
|
|
70819
70862
|
const identity = {
|
|
70820
70863
|
display: createSoloDisplay(input.verbose),
|
|
70821
70864
|
itemId: "spec",
|
|
70822
|
-
itemName: import_node_path17.default.basename(context.absolutePath, ".test.md")
|
|
70865
|
+
itemName: import_node_path17.default.basename(context.absolutePath, ".test.md"),
|
|
70866
|
+
simulatorUdid: ""
|
|
70823
70867
|
};
|
|
70824
70868
|
const startedAt = Date.now();
|
|
70825
70869
|
emitItemStart(identity, startedAt);
|
|
@@ -70887,7 +70931,7 @@ function runUpdateCommand() {
|
|
|
70887
70931
|
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
70888
70932
|
var import_node_url2 = require("node:url");
|
|
70889
70933
|
var import_dotenv = __toESM(require_main(), 1);
|
|
70890
|
-
var
|
|
70934
|
+
var import_neverthrow44 = __toESM(require_index_cjs(), 1);
|
|
70891
70935
|
|
|
70892
70936
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
70893
70937
|
var external_exports2 = {};
|
|
@@ -74948,10 +74992,10 @@ function loadConfig() {
|
|
|
74948
74992
|
const messages = result.error.issues.map(
|
|
74949
74993
|
(issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`
|
|
74950
74994
|
);
|
|
74951
|
-
return (0,
|
|
74995
|
+
return (0, import_neverthrow44.err)({ type: "INVALID_CONFIG", message: `Configuration error:
|
|
74952
74996
|
${messages.join("\n")}` });
|
|
74953
74997
|
}
|
|
74954
|
-
return (0,
|
|
74998
|
+
return (0, import_neverthrow44.ok)(result.data);
|
|
74955
74999
|
}
|
|
74956
75000
|
|
|
74957
75001
|
// src/core/parse-timeout-seconds.ts
|
|
@@ -74984,7 +75028,7 @@ function parseVerboseOption(value) {
|
|
|
74984
75028
|
|
|
74985
75029
|
// src/pid-lock.ts
|
|
74986
75030
|
var import_node_fs9 = require("node:fs");
|
|
74987
|
-
var
|
|
75031
|
+
var import_neverthrow45 = __toESM(require_index_cjs(), 1);
|
|
74988
75032
|
var PID_FILE = "/tmp/xqa.pid";
|
|
74989
75033
|
var SIGINT_EXIT_CODE = 130;
|
|
74990
75034
|
var SIGTERM_EXIT_CODE = 143;
|
|
@@ -74993,7 +75037,7 @@ var HARD_TIMEOUT_MS = 1e4;
|
|
|
74993
75037
|
var cleanup = () => {
|
|
74994
75038
|
(0, import_node_fs9.rmSync)(PID_FILE, { force: true });
|
|
74995
75039
|
};
|
|
74996
|
-
var checkProcessRunning = (0,
|
|
75040
|
+
var checkProcessRunning = (0, import_neverthrow45.fromThrowable)(
|
|
74997
75041
|
(pid) => {
|
|
74998
75042
|
process.kill(pid, 0);
|
|
74999
75043
|
return true;
|
|
@@ -75059,17 +75103,17 @@ function acquireLock() {
|
|
|
75059
75103
|
// src/shell/xqa-directory.ts
|
|
75060
75104
|
var import_node_fs10 = require("node:fs");
|
|
75061
75105
|
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
75062
|
-
var
|
|
75106
|
+
var import_neverthrow46 = __toESM(require_index_cjs(), 1);
|
|
75063
75107
|
function findXqaDirectory(startDirectory) {
|
|
75064
75108
|
let current = startDirectory;
|
|
75065
75109
|
for (; ; ) {
|
|
75066
75110
|
const candidate = import_node_path19.default.join(current, ".xqa");
|
|
75067
75111
|
if ((0, import_node_fs10.existsSync)(candidate)) {
|
|
75068
|
-
return (0,
|
|
75112
|
+
return (0, import_neverthrow46.ok)(candidate);
|
|
75069
75113
|
}
|
|
75070
75114
|
const parent = import_node_path19.default.dirname(current);
|
|
75071
75115
|
if (parent === current) {
|
|
75072
|
-
return (0,
|
|
75116
|
+
return (0, import_neverthrow46.err)({ type: "XQA_NOT_INITIALIZED" });
|
|
75073
75117
|
}
|
|
75074
75118
|
current = parent;
|
|
75075
75119
|
}
|
|
@@ -75079,7 +75123,7 @@ function findXqaDirectory(startDirectory) {
|
|
|
75079
75123
|
var import_promises19 = __toESM(require("node:fs/promises"), 1);
|
|
75080
75124
|
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
75081
75125
|
var import_fast_glob = __toESM(require_out4(), 1);
|
|
75082
|
-
var
|
|
75126
|
+
var import_neverthrow51 = __toESM(require_index_cjs(), 1);
|
|
75083
75127
|
|
|
75084
75128
|
// src/suite/core/run-id.ts
|
|
75085
75129
|
var RUN_ID_PAD_LENGTH2 = 4;
|
|
@@ -75102,8 +75146,8 @@ function computeNextRunId(existingDirectories) {
|
|
|
75102
75146
|
}
|
|
75103
75147
|
|
|
75104
75148
|
// src/suite/core/suite-config-parser.ts
|
|
75105
|
-
var import_neverthrow46 = __toESM(require_index_cjs(), 1);
|
|
75106
75149
|
var import_neverthrow47 = __toESM(require_index_cjs(), 1);
|
|
75150
|
+
var import_neverthrow48 = __toESM(require_index_cjs(), 1);
|
|
75107
75151
|
var freestyleEntrySchema = external_exports2.object({
|
|
75108
75152
|
prompt: external_exports2.string().optional(),
|
|
75109
75153
|
timeoutSeconds: external_exports2.number().int().positive()
|
|
@@ -75122,7 +75166,7 @@ var suiteConfigSchema = external_exports2.object({
|
|
|
75122
75166
|
specs: external_exports2.array(external_exports2.string()).nonempty(),
|
|
75123
75167
|
freestyle: freestyleSchema
|
|
75124
75168
|
});
|
|
75125
|
-
var safeJsonParse4 = (0,
|
|
75169
|
+
var safeJsonParse4 = (0, import_neverthrow47.fromThrowable)(
|
|
75126
75170
|
JSON.parse,
|
|
75127
75171
|
(cause) => ({
|
|
75128
75172
|
type: "INVALID_SUITE_CONFIG",
|
|
@@ -75133,9 +75177,9 @@ function parseSuiteConfig(raw) {
|
|
|
75133
75177
|
return safeJsonParse4(raw).andThen((data) => {
|
|
75134
75178
|
const parsed = suiteConfigSchema.safeParse(data);
|
|
75135
75179
|
if (!parsed.success) {
|
|
75136
|
-
return (0,
|
|
75180
|
+
return (0, import_neverthrow48.err)({ type: "INVALID_SUITE_CONFIG", cause: parsed.error });
|
|
75137
75181
|
}
|
|
75138
|
-
return (0,
|
|
75182
|
+
return (0, import_neverthrow48.ok)({ specs: parsed.data.specs, freestyle: parsed.data.freestyle });
|
|
75139
75183
|
});
|
|
75140
75184
|
}
|
|
75141
75185
|
|
|
@@ -75201,7 +75245,7 @@ function buildFreestyleItems(entries) {
|
|
|
75201
75245
|
// src/suite/shell/suite-findings-writer.ts
|
|
75202
75246
|
var import_promises18 = __toESM(require("node:fs/promises"), 1);
|
|
75203
75247
|
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
75204
|
-
var
|
|
75248
|
+
var import_neverthrow49 = __toESM(require_index_cjs(), 1);
|
|
75205
75249
|
var INDENT_SPACES = 2;
|
|
75206
75250
|
function writeSuiteFindings(findings, options) {
|
|
75207
75251
|
const directory = import_node_path20.default.join(
|
|
@@ -75213,7 +75257,7 @@ function writeSuiteFindings(findings, options) {
|
|
|
75213
75257
|
);
|
|
75214
75258
|
const finalPath = import_node_path20.default.join(directory, "findings.json");
|
|
75215
75259
|
const temporaryPath = `${finalPath}.tmp`;
|
|
75216
|
-
const safeWriteAtomically =
|
|
75260
|
+
const safeWriteAtomically = import_neverthrow49.ResultAsync.fromThrowable(
|
|
75217
75261
|
async () => {
|
|
75218
75262
|
await import_promises18.default.mkdir(directory, { recursive: true });
|
|
75219
75263
|
await import_promises18.default.writeFile(temporaryPath, JSON.stringify(findings, void 0, INDENT_SPACES));
|
|
@@ -75226,7 +75270,7 @@ function writeSuiteFindings(findings, options) {
|
|
|
75226
75270
|
}
|
|
75227
75271
|
|
|
75228
75272
|
// src/suite/shell/worker-pool.ts
|
|
75229
|
-
var
|
|
75273
|
+
var import_neverthrow50 = __toESM(require_index_cjs(), 1);
|
|
75230
75274
|
|
|
75231
75275
|
// src/suite/shell/item-result-builder.ts
|
|
75232
75276
|
function getErrorMessage(cause) {
|
|
@@ -75454,7 +75498,7 @@ function runWorkerPool(config3) {
|
|
|
75454
75498
|
const queue = setupQueue(config3);
|
|
75455
75499
|
const results = [];
|
|
75456
75500
|
const suiteStartMs = Date.now();
|
|
75457
|
-
const safeRun =
|
|
75501
|
+
const safeRun = import_neverthrow50.ResultAsync.fromThrowable(
|
|
75458
75502
|
async () => runAllWorkers({ config: config3, queue, results, suiteStartMs }),
|
|
75459
75503
|
(cause) => ({ type: "WORKER_POOL_FAILED", cause })
|
|
75460
75504
|
);
|
|
@@ -75541,14 +75585,14 @@ function makeExecuteItem(context) {
|
|
|
75541
75585
|
|
|
75542
75586
|
// src/suite/commands/run-command.ts
|
|
75543
75587
|
var ISO_DATE_LENGTH3 = 10;
|
|
75544
|
-
var safeReaddir2 =
|
|
75588
|
+
var safeReaddir2 = import_neverthrow51.ResultAsync.fromThrowable(
|
|
75545
75589
|
async (directoryPath) => {
|
|
75546
75590
|
const entries = await import_promises19.default.readdir(directoryPath, { withFileTypes: true });
|
|
75547
75591
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
75548
75592
|
},
|
|
75549
75593
|
() => "READDIR_FAILED"
|
|
75550
75594
|
);
|
|
75551
|
-
var safeReadFile5 =
|
|
75595
|
+
var safeReadFile5 = import_neverthrow51.ResultAsync.fromThrowable(
|
|
75552
75596
|
async (filePath) => import_promises19.default.readFile(filePath, "utf8"),
|
|
75553
75597
|
() => "READ_FAILED"
|
|
75554
75598
|
);
|
|
@@ -75730,7 +75774,7 @@ function resolveXqaDirectory() {
|
|
|
75730
75774
|
return result.value;
|
|
75731
75775
|
}
|
|
75732
75776
|
var program2 = new Command();
|
|
75733
|
-
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.
|
|
75777
|
+
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"1.8.0"}${false ? ` (dev build +${"d16dbac"})` : ""}`);
|
|
75734
75778
|
program2.command("init").description("Initialize a new xqa project in the current directory").action(() => {
|
|
75735
75779
|
runInitCommand();
|
|
75736
75780
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/xqa",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.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": {
|