@exodus/xqa 1.17.0 → 2.0.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 +1093 -811
- package/package.json +1 -1
package/dist/xqa.cjs
CHANGED
|
@@ -1621,9 +1621,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1621
1621
|
if (fn) {
|
|
1622
1622
|
this._exitCallback = fn;
|
|
1623
1623
|
} else {
|
|
1624
|
-
this._exitCallback = (
|
|
1625
|
-
if (
|
|
1626
|
-
throw
|
|
1624
|
+
this._exitCallback = (err26) => {
|
|
1625
|
+
if (err26.code !== "commander.executeSubCommandAsync") {
|
|
1626
|
+
throw err26;
|
|
1627
1627
|
} else {
|
|
1628
1628
|
}
|
|
1629
1629
|
};
|
|
@@ -1699,12 +1699,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1699
1699
|
_callParseArg(target, value, previous, invalidArgumentMessage) {
|
|
1700
1700
|
try {
|
|
1701
1701
|
return target.parseArg(value, previous);
|
|
1702
|
-
} catch (
|
|
1703
|
-
if (
|
|
1704
|
-
const message = `${invalidArgumentMessage} ${
|
|
1705
|
-
this.error(message, { exitCode:
|
|
1702
|
+
} catch (err26) {
|
|
1703
|
+
if (err26.code === "commander.invalidArgument") {
|
|
1704
|
+
const message = `${invalidArgumentMessage} ${err26.message}`;
|
|
1705
|
+
this.error(message, { exitCode: err26.exitCode, code: err26.code });
|
|
1706
1706
|
}
|
|
1707
|
-
throw
|
|
1707
|
+
throw err26;
|
|
1708
1708
|
}
|
|
1709
1709
|
}
|
|
1710
1710
|
/**
|
|
@@ -2293,14 +2293,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2293
2293
|
);
|
|
2294
2294
|
}
|
|
2295
2295
|
});
|
|
2296
|
-
proc.on("error", (
|
|
2297
|
-
if (
|
|
2296
|
+
proc.on("error", (err26) => {
|
|
2297
|
+
if (err26.code === "ENOENT") {
|
|
2298
2298
|
this._checkForMissingExecutable(
|
|
2299
2299
|
executableFile,
|
|
2300
2300
|
executableDir,
|
|
2301
2301
|
subcommand._name
|
|
2302
2302
|
);
|
|
2303
|
-
} else if (
|
|
2303
|
+
} else if (err26.code === "EACCES") {
|
|
2304
2304
|
throw new Error(`'${executableFile}' not executable`);
|
|
2305
2305
|
}
|
|
2306
2306
|
if (!exitCallback) {
|
|
@@ -2311,7 +2311,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2311
2311
|
"commander.executeSubCommandAsync",
|
|
2312
2312
|
"(error)"
|
|
2313
2313
|
);
|
|
2314
|
-
wrappedError.nestedError =
|
|
2314
|
+
wrappedError.nestedError = err26;
|
|
2315
2315
|
exitCallback(wrappedError);
|
|
2316
2316
|
}
|
|
2317
2317
|
});
|
|
@@ -3688,8 +3688,8 @@ var require_index_cjs = __commonJS({
|
|
|
3688
3688
|
return new Ok(res.value);
|
|
3689
3689
|
})));
|
|
3690
3690
|
}
|
|
3691
|
-
match(
|
|
3692
|
-
return this._promise.then((res) => res.match(
|
|
3691
|
+
match(ok28, _err) {
|
|
3692
|
+
return this._promise.then((res) => res.match(ok28, _err));
|
|
3693
3693
|
}
|
|
3694
3694
|
unwrapOr(t) {
|
|
3695
3695
|
return this._promise.then((res) => res.unwrapOr(t));
|
|
@@ -3728,17 +3728,17 @@ var require_index_cjs = __commonJS({
|
|
|
3728
3728
|
function okAsync10(value) {
|
|
3729
3729
|
return new ResultAsync18(Promise.resolve(new Ok(value)));
|
|
3730
3730
|
}
|
|
3731
|
-
function errAsync10(
|
|
3732
|
-
return new ResultAsync18(Promise.resolve(new Err(
|
|
3731
|
+
function errAsync10(err27) {
|
|
3732
|
+
return new ResultAsync18(Promise.resolve(new Err(err27)));
|
|
3733
3733
|
}
|
|
3734
3734
|
var fromPromise = ResultAsync18.fromPromise;
|
|
3735
3735
|
var fromSafePromise2 = ResultAsync18.fromSafePromise;
|
|
3736
3736
|
var fromAsyncThrowable10 = ResultAsync18.fromThrowable;
|
|
3737
3737
|
var combineResultList = (resultList) => {
|
|
3738
|
-
let acc =
|
|
3738
|
+
let acc = ok27([]);
|
|
3739
3739
|
for (const result of resultList) {
|
|
3740
3740
|
if (result.isErr()) {
|
|
3741
|
-
acc =
|
|
3741
|
+
acc = err26(result.error);
|
|
3742
3742
|
break;
|
|
3743
3743
|
} else {
|
|
3744
3744
|
acc.map((list) => list.push(result.value));
|
|
@@ -3748,12 +3748,12 @@ var require_index_cjs = __commonJS({
|
|
|
3748
3748
|
};
|
|
3749
3749
|
var combineResultAsyncList = (asyncResultList) => ResultAsync18.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultList);
|
|
3750
3750
|
var combineResultListWithAllErrors = (resultList) => {
|
|
3751
|
-
let acc =
|
|
3751
|
+
let acc = ok27([]);
|
|
3752
3752
|
for (const result of resultList) {
|
|
3753
3753
|
if (result.isErr() && acc.isErr()) {
|
|
3754
3754
|
acc.error.push(result.error);
|
|
3755
3755
|
} else if (result.isErr() && acc.isOk()) {
|
|
3756
|
-
acc =
|
|
3756
|
+
acc = err26([result.error]);
|
|
3757
3757
|
} else if (result.isOk() && acc.isOk()) {
|
|
3758
3758
|
acc.value.push(result.value);
|
|
3759
3759
|
}
|
|
@@ -3767,9 +3767,9 @@ var require_index_cjs = __commonJS({
|
|
|
3767
3767
|
return (...args) => {
|
|
3768
3768
|
try {
|
|
3769
3769
|
const result = fn(...args);
|
|
3770
|
-
return
|
|
3770
|
+
return ok27(result);
|
|
3771
3771
|
} catch (e3) {
|
|
3772
|
-
return
|
|
3772
|
+
return err26(errorFn ? errorFn(e3) : e3);
|
|
3773
3773
|
}
|
|
3774
3774
|
};
|
|
3775
3775
|
}
|
|
@@ -3783,11 +3783,11 @@ var require_index_cjs = __commonJS({
|
|
|
3783
3783
|
}
|
|
3784
3784
|
Result3.combineWithAllErrors = combineWithAllErrors;
|
|
3785
3785
|
})(exports2.Result || (exports2.Result = {}));
|
|
3786
|
-
function
|
|
3786
|
+
function ok27(value) {
|
|
3787
3787
|
return new Ok(value);
|
|
3788
3788
|
}
|
|
3789
|
-
function
|
|
3790
|
-
return new Err(
|
|
3789
|
+
function err26(err27) {
|
|
3790
|
+
return new Err(err27);
|
|
3791
3791
|
}
|
|
3792
3792
|
function safeTry(body) {
|
|
3793
3793
|
const n3 = body().next();
|
|
@@ -3807,11 +3807,11 @@ var require_index_cjs = __commonJS({
|
|
|
3807
3807
|
return !this.isOk();
|
|
3808
3808
|
}
|
|
3809
3809
|
map(f6) {
|
|
3810
|
-
return
|
|
3810
|
+
return ok27(f6(this.value));
|
|
3811
3811
|
}
|
|
3812
3812
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3813
3813
|
mapErr(_f) {
|
|
3814
|
-
return
|
|
3814
|
+
return ok27(this.value);
|
|
3815
3815
|
}
|
|
3816
3816
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
3817
3817
|
andThen(f6) {
|
|
@@ -3826,14 +3826,14 @@ var require_index_cjs = __commonJS({
|
|
|
3826
3826
|
f6(this.value);
|
|
3827
3827
|
} catch (e3) {
|
|
3828
3828
|
}
|
|
3829
|
-
return
|
|
3829
|
+
return ok27(this.value);
|
|
3830
3830
|
}
|
|
3831
3831
|
orTee(_f) {
|
|
3832
|
-
return
|
|
3832
|
+
return ok27(this.value);
|
|
3833
3833
|
}
|
|
3834
3834
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
3835
3835
|
orElse(_f) {
|
|
3836
|
-
return
|
|
3836
|
+
return ok27(this.value);
|
|
3837
3837
|
}
|
|
3838
3838
|
asyncAndThen(f6) {
|
|
3839
3839
|
return f6(this.value);
|
|
@@ -3850,8 +3850,8 @@ var require_index_cjs = __commonJS({
|
|
|
3850
3850
|
return this.value;
|
|
3851
3851
|
}
|
|
3852
3852
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3853
|
-
match(
|
|
3854
|
-
return
|
|
3853
|
+
match(ok28, _err) {
|
|
3854
|
+
return ok28(this.value);
|
|
3855
3855
|
}
|
|
3856
3856
|
safeUnwrap() {
|
|
3857
3857
|
const value = this.value;
|
|
@@ -3882,27 +3882,27 @@ var require_index_cjs = __commonJS({
|
|
|
3882
3882
|
}
|
|
3883
3883
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3884
3884
|
map(_f) {
|
|
3885
|
-
return
|
|
3885
|
+
return err26(this.error);
|
|
3886
3886
|
}
|
|
3887
3887
|
mapErr(f6) {
|
|
3888
|
-
return
|
|
3888
|
+
return err26(f6(this.error));
|
|
3889
3889
|
}
|
|
3890
3890
|
andThrough(_f) {
|
|
3891
|
-
return
|
|
3891
|
+
return err26(this.error);
|
|
3892
3892
|
}
|
|
3893
3893
|
andTee(_f) {
|
|
3894
|
-
return
|
|
3894
|
+
return err26(this.error);
|
|
3895
3895
|
}
|
|
3896
3896
|
orTee(f6) {
|
|
3897
3897
|
try {
|
|
3898
3898
|
f6(this.error);
|
|
3899
3899
|
} catch (e3) {
|
|
3900
3900
|
}
|
|
3901
|
-
return
|
|
3901
|
+
return err26(this.error);
|
|
3902
3902
|
}
|
|
3903
3903
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
3904
3904
|
andThen(_f) {
|
|
3905
|
-
return
|
|
3905
|
+
return err26(this.error);
|
|
3906
3906
|
}
|
|
3907
3907
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
3908
3908
|
orElse(f6) {
|
|
@@ -3922,13 +3922,13 @@ var require_index_cjs = __commonJS({
|
|
|
3922
3922
|
unwrapOr(v2) {
|
|
3923
3923
|
return v2;
|
|
3924
3924
|
}
|
|
3925
|
-
match(_ok,
|
|
3926
|
-
return
|
|
3925
|
+
match(_ok, err27) {
|
|
3926
|
+
return err27(this.error);
|
|
3927
3927
|
}
|
|
3928
3928
|
safeUnwrap() {
|
|
3929
3929
|
const error48 = this.error;
|
|
3930
3930
|
return (function* () {
|
|
3931
|
-
yield
|
|
3931
|
+
yield err26(error48);
|
|
3932
3932
|
throw new Error("Do not use this generator out of `safeTry`");
|
|
3933
3933
|
})();
|
|
3934
3934
|
}
|
|
@@ -3948,13 +3948,13 @@ var require_index_cjs = __commonJS({
|
|
|
3948
3948
|
exports2.Err = Err;
|
|
3949
3949
|
exports2.Ok = Ok;
|
|
3950
3950
|
exports2.ResultAsync = ResultAsync18;
|
|
3951
|
-
exports2.err =
|
|
3951
|
+
exports2.err = err26;
|
|
3952
3952
|
exports2.errAsync = errAsync10;
|
|
3953
3953
|
exports2.fromAsyncThrowable = fromAsyncThrowable10;
|
|
3954
3954
|
exports2.fromPromise = fromPromise;
|
|
3955
3955
|
exports2.fromSafePromise = fromSafePromise2;
|
|
3956
3956
|
exports2.fromThrowable = fromThrowable17;
|
|
3957
|
-
exports2.ok =
|
|
3957
|
+
exports2.ok = ok27;
|
|
3958
3958
|
exports2.okAsync = okAsync10;
|
|
3959
3959
|
exports2.safeTry = safeTry;
|
|
3960
3960
|
}
|
|
@@ -11117,12 +11117,12 @@ var require_lib2 = __commonJS({
|
|
|
11117
11117
|
var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
|
|
11118
11118
|
let fd;
|
|
11119
11119
|
const fs4 = (0, node_1.default)();
|
|
11120
|
-
const handler2 = (
|
|
11120
|
+
const handler2 = (err26, buffer) => {
|
|
11121
11121
|
if (fd) {
|
|
11122
11122
|
fs4.closeSync(fd);
|
|
11123
11123
|
}
|
|
11124
|
-
if (
|
|
11125
|
-
reject(
|
|
11124
|
+
if (err26) {
|
|
11125
|
+
reject(err26);
|
|
11126
11126
|
} else if (buffer) {
|
|
11127
11127
|
resolve((0, exports2.detect)(buffer));
|
|
11128
11128
|
} else {
|
|
@@ -11133,9 +11133,9 @@ var require_lib2 = __commonJS({
|
|
|
11133
11133
|
if (sampleSize > 0) {
|
|
11134
11134
|
fd = fs4.openSync(filepath, "r");
|
|
11135
11135
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
11136
|
-
fs4.read(fd, sample, 0, sampleSize, opts.offset, (
|
|
11137
|
-
if (
|
|
11138
|
-
handler2(
|
|
11136
|
+
fs4.read(fd, sample, 0, sampleSize, opts.offset, (err26, bytesRead) => {
|
|
11137
|
+
if (err26) {
|
|
11138
|
+
handler2(err26, null);
|
|
11139
11139
|
} else {
|
|
11140
11140
|
if (bytesRead < sampleSize) {
|
|
11141
11141
|
sample = sample.subarray(0, bytesRead);
|
|
@@ -15059,8 +15059,8 @@ var require_kind_of = __commonJS({
|
|
|
15059
15059
|
if (typeof val.length === "number" && typeof val.callee === "function") {
|
|
15060
15060
|
return true;
|
|
15061
15061
|
}
|
|
15062
|
-
} catch (
|
|
15063
|
-
if (
|
|
15062
|
+
} catch (err26) {
|
|
15063
|
+
if (err26.message.indexOf("callee") !== -1) {
|
|
15064
15064
|
return true;
|
|
15065
15065
|
}
|
|
15066
15066
|
}
|
|
@@ -16283,7 +16283,7 @@ var require_function = __commonJS({
|
|
|
16283
16283
|
return false;
|
|
16284
16284
|
}
|
|
16285
16285
|
return true;
|
|
16286
|
-
} catch (
|
|
16286
|
+
} catch (err26) {
|
|
16287
16287
|
return false;
|
|
16288
16288
|
}
|
|
16289
16289
|
}
|
|
@@ -18070,11 +18070,11 @@ var require_engines = __commonJS({
|
|
|
18070
18070
|
str = "(function() {\nreturn " + str.trim() + ";\n}());";
|
|
18071
18071
|
}
|
|
18072
18072
|
return eval(str) || {};
|
|
18073
|
-
} catch (
|
|
18074
|
-
if (wrap !== false && /(unexpected|identifier)/i.test(
|
|
18073
|
+
} catch (err26) {
|
|
18074
|
+
if (wrap !== false && /(unexpected|identifier)/i.test(err26.message)) {
|
|
18075
18075
|
return parse(str, options, false);
|
|
18076
18076
|
}
|
|
18077
|
-
throw new SyntaxError(
|
|
18077
|
+
throw new SyntaxError(err26);
|
|
18078
18078
|
}
|
|
18079
18079
|
},
|
|
18080
18080
|
stringify: function() {
|
|
@@ -18636,9 +18636,9 @@ var require_main = __commonJS({
|
|
|
18636
18636
|
options2.path = vaultPath;
|
|
18637
18637
|
const result = DotenvModule.configDotenv(options2);
|
|
18638
18638
|
if (!result.parsed) {
|
|
18639
|
-
const
|
|
18640
|
-
|
|
18641
|
-
throw
|
|
18639
|
+
const err26 = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
18640
|
+
err26.code = "MISSING_DATA";
|
|
18641
|
+
throw err26;
|
|
18642
18642
|
}
|
|
18643
18643
|
const keys = _dotenvKey(options2).split(",");
|
|
18644
18644
|
const length = keys.length;
|
|
@@ -18681,30 +18681,30 @@ var require_main = __commonJS({
|
|
|
18681
18681
|
uri = new URL(dotenvKey);
|
|
18682
18682
|
} catch (error48) {
|
|
18683
18683
|
if (error48.code === "ERR_INVALID_URL") {
|
|
18684
|
-
const
|
|
18685
|
-
|
|
18686
|
-
throw
|
|
18684
|
+
const err26 = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
18685
|
+
err26.code = "INVALID_DOTENV_KEY";
|
|
18686
|
+
throw err26;
|
|
18687
18687
|
}
|
|
18688
18688
|
throw error48;
|
|
18689
18689
|
}
|
|
18690
18690
|
const key = uri.password;
|
|
18691
18691
|
if (!key) {
|
|
18692
|
-
const
|
|
18693
|
-
|
|
18694
|
-
throw
|
|
18692
|
+
const err26 = new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
18693
|
+
err26.code = "INVALID_DOTENV_KEY";
|
|
18694
|
+
throw err26;
|
|
18695
18695
|
}
|
|
18696
18696
|
const environment = uri.searchParams.get("environment");
|
|
18697
18697
|
if (!environment) {
|
|
18698
|
-
const
|
|
18699
|
-
|
|
18700
|
-
throw
|
|
18698
|
+
const err26 = new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
18699
|
+
err26.code = "INVALID_DOTENV_KEY";
|
|
18700
|
+
throw err26;
|
|
18701
18701
|
}
|
|
18702
18702
|
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
18703
18703
|
const ciphertext = result.parsed[environmentKey];
|
|
18704
18704
|
if (!ciphertext) {
|
|
18705
|
-
const
|
|
18706
|
-
|
|
18707
|
-
throw
|
|
18705
|
+
const err26 = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
18706
|
+
err26.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
18707
|
+
throw err26;
|
|
18708
18708
|
}
|
|
18709
18709
|
return { ciphertext, key };
|
|
18710
18710
|
}
|
|
@@ -18834,13 +18834,13 @@ var require_main = __commonJS({
|
|
|
18834
18834
|
const invalidKeyLength = error48.message === "Invalid key length";
|
|
18835
18835
|
const decryptionFailed = error48.message === "Unsupported state or unable to authenticate data";
|
|
18836
18836
|
if (isRange || invalidKeyLength) {
|
|
18837
|
-
const
|
|
18838
|
-
|
|
18839
|
-
throw
|
|
18837
|
+
const err26 = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
18838
|
+
err26.code = "INVALID_DOTENV_KEY";
|
|
18839
|
+
throw err26;
|
|
18840
18840
|
} else if (decryptionFailed) {
|
|
18841
|
-
const
|
|
18842
|
-
|
|
18843
|
-
throw
|
|
18841
|
+
const err26 = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
18842
|
+
err26.code = "DECRYPTION_FAILED";
|
|
18843
|
+
throw err26;
|
|
18844
18844
|
} else {
|
|
18845
18845
|
throw error48;
|
|
18846
18846
|
}
|
|
@@ -18850,9 +18850,9 @@ var require_main = __commonJS({
|
|
|
18850
18850
|
const debug = Boolean(options2 && options2.debug);
|
|
18851
18851
|
const override = Boolean(options2 && options2.override);
|
|
18852
18852
|
if (typeof parsed !== "object") {
|
|
18853
|
-
const
|
|
18854
|
-
|
|
18855
|
-
throw
|
|
18853
|
+
const err26 = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
18854
|
+
err26.code = "OBJECT_REQUIRED";
|
|
18855
|
+
throw err26;
|
|
18856
18856
|
}
|
|
18857
18857
|
for (const key of Object.keys(parsed)) {
|
|
18858
18858
|
if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
@@ -21993,8 +21993,8 @@ var require_picomatch = __commonJS({
|
|
|
21993
21993
|
try {
|
|
21994
21994
|
const opts = options2 || {};
|
|
21995
21995
|
return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
|
|
21996
|
-
} catch (
|
|
21997
|
-
if (options2 && options2.debug === true) throw
|
|
21996
|
+
} catch (err26) {
|
|
21997
|
+
if (options2 && options2.debug === true) throw err26;
|
|
21998
21998
|
return /$^/;
|
|
21999
21999
|
}
|
|
22000
22000
|
};
|
|
@@ -22401,8 +22401,8 @@ var require_merge2 = __commonJS({
|
|
|
22401
22401
|
}
|
|
22402
22402
|
next();
|
|
22403
22403
|
}
|
|
22404
|
-
function onerror(
|
|
22405
|
-
mergedStream.emit("error",
|
|
22404
|
+
function onerror(err26) {
|
|
22405
|
+
mergedStream.emit("error", err26);
|
|
22406
22406
|
}
|
|
22407
22407
|
if (stream._readableState.endEmitted) {
|
|
22408
22408
|
return next();
|
|
@@ -22766,8 +22766,8 @@ var require_out = __commonJS({
|
|
|
22766
22766
|
var require_queue_microtask = __commonJS({
|
|
22767
22767
|
"../../node_modules/.pnpm/queue-microtask@1.2.3/node_modules/queue-microtask/index.js"(exports2, module2) {
|
|
22768
22768
|
var promise2;
|
|
22769
|
-
module2.exports = typeof queueMicrotask === "function" ? queueMicrotask.bind(typeof window !== "undefined" ? window : global) : (cb2) => (promise2 || (promise2 = Promise.resolve())).then(cb2).catch((
|
|
22770
|
-
throw
|
|
22769
|
+
module2.exports = typeof queueMicrotask === "function" ? queueMicrotask.bind(typeof window !== "undefined" ? window : global) : (cb2) => (promise2 || (promise2 = Promise.resolve())).then(cb2).catch((err26) => setTimeout(() => {
|
|
22770
|
+
throw err26;
|
|
22771
22771
|
}, 0));
|
|
22772
22772
|
}
|
|
22773
22773
|
});
|
|
@@ -22788,32 +22788,32 @@ var require_run_parallel = __commonJS({
|
|
|
22788
22788
|
results = {};
|
|
22789
22789
|
pending = keys.length;
|
|
22790
22790
|
}
|
|
22791
|
-
function done(
|
|
22791
|
+
function done(err26) {
|
|
22792
22792
|
function end() {
|
|
22793
|
-
if (cb2) cb2(
|
|
22793
|
+
if (cb2) cb2(err26, results);
|
|
22794
22794
|
cb2 = null;
|
|
22795
22795
|
}
|
|
22796
22796
|
if (isSync) queueMicrotask2(end);
|
|
22797
22797
|
else end();
|
|
22798
22798
|
}
|
|
22799
|
-
function each(i3,
|
|
22799
|
+
function each(i3, err26, result) {
|
|
22800
22800
|
results[i3] = result;
|
|
22801
|
-
if (--pending === 0 ||
|
|
22802
|
-
done(
|
|
22801
|
+
if (--pending === 0 || err26) {
|
|
22802
|
+
done(err26);
|
|
22803
22803
|
}
|
|
22804
22804
|
}
|
|
22805
22805
|
if (!pending) {
|
|
22806
22806
|
done(null);
|
|
22807
22807
|
} else if (keys) {
|
|
22808
22808
|
keys.forEach(function(key) {
|
|
22809
|
-
tasks[key](function(
|
|
22810
|
-
each(key,
|
|
22809
|
+
tasks[key](function(err26, result) {
|
|
22810
|
+
each(key, err26, result);
|
|
22811
22811
|
});
|
|
22812
22812
|
});
|
|
22813
22813
|
} else {
|
|
22814
22814
|
tasks.forEach(function(task, i3) {
|
|
22815
|
-
task(function(
|
|
22816
|
-
each(i3,
|
|
22815
|
+
task(function(err26, result) {
|
|
22816
|
+
each(i3, err26, result);
|
|
22817
22817
|
});
|
|
22818
22818
|
});
|
|
22819
22819
|
}
|
|
@@ -23385,16 +23385,16 @@ var require_queue = __commonJS({
|
|
|
23385
23385
|
this.context = null;
|
|
23386
23386
|
this.errorHandler = null;
|
|
23387
23387
|
var self2 = this;
|
|
23388
|
-
this.worked = function worked(
|
|
23388
|
+
this.worked = function worked(err26, result) {
|
|
23389
23389
|
var callback = self2.callback;
|
|
23390
23390
|
var errorHandler = self2.errorHandler;
|
|
23391
23391
|
var val = self2.value;
|
|
23392
23392
|
self2.value = null;
|
|
23393
23393
|
self2.callback = noop4;
|
|
23394
23394
|
if (self2.errorHandler) {
|
|
23395
|
-
errorHandler(
|
|
23395
|
+
errorHandler(err26, val);
|
|
23396
23396
|
}
|
|
23397
|
-
callback.call(self2.context,
|
|
23397
|
+
callback.call(self2.context, err26, result);
|
|
23398
23398
|
self2.release(self2);
|
|
23399
23399
|
};
|
|
23400
23400
|
}
|
|
@@ -23418,9 +23418,9 @@ var require_queue = __commonJS({
|
|
|
23418
23418
|
return queue;
|
|
23419
23419
|
function push(value) {
|
|
23420
23420
|
var p = new Promise(function(resolve, reject) {
|
|
23421
|
-
pushCb(value, function(
|
|
23422
|
-
if (
|
|
23423
|
-
reject(
|
|
23421
|
+
pushCb(value, function(err26, result) {
|
|
23422
|
+
if (err26) {
|
|
23423
|
+
reject(err26);
|
|
23424
23424
|
return;
|
|
23425
23425
|
}
|
|
23426
23426
|
resolve(result);
|
|
@@ -23431,9 +23431,9 @@ var require_queue = __commonJS({
|
|
|
23431
23431
|
}
|
|
23432
23432
|
function unshift(value) {
|
|
23433
23433
|
var p = new Promise(function(resolve, reject) {
|
|
23434
|
-
unshiftCb(value, function(
|
|
23435
|
-
if (
|
|
23436
|
-
reject(
|
|
23434
|
+
unshiftCb(value, function(err26, result) {
|
|
23435
|
+
if (err26) {
|
|
23436
|
+
reject(err26);
|
|
23437
23437
|
return;
|
|
23438
23438
|
}
|
|
23439
23439
|
resolve(result);
|
|
@@ -24654,7 +24654,7 @@ var {
|
|
|
24654
24654
|
} = import_index.default;
|
|
24655
24655
|
|
|
24656
24656
|
// src/commands/analyse-command.ts
|
|
24657
|
-
var
|
|
24657
|
+
var import_promises18 = require("node:fs/promises");
|
|
24658
24658
|
|
|
24659
24659
|
// ../../packages/pipeline/dist/index.js
|
|
24660
24660
|
var import_node_fs2 = require("node:fs");
|
|
@@ -27947,9 +27947,9 @@ var tq = k((oq) => {
|
|
|
27947
27947
|
});
|
|
27948
27948
|
var sq = k((aq) => {
|
|
27949
27949
|
Object.defineProperty(aq, "__esModule", { value: true });
|
|
27950
|
-
var
|
|
27950
|
+
var ok27 = Q$(), tk = { keyword: "not", schemaType: ["object", "boolean"], trackErrors: true, code($) {
|
|
27951
27951
|
let { gen: X, schema: J, it: Q } = $;
|
|
27952
|
-
if ((0,
|
|
27952
|
+
if ((0, ok27.alwaysValidSchema)(Q, J)) {
|
|
27953
27953
|
$.fail();
|
|
27954
27954
|
return;
|
|
27955
27955
|
}
|
|
@@ -56400,6 +56400,24 @@ function createMobileIosServer(udid = "booted", extraTools = []) {
|
|
|
56400
56400
|
});
|
|
56401
56401
|
}
|
|
56402
56402
|
|
|
56403
|
+
// ../../packages/shared/dist/confidence.js
|
|
56404
|
+
var CONFIDENCE_LABELS = ["HIGH", "MEDIUM", "LOW"];
|
|
56405
|
+
var confidenceLabelSchema = external_exports.enum(CONFIDENCE_LABELS);
|
|
56406
|
+
var CONFIDENCE_ORDER = {
|
|
56407
|
+
LOW: 0,
|
|
56408
|
+
MEDIUM: 1,
|
|
56409
|
+
HIGH: 2
|
|
56410
|
+
};
|
|
56411
|
+
function compareConfidence(left, right) {
|
|
56412
|
+
return CONFIDENCE_ORDER[left] - CONFIDENCE_ORDER[right];
|
|
56413
|
+
}
|
|
56414
|
+
function maxConfidence(left, right) {
|
|
56415
|
+
return compareConfidence(left, right) >= 0 ? left : right;
|
|
56416
|
+
}
|
|
56417
|
+
function meetsConfidenceThreshold(label, threshold) {
|
|
56418
|
+
return compareConfidence(label, threshold) >= 0;
|
|
56419
|
+
}
|
|
56420
|
+
|
|
56403
56421
|
// ../../packages/shared/dist/finding-schema.js
|
|
56404
56422
|
var findingSchema = external_exports.object({
|
|
56405
56423
|
triggerType: external_exports.enum([
|
|
@@ -56420,12 +56438,15 @@ var findingSchema = external_exports.object({
|
|
|
56420
56438
|
]),
|
|
56421
56439
|
flow: external_exports.string(),
|
|
56422
56440
|
steps: external_exports.array(external_exports.string()),
|
|
56423
|
-
confidence:
|
|
56441
|
+
confidence: confidenceLabelSchema,
|
|
56424
56442
|
description: external_exports.string(),
|
|
56425
56443
|
screenshots: external_exports.array(external_exports.string()),
|
|
56426
56444
|
agent: external_exports.string()
|
|
56427
56445
|
});
|
|
56428
56446
|
|
|
56447
|
+
// ../../packages/shared/dist/finding-input-schema.js
|
|
56448
|
+
var findingInputSchema = findingSchema.omit({ agent: true, screenshots: true, confidence: true }).extend({ confidence: confidenceLabelSchema });
|
|
56449
|
+
|
|
56429
56450
|
// ../../packages/shared/dist/run-paths.js
|
|
56430
56451
|
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
56431
56452
|
var import_neverthrow8 = __toESM(require_index_cjs(), 1);
|
|
@@ -56458,8 +56479,8 @@ function dismissalsPath(baseDirectory, override) {
|
|
|
56458
56479
|
}
|
|
56459
56480
|
|
|
56460
56481
|
// ../../packages/pipeline/dist/index.js
|
|
56461
|
-
var
|
|
56462
|
-
var
|
|
56482
|
+
var import_neverthrow32 = __toESM(require_index_cjs(), 1);
|
|
56483
|
+
var import_promises16 = require("node:timers/promises");
|
|
56463
56484
|
|
|
56464
56485
|
// ../../agents/analyser/dist/index.js
|
|
56465
56486
|
var import_promises7 = require("node:fs/promises");
|
|
@@ -57424,6 +57445,47 @@ function formatMemoryElements(elements) {
|
|
|
57424
57445
|
(element) => `${element.label} [${String(Math.round(element.confidence * PCT_MULTIPLIER))}%${element.phase === "after-scroll" ? "\u2193" : ""}]`
|
|
57425
57446
|
).join(", ");
|
|
57426
57447
|
}
|
|
57448
|
+
function inspectorLabel(stepIndex, screenLabel) {
|
|
57449
|
+
return `inspector: step ${String(stepIndex + 1)} (${screenLabel})`;
|
|
57450
|
+
}
|
|
57451
|
+
function inspectorFailLines(label, event) {
|
|
57452
|
+
const desc = event.finding?.description ?? "unknown finding";
|
|
57453
|
+
return [
|
|
57454
|
+
{ kind: "text", style: "error", text: `${label} \u2014 \u2716 ${desc}`, source: "inspector" },
|
|
57455
|
+
{ kind: "annotation", level: "warning", message: `${label} \u2014 ${desc}` }
|
|
57456
|
+
];
|
|
57457
|
+
}
|
|
57458
|
+
function normalizeInspectorStepStart(event) {
|
|
57459
|
+
return [
|
|
57460
|
+
{
|
|
57461
|
+
kind: "text",
|
|
57462
|
+
style: "default",
|
|
57463
|
+
text: `inspector: analysing step ${String(event.stepIndex + 1)} (${event.screenLabel})`,
|
|
57464
|
+
source: "inspector"
|
|
57465
|
+
}
|
|
57466
|
+
];
|
|
57467
|
+
}
|
|
57468
|
+
function normalizeInspectorStep(event) {
|
|
57469
|
+
const label = inspectorLabel(event.stepIndex, event.screenLabel);
|
|
57470
|
+
switch (event.outcome) {
|
|
57471
|
+
case "pass": {
|
|
57472
|
+
return [
|
|
57473
|
+
{ kind: "text", style: "success", text: `${label} \u2014 matches design`, source: "inspector" }
|
|
57474
|
+
];
|
|
57475
|
+
}
|
|
57476
|
+
case "fail": {
|
|
57477
|
+
return inspectorFailLines(label, event);
|
|
57478
|
+
}
|
|
57479
|
+
case "stale": {
|
|
57480
|
+
return [
|
|
57481
|
+
{ kind: "text", style: "default", text: `${label} \u2014 stale artboard`, source: "inspector" }
|
|
57482
|
+
];
|
|
57483
|
+
}
|
|
57484
|
+
case "skip": {
|
|
57485
|
+
return [{ kind: "text", style: "default", text: `${label} \u2014 skipped`, source: "inspector" }];
|
|
57486
|
+
}
|
|
57487
|
+
}
|
|
57488
|
+
}
|
|
57427
57489
|
var HIDDEN_TOOL_ARGS = /* @__PURE__ */ new Set(["device"]);
|
|
57428
57490
|
var SCREEN_PREVIEW_LENGTH = 80;
|
|
57429
57491
|
var MS_PER_SECOND22 = 1e3;
|
|
@@ -57442,7 +57504,20 @@ function normalizeTimeoutGraceEntered(event) {
|
|
|
57442
57504
|
{
|
|
57443
57505
|
kind: "annotation",
|
|
57444
57506
|
level: "warning",
|
|
57445
|
-
message: `${event.agent}: soft deadline reached \u2014 ${String(seconds)}s grace period
|
|
57507
|
+
message: `${event.agent}: soft deadline reached \u2014 ${String(seconds)}s grace period before interrupt`
|
|
57508
|
+
}
|
|
57509
|
+
];
|
|
57510
|
+
}
|
|
57511
|
+
function normalizeFindingReported(event) {
|
|
57512
|
+
const marker = `#${String(event.findingIndex + 1)} [${event.finding.triggerType}]`;
|
|
57513
|
+
const header = `${event.agent}: finding ${marker} \u2014 ${event.finding.description}`;
|
|
57514
|
+
return [
|
|
57515
|
+
{ kind: "text", style: "error", text: header },
|
|
57516
|
+
{ kind: "text", style: "dim", text: ` screenshot: ${event.screenshotPath}` },
|
|
57517
|
+
{
|
|
57518
|
+
kind: "annotation",
|
|
57519
|
+
level: "warning",
|
|
57520
|
+
message: `${event.agent} finding ${marker}`
|
|
57446
57521
|
}
|
|
57447
57522
|
];
|
|
57448
57523
|
}
|
|
@@ -57556,47 +57631,6 @@ function normalizeError(event) {
|
|
|
57556
57631
|
}
|
|
57557
57632
|
return lines;
|
|
57558
57633
|
}
|
|
57559
|
-
function inspectorLabel(stepIndex, screenLabel) {
|
|
57560
|
-
return `inspector: step ${String(stepIndex + 1)} (${screenLabel})`;
|
|
57561
|
-
}
|
|
57562
|
-
function normalizeInspectorStepStart(event) {
|
|
57563
|
-
return [
|
|
57564
|
-
{
|
|
57565
|
-
kind: "text",
|
|
57566
|
-
style: "default",
|
|
57567
|
-
text: `inspector: analysing step ${String(event.stepIndex + 1)} (${event.screenLabel})`,
|
|
57568
|
-
source: "inspector"
|
|
57569
|
-
}
|
|
57570
|
-
];
|
|
57571
|
-
}
|
|
57572
|
-
function inspectorFailLines(label, event) {
|
|
57573
|
-
const desc = event.finding?.description ?? "unknown finding";
|
|
57574
|
-
return [
|
|
57575
|
-
{ kind: "text", style: "error", text: `${label} \u2014 \u2716 ${desc}`, source: "inspector" },
|
|
57576
|
-
{ kind: "annotation", level: "warning", message: `${label} \u2014 ${desc}` }
|
|
57577
|
-
];
|
|
57578
|
-
}
|
|
57579
|
-
function normalizeInspectorStep(event) {
|
|
57580
|
-
const label = inspectorLabel(event.stepIndex, event.screenLabel);
|
|
57581
|
-
switch (event.outcome) {
|
|
57582
|
-
case "pass": {
|
|
57583
|
-
return [
|
|
57584
|
-
{ kind: "text", style: "success", text: `${label} \u2014 matches design`, source: "inspector" }
|
|
57585
|
-
];
|
|
57586
|
-
}
|
|
57587
|
-
case "fail": {
|
|
57588
|
-
return inspectorFailLines(label, event);
|
|
57589
|
-
}
|
|
57590
|
-
case "stale": {
|
|
57591
|
-
return [
|
|
57592
|
-
{ kind: "text", style: "default", text: `${label} \u2014 stale artboard`, source: "inspector" }
|
|
57593
|
-
];
|
|
57594
|
-
}
|
|
57595
|
-
case "skip": {
|
|
57596
|
-
return [{ kind: "text", style: "default", text: `${label} \u2014 skipped`, source: "inspector" }];
|
|
57597
|
-
}
|
|
57598
|
-
}
|
|
57599
|
-
}
|
|
57600
57634
|
var HANDLERS2 = {
|
|
57601
57635
|
STAGE_START: (event) => normalizeStageStart(event),
|
|
57602
57636
|
STAGE_END: (event) => normalizeStageEnd(event),
|
|
@@ -57615,7 +57649,8 @@ var HANDLERS2 = {
|
|
|
57615
57649
|
INSPECTOR_STEP_START: (event) => normalizeInspectorStepStart(event),
|
|
57616
57650
|
INSPECTOR_STEP: (event) => normalizeInspectorStep(event),
|
|
57617
57651
|
TIMEOUT_GRACE_ENTERED: (event) => normalizeTimeoutGraceEntered(event),
|
|
57618
|
-
VISUAL_STEP: () => []
|
|
57652
|
+
VISUAL_STEP: () => [],
|
|
57653
|
+
FINDING_REPORTED: (event) => normalizeFindingReported(event)
|
|
57619
57654
|
};
|
|
57620
57655
|
function normalizeAgentEvent(event, verbose) {
|
|
57621
57656
|
return HANDLERS2[event.type](event, verbose);
|
|
@@ -58361,15 +58396,15 @@ async function makeRequest(url2, fetchOptions, fetchFn = fetch) {
|
|
|
58361
58396
|
return response;
|
|
58362
58397
|
}
|
|
58363
58398
|
function handleResponseError(e3, url2) {
|
|
58364
|
-
let
|
|
58365
|
-
if (
|
|
58366
|
-
|
|
58367
|
-
|
|
58399
|
+
let err26 = e3;
|
|
58400
|
+
if (err26.name === "AbortError") {
|
|
58401
|
+
err26 = new GoogleGenerativeAIAbortError(`Request aborted when fetching ${url2.toString()}: ${e3.message}`);
|
|
58402
|
+
err26.stack = e3.stack;
|
|
58368
58403
|
} else if (!(e3 instanceof GoogleGenerativeAIFetchError || e3 instanceof GoogleGenerativeAIRequestInputError)) {
|
|
58369
|
-
|
|
58370
|
-
|
|
58404
|
+
err26 = new GoogleGenerativeAIError(`Error fetching from ${url2.toString()}: ${e3.message}`);
|
|
58405
|
+
err26.stack = e3.stack;
|
|
58371
58406
|
}
|
|
58372
|
-
throw
|
|
58407
|
+
throw err26;
|
|
58373
58408
|
}
|
|
58374
58409
|
async function handleResponseNotOk(response, url2) {
|
|
58375
58410
|
let message = "";
|
|
@@ -58616,14 +58651,14 @@ function getResponseStream(inputStream) {
|
|
|
58616
58651
|
}
|
|
58617
58652
|
return pump();
|
|
58618
58653
|
}).catch((e3) => {
|
|
58619
|
-
let
|
|
58620
|
-
|
|
58621
|
-
if (
|
|
58622
|
-
|
|
58654
|
+
let err26 = e3;
|
|
58655
|
+
err26.stack = e3.stack;
|
|
58656
|
+
if (err26.name === "AbortError") {
|
|
58657
|
+
err26 = new GoogleGenerativeAIAbortError("Request aborted when reading from the stream");
|
|
58623
58658
|
} else {
|
|
58624
|
-
|
|
58659
|
+
err26 = new GoogleGenerativeAIError("Error reading from the stream");
|
|
58625
58660
|
}
|
|
58626
|
-
throw
|
|
58661
|
+
throw err26;
|
|
58627
58662
|
});
|
|
58628
58663
|
}
|
|
58629
58664
|
}
|
|
@@ -59219,15 +59254,15 @@ async function makeRequest2(url2, fetchOptions, fetchFn = fetch) {
|
|
|
59219
59254
|
return response;
|
|
59220
59255
|
}
|
|
59221
59256
|
function handleResponseError2(e3, url2) {
|
|
59222
|
-
let
|
|
59223
|
-
if (
|
|
59224
|
-
|
|
59225
|
-
|
|
59257
|
+
let err26 = e3;
|
|
59258
|
+
if (err26.name === "AbortError") {
|
|
59259
|
+
err26 = new GoogleGenerativeAIAbortError2(`Request aborted when fetching ${url2.toString()}: ${e3.message}`);
|
|
59260
|
+
err26.stack = e3.stack;
|
|
59226
59261
|
} else if (!(e3 instanceof GoogleGenerativeAIFetchError2 || e3 instanceof GoogleGenerativeAIRequestInputError2)) {
|
|
59227
|
-
|
|
59228
|
-
|
|
59262
|
+
err26 = new GoogleGenerativeAIError2(`Error fetching from ${url2.toString()}: ${e3.message}`);
|
|
59263
|
+
err26.stack = e3.stack;
|
|
59229
59264
|
}
|
|
59230
|
-
throw
|
|
59265
|
+
throw err26;
|
|
59231
59266
|
}
|
|
59232
59267
|
async function handleResponseNotOk2(response, url2) {
|
|
59233
59268
|
let message = "";
|
|
@@ -59542,7 +59577,16 @@ var DynamicRetrievalMode2;
|
|
|
59542
59577
|
var import_neverthrow11 = __toESM(require_index_cjs(), 1);
|
|
59543
59578
|
var MAX_POLL_ATTEMPTS = 30;
|
|
59544
59579
|
var POLL_INTERVAL_MS = 2e3;
|
|
59545
|
-
var
|
|
59580
|
+
var categoricalFindingSchema = external_exports.object({
|
|
59581
|
+
triggerType: external_exports.string(),
|
|
59582
|
+
flow: external_exports.string(),
|
|
59583
|
+
steps: external_exports.array(external_exports.string()),
|
|
59584
|
+
description: external_exports.string(),
|
|
59585
|
+
confidence: external_exports.enum(["HIGH", "MEDIUM"]),
|
|
59586
|
+
screenshots: external_exports.array(external_exports.string()),
|
|
59587
|
+
agent: external_exports.string()
|
|
59588
|
+
});
|
|
59589
|
+
var categoricalFindingsArraySchema = external_exports.array(categoricalFindingSchema);
|
|
59546
59590
|
var safeJsonParse2 = (0, import_neverthrow11.fromThrowable)(JSON.parse);
|
|
59547
59591
|
var FINDINGS_RESPONSE_SCHEMA = {
|
|
59548
59592
|
type: "array",
|
|
@@ -59561,12 +59605,12 @@ var FINDINGS_RESPONSE_SCHEMA = {
|
|
|
59561
59605
|
},
|
|
59562
59606
|
flow: { type: "string" },
|
|
59563
59607
|
steps: { type: "array", items: { type: "string" } },
|
|
59564
|
-
confidence: { type: "number" },
|
|
59565
59608
|
description: { type: "string" },
|
|
59609
|
+
confidence: { type: "string", format: "enum", enum: ["HIGH", "MEDIUM"] },
|
|
59566
59610
|
screenshots: { type: "array", items: { type: "string" } },
|
|
59567
59611
|
agent: { type: "string", format: "enum", enum: ["analyser"] }
|
|
59568
59612
|
},
|
|
59569
|
-
required: ["triggerType", "flow", "steps", "
|
|
59613
|
+
required: ["triggerType", "flow", "steps", "description", "confidence", "screenshots", "agent"]
|
|
59570
59614
|
}
|
|
59571
59615
|
};
|
|
59572
59616
|
function extractFileName(fileUri) {
|
|
@@ -59615,17 +59659,21 @@ function parseAnalysisResponse(text) {
|
|
|
59615
59659
|
return (0, import_neverthrow11.err)({ type: "REQUEST_FAILED", cause: parseResult.error });
|
|
59616
59660
|
}
|
|
59617
59661
|
const raw = parseResult.value;
|
|
59618
|
-
const validated =
|
|
59662
|
+
const validated = categoricalFindingsArraySchema.safeParse(raw);
|
|
59619
59663
|
if (!validated.success) {
|
|
59620
59664
|
return (0, import_neverthrow11.err)({ type: "SCHEMA_VALIDATION_FAILED", cause: validated.error });
|
|
59621
59665
|
}
|
|
59622
|
-
|
|
59666
|
+
const findings = validated.data.map((finding) => ({ ...finding }));
|
|
59667
|
+
return (0, import_neverthrow11.ok)(findings);
|
|
59623
59668
|
}
|
|
59669
|
+
var STEP_BY_STEP_DIRECTIVE = "Think step by step before calling set_output.";
|
|
59624
59670
|
function buildGenerativeModel(apiKey, model) {
|
|
59625
59671
|
const genAI = new GoogleGenerativeAI(apiKey);
|
|
59626
59672
|
return genAI.getGenerativeModel({
|
|
59627
59673
|
model,
|
|
59674
|
+
systemInstruction: STEP_BY_STEP_DIRECTIVE,
|
|
59628
59675
|
generationConfig: {
|
|
59676
|
+
temperature: 0,
|
|
59629
59677
|
responseMimeType: "application/json",
|
|
59630
59678
|
responseSchema: FINDINGS_RESPONSE_SCHEMA
|
|
59631
59679
|
}
|
|
@@ -59687,9 +59735,11 @@ var OUTPUT_FIELDS_SECTION = `For each finding:
|
|
|
59687
59735
|
- \`triggerType\`: the category in parentheses from the section headings above
|
|
59688
59736
|
- \`flow\`: name of the user flow from the snapshots (e.g. "send-funds", "onboarding")
|
|
59689
59737
|
- \`steps\`: stepIndex values from the snapshots visible during or immediately before the issue
|
|
59690
|
-
- \`
|
|
59691
|
-
- \`
|
|
59692
|
-
- \`screenshots\`: the \`screenshotPath\` values from the matching snapshots as reference identifiers \u2014 or the stepIndex as a string if no path is present
|
|
59738
|
+
- \`description\`: name the element, state what it was doing, and state how long or across how many steps the issue persisted \u2014 write this first, before committing to a confidence label
|
|
59739
|
+
- \`confidence\`: HIGH for unambiguous regressions visible repeatedly with no plausible intentional cause; MEDIUM for issues that are visible but ambiguous (could be a deliberate design choice); LOW \u2014 do not include the finding at all, omit it entirely
|
|
59740
|
+
- \`screenshots\`: the \`screenshotPath\` values from the matching snapshots as reference identifiers \u2014 or the stepIndex as a string if no path is present
|
|
59741
|
+
|
|
59742
|
+
Write the description first \u2014 justify what you saw and across how many steps \u2014 only then commit to a HIGH or MEDIUM label.`;
|
|
59693
59743
|
function buildAnalyserPrompt(snapshots) {
|
|
59694
59744
|
const snapshotHistory = JSON.stringify(snapshots, void 0, 2);
|
|
59695
59745
|
return `You are a QA engineer watching a recorded mobile app session. Your task is to identify issues that can only be detected by watching the full video \u2014 things a static screenshot or accessibility tree cannot reveal.
|
|
@@ -59812,34 +59862,34 @@ var uuid42 = function() {
|
|
|
59812
59862
|
};
|
|
59813
59863
|
|
|
59814
59864
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/internal/errors.mjs
|
|
59815
|
-
function isAbortError(
|
|
59816
|
-
return typeof
|
|
59817
|
-
("name" in
|
|
59818
|
-
"message" in
|
|
59819
|
-
}
|
|
59820
|
-
var castToError = (
|
|
59821
|
-
if (
|
|
59822
|
-
return
|
|
59823
|
-
if (typeof
|
|
59865
|
+
function isAbortError(err26) {
|
|
59866
|
+
return typeof err26 === "object" && err26 !== null && // Spec-compliant fetch implementations
|
|
59867
|
+
("name" in err26 && err26.name === "AbortError" || // Expo fetch
|
|
59868
|
+
"message" in err26 && String(err26.message).includes("FetchRequestCanceledException"));
|
|
59869
|
+
}
|
|
59870
|
+
var castToError = (err26) => {
|
|
59871
|
+
if (err26 instanceof Error)
|
|
59872
|
+
return err26;
|
|
59873
|
+
if (typeof err26 === "object" && err26 !== null) {
|
|
59824
59874
|
try {
|
|
59825
|
-
if (Object.prototype.toString.call(
|
|
59826
|
-
const error48 = new Error(
|
|
59827
|
-
if (
|
|
59828
|
-
error48.stack =
|
|
59829
|
-
if (
|
|
59830
|
-
error48.cause =
|
|
59831
|
-
if (
|
|
59832
|
-
error48.name =
|
|
59875
|
+
if (Object.prototype.toString.call(err26) === "[object Error]") {
|
|
59876
|
+
const error48 = new Error(err26.message, err26.cause ? { cause: err26.cause } : {});
|
|
59877
|
+
if (err26.stack)
|
|
59878
|
+
error48.stack = err26.stack;
|
|
59879
|
+
if (err26.cause && !error48.cause)
|
|
59880
|
+
error48.cause = err26.cause;
|
|
59881
|
+
if (err26.name)
|
|
59882
|
+
error48.name = err26.name;
|
|
59833
59883
|
return error48;
|
|
59834
59884
|
}
|
|
59835
59885
|
} catch {
|
|
59836
59886
|
}
|
|
59837
59887
|
try {
|
|
59838
|
-
return new Error(JSON.stringify(
|
|
59888
|
+
return new Error(JSON.stringify(err26));
|
|
59839
59889
|
} catch {
|
|
59840
59890
|
}
|
|
59841
59891
|
}
|
|
59842
|
-
return new Error(
|
|
59892
|
+
return new Error(err26);
|
|
59843
59893
|
};
|
|
59844
59894
|
|
|
59845
59895
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@4.3.6/node_modules/@anthropic-ai/sdk/core/error.mjs
|
|
@@ -59969,7 +60019,7 @@ var validatePositiveInteger = (name, n3) => {
|
|
|
59969
60019
|
var safeJSON = (text) => {
|
|
59970
60020
|
try {
|
|
59971
60021
|
return JSON.parse(text);
|
|
59972
|
-
} catch (
|
|
60022
|
+
} catch (err26) {
|
|
59973
60023
|
return void 0;
|
|
59974
60024
|
}
|
|
59975
60025
|
};
|
|
@@ -60533,8 +60583,8 @@ var Stream = class _Stream {
|
|
|
60533
60583
|
return ctrl.close();
|
|
60534
60584
|
const bytes = encodeUTF8(JSON.stringify(value) + "\n");
|
|
60535
60585
|
ctrl.enqueue(bytes);
|
|
60536
|
-
} catch (
|
|
60537
|
-
ctrl.error(
|
|
60586
|
+
} catch (err26) {
|
|
60587
|
+
ctrl.error(err26);
|
|
60538
60588
|
}
|
|
60539
60589
|
},
|
|
60540
60590
|
async cancel() {
|
|
@@ -62441,8 +62491,8 @@ var BetaMessageStream = class _BetaMessageStream {
|
|
|
62441
62491
|
if (jsonBuf) {
|
|
62442
62492
|
try {
|
|
62443
62493
|
newContent.input = partialParse(jsonBuf);
|
|
62444
|
-
} catch (
|
|
62445
|
-
const error48 = new AnthropicError(`Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: ${
|
|
62494
|
+
} catch (err26) {
|
|
62495
|
+
const error48 = new AnthropicError(`Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: ${err26}. JSON: ${jsonBuf}`);
|
|
62446
62496
|
__classPrivateFieldGet(this, _BetaMessageStream_handleError, "f").call(this, error48);
|
|
62447
62497
|
}
|
|
62448
62498
|
}
|
|
@@ -62504,17 +62554,17 @@ var BetaMessageStream = class _BetaMessageStream {
|
|
|
62504
62554
|
}
|
|
62505
62555
|
readQueue.length = 0;
|
|
62506
62556
|
});
|
|
62507
|
-
this.on("abort", (
|
|
62557
|
+
this.on("abort", (err26) => {
|
|
62508
62558
|
done = true;
|
|
62509
62559
|
for (const reader of readQueue) {
|
|
62510
|
-
reader.reject(
|
|
62560
|
+
reader.reject(err26);
|
|
62511
62561
|
}
|
|
62512
62562
|
readQueue.length = 0;
|
|
62513
62563
|
});
|
|
62514
|
-
this.on("error", (
|
|
62564
|
+
this.on("error", (err26) => {
|
|
62515
62565
|
done = true;
|
|
62516
62566
|
for (const reader of readQueue) {
|
|
62517
|
-
reader.reject(
|
|
62567
|
+
reader.reject(err26);
|
|
62518
62568
|
}
|
|
62519
62569
|
readQueue.length = 0;
|
|
62520
62570
|
});
|
|
@@ -64757,17 +64807,17 @@ var MessageStream = class _MessageStream {
|
|
|
64757
64807
|
}
|
|
64758
64808
|
readQueue.length = 0;
|
|
64759
64809
|
});
|
|
64760
|
-
this.on("abort", (
|
|
64810
|
+
this.on("abort", (err26) => {
|
|
64761
64811
|
done = true;
|
|
64762
64812
|
for (const reader of readQueue) {
|
|
64763
|
-
reader.reject(
|
|
64813
|
+
reader.reject(err26);
|
|
64764
64814
|
}
|
|
64765
64815
|
readQueue.length = 0;
|
|
64766
64816
|
});
|
|
64767
|
-
this.on("error", (
|
|
64817
|
+
this.on("error", (err26) => {
|
|
64768
64818
|
done = true;
|
|
64769
64819
|
for (const reader of readQueue) {
|
|
64770
|
-
reader.reject(
|
|
64820
|
+
reader.reject(err26);
|
|
64771
64821
|
}
|
|
64772
64822
|
readQueue.length = 0;
|
|
64773
64823
|
});
|
|
@@ -65347,7 +65397,7 @@ var BaseAnthropic = class {
|
|
|
65347
65397
|
}
|
|
65348
65398
|
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
65349
65399
|
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
65350
|
-
const errText = await response.text().catch((
|
|
65400
|
+
const errText = await response.text().catch((err27) => castToError(err27).message);
|
|
65351
65401
|
const errJSON = safeJSON(errText);
|
|
65352
65402
|
const errMessage = errJSON ? void 0 : errText;
|
|
65353
65403
|
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
@@ -65358,8 +65408,8 @@ var BaseAnthropic = class {
|
|
|
65358
65408
|
message: errMessage,
|
|
65359
65409
|
durationMs: Date.now() - startTime
|
|
65360
65410
|
}));
|
|
65361
|
-
const
|
|
65362
|
-
throw
|
|
65411
|
+
const err26 = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
65412
|
+
throw err26;
|
|
65363
65413
|
}
|
|
65364
65414
|
loggerFor(this).info(responseInfo);
|
|
65365
65415
|
loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
|
|
@@ -65616,51 +65666,20 @@ function createOutputTools(schema2) {
|
|
|
65616
65666
|
})
|
|
65617
65667
|
};
|
|
65618
65668
|
}
|
|
65619
|
-
function buildOutputServer(options2) {
|
|
65620
|
-
return xx({
|
|
65621
|
-
name: options2.serverName,
|
|
65622
|
-
tools: [
|
|
65623
|
-
_x(
|
|
65624
|
-
"set_output",
|
|
65625
|
-
"Report the final output when the task is complete. Call once at the end of the session.",
|
|
65626
|
-
options2.shape,
|
|
65627
|
-
async (input) => {
|
|
65628
|
-
options2.store(input);
|
|
65629
|
-
return await Promise.resolve({ content: [{ type: "text", text: "ok" }] });
|
|
65630
|
-
}
|
|
65631
|
-
)
|
|
65632
|
-
]
|
|
65633
|
-
});
|
|
65634
|
-
}
|
|
65635
|
-
function createOutputTool(shape, options2) {
|
|
65636
|
-
const serverName = options2?.serverName ?? "output";
|
|
65637
|
-
const schema2 = external_exports.object(shape);
|
|
65638
|
-
let current;
|
|
65639
|
-
function store(input) {
|
|
65640
|
-
const parsed = schema2.safeParse(input);
|
|
65641
|
-
if (parsed.success) {
|
|
65642
|
-
current = parsed.data;
|
|
65643
|
-
}
|
|
65644
|
-
}
|
|
65645
|
-
return {
|
|
65646
|
-
server: buildOutputServer({ serverName, shape, store }),
|
|
65647
|
-
getOutput: () => current,
|
|
65648
|
-
captureInput: store,
|
|
65649
|
-
allowedToolNames: [`mcp__${serverName}__set_output`]
|
|
65650
|
-
};
|
|
65651
|
-
}
|
|
65652
65669
|
|
|
65653
65670
|
// ../../agents/consolidator/dist/index.js
|
|
65654
65671
|
var import_neverthrow14 = __toESM(require_index_cjs(), 1);
|
|
65672
|
+
var import_neverthrow15 = __toESM(require_index_cjs(), 1);
|
|
65655
65673
|
var MODEL = "claude-opus-4-6";
|
|
65656
65674
|
var MAX_TOKENS = 4096;
|
|
65657
|
-
var
|
|
65658
|
-
|
|
65675
|
+
var findingWithoutConfidenceSchema = findingSchema.omit({ confidence: true });
|
|
65676
|
+
var dismissedRawFindingSchema = external_exports.object({
|
|
65677
|
+
finding: findingWithoutConfidenceSchema,
|
|
65659
65678
|
reason: external_exports.string()
|
|
65660
65679
|
});
|
|
65661
|
-
var
|
|
65662
|
-
findings: external_exports.array(
|
|
65663
|
-
dismissed: external_exports.array(
|
|
65680
|
+
var rawConsolidationOutputSchema = external_exports.object({
|
|
65681
|
+
findings: external_exports.array(findingWithoutConfidenceSchema),
|
|
65682
|
+
dismissed: external_exports.array(dismissedRawFindingSchema)
|
|
65664
65683
|
});
|
|
65665
65684
|
async function fetchMessage({
|
|
65666
65685
|
client,
|
|
@@ -65690,7 +65709,10 @@ function processToolUseBlock(toolUseBlock, context) {
|
|
|
65690
65709
|
});
|
|
65691
65710
|
const result = context.factory.handleToolCall(toolUseBlock.name, toolUseBlock.input);
|
|
65692
65711
|
if (result.isErr()) {
|
|
65693
|
-
return (0, import_neverthrow14.err)({
|
|
65712
|
+
return (0, import_neverthrow14.err)({
|
|
65713
|
+
type: "REQUEST_FAILED",
|
|
65714
|
+
cause: result.error
|
|
65715
|
+
});
|
|
65694
65716
|
}
|
|
65695
65717
|
const output = context.factory.getOutput();
|
|
65696
65718
|
if (output === void 0) {
|
|
@@ -65698,7 +65720,7 @@ function processToolUseBlock(toolUseBlock, context) {
|
|
|
65698
65720
|
}
|
|
65699
65721
|
return (0, import_neverthrow14.ok)(output);
|
|
65700
65722
|
}
|
|
65701
|
-
function
|
|
65723
|
+
function extractRawOutput(response, context) {
|
|
65702
65724
|
emitThoughts(response, context.onEvent);
|
|
65703
65725
|
const toolUseBlock = response.content.find(
|
|
65704
65726
|
(block) => block.type === "tool_use" && block.name === "set_output"
|
|
@@ -65710,13 +65732,74 @@ function extractConsolidationResult(response, context) {
|
|
|
65710
65732
|
}
|
|
65711
65733
|
function consolidateFindings(prompt, onEvent) {
|
|
65712
65734
|
const client = new Anthropic();
|
|
65713
|
-
const factory = createOutputTools(
|
|
65735
|
+
const factory = createOutputTools(rawConsolidationOutputSchema);
|
|
65714
65736
|
const tools = [factory.tools[1]];
|
|
65715
65737
|
return (0, import_neverthrow14.fromAsyncThrowable)(
|
|
65716
65738
|
fetchMessage,
|
|
65717
65739
|
(cause) => ({ type: "REQUEST_FAILED", cause })
|
|
65718
65740
|
)({ client, prompt, tools }).andThen(
|
|
65719
|
-
(response) =>
|
|
65741
|
+
(response) => extractRawOutput(response, { factory, onEvent })
|
|
65742
|
+
);
|
|
65743
|
+
}
|
|
65744
|
+
function normalizeKey(value) {
|
|
65745
|
+
return value.toLowerCase().trim();
|
|
65746
|
+
}
|
|
65747
|
+
function findByKey(findings, key) {
|
|
65748
|
+
const normalizedFlow = normalizeKey(key.flow);
|
|
65749
|
+
const normalizedDescription = normalizeKey(key.description);
|
|
65750
|
+
return findings.find(
|
|
65751
|
+
(finding) => normalizeKey(finding.flow) === normalizedFlow && normalizeKey(finding.description) === normalizedDescription
|
|
65752
|
+
);
|
|
65753
|
+
}
|
|
65754
|
+
function resolveConfidence(output, pool) {
|
|
65755
|
+
const key = { flow: output.flow, description: output.description };
|
|
65756
|
+
const metadataMatch = findByKey(pool.metadataFindings, key);
|
|
65757
|
+
const visualMatch = findByKey(pool.visualFindings, key);
|
|
65758
|
+
if (metadataMatch !== void 0 && visualMatch !== void 0) {
|
|
65759
|
+
return (0, import_neverthrow15.ok)(maxConfidence(metadataMatch.confidence, visualMatch.confidence));
|
|
65760
|
+
}
|
|
65761
|
+
if (metadataMatch !== void 0) {
|
|
65762
|
+
return (0, import_neverthrow15.ok)(metadataMatch.confidence);
|
|
65763
|
+
}
|
|
65764
|
+
if (visualMatch !== void 0) {
|
|
65765
|
+
return (0, import_neverthrow15.ok)(visualMatch.confidence);
|
|
65766
|
+
}
|
|
65767
|
+
return (0, import_neverthrow15.err)({
|
|
65768
|
+
type: "UNMATCHED_OUTPUT_FINDING",
|
|
65769
|
+
flow: output.flow,
|
|
65770
|
+
description: output.description
|
|
65771
|
+
});
|
|
65772
|
+
}
|
|
65773
|
+
function attachConfidence(output, pool) {
|
|
65774
|
+
return resolveConfidence(output, pool).map((confidence) => ({ ...output, confidence }));
|
|
65775
|
+
}
|
|
65776
|
+
function mergeFindings(outputs, state) {
|
|
65777
|
+
if (outputs.length === 0) {
|
|
65778
|
+
return (0, import_neverthrow15.ok)(state.accumulated);
|
|
65779
|
+
}
|
|
65780
|
+
const [head, ...tail] = outputs;
|
|
65781
|
+
return attachConfidence(head, state.pool).andThen(
|
|
65782
|
+
(finding) => mergeFindings(tail, { pool: state.pool, accumulated: [...state.accumulated, finding] })
|
|
65783
|
+
);
|
|
65784
|
+
}
|
|
65785
|
+
function mergeDismissed(outputs, state) {
|
|
65786
|
+
if (outputs.length === 0) {
|
|
65787
|
+
return (0, import_neverthrow15.ok)(state.accumulated);
|
|
65788
|
+
}
|
|
65789
|
+
const [head, ...tail] = outputs;
|
|
65790
|
+
return attachConfidence(head.finding, state.pool).andThen(
|
|
65791
|
+
(finding) => mergeDismissed(tail, {
|
|
65792
|
+
pool: state.pool,
|
|
65793
|
+
accumulated: [...state.accumulated, { finding, reason: head.reason }]
|
|
65794
|
+
})
|
|
65795
|
+
);
|
|
65796
|
+
}
|
|
65797
|
+
function attachAllConfidences(raw, pool) {
|
|
65798
|
+
return mergeFindings(raw.findings, { pool, accumulated: [] }).andThen(
|
|
65799
|
+
(findings) => mergeDismissed(raw.dismissed, { pool, accumulated: [] }).map((dismissed) => ({
|
|
65800
|
+
findings,
|
|
65801
|
+
dismissed
|
|
65802
|
+
}))
|
|
65720
65803
|
);
|
|
65721
65804
|
}
|
|
65722
65805
|
function buildDismissalSection(dismissals) {
|
|
@@ -65736,14 +65819,14 @@ function buildRulesSection() {
|
|
|
65736
65819
|
return `## Rules
|
|
65737
65820
|
|
|
65738
65821
|
1. Merge findings that share the same \`flow\` AND describe the same failure (overlapping \`steps\` or matching \`description\` intent). Do NOT merge findings from different flows.
|
|
65739
|
-
2. When merging:
|
|
65822
|
+
2. When merging: combine \`steps\` and \`screenshots\` from both findings into the merged output. The system computes \`confidence\` after consolidation \u2014 do not emit it.
|
|
65740
65823
|
3. Preserve unique findings unchanged.
|
|
65741
65824
|
4. When uncertain if two findings are duplicates: keep both.
|
|
65742
65825
|
5. Place a finding in \`dismissed\` only when it matches a dismissed entry on the same \`flow\` AND describes substantively the same failure (not just topically related). Copy the reason verbatim. When in doubt, keep it in \`findings\`.
|
|
65743
65826
|
6. Every input finding MUST appear in exactly one of \`findings\` or \`dismissed\` \u2014 never both, never neither.
|
|
65744
65827
|
|
|
65745
65828
|
CRITICAL: Call \`set_output\` exactly once when done. Do not reply in plain text.
|
|
65746
|
-
- \`findings\`: array of Finding objects \u2014 preserve all original fields (\`triggerType\`, \`flow\`, \`steps\`, \`
|
|
65829
|
+
- \`findings\`: array of Finding objects \u2014 preserve all original fields (\`triggerType\`, \`flow\`, \`steps\`, \`description\`, \`screenshots\`, \`agent\`)
|
|
65747
65830
|
- \`dismissed\`: array of objects with shape \`{ finding: Finding, reason: string }\` \u2014 populate \`finding\` with the full Finding object and copy \`reason\` verbatim from the dismissed context entry`;
|
|
65748
65831
|
}
|
|
65749
65832
|
function buildConsolidationPrompt({
|
|
@@ -65774,55 +65857,156 @@ function serializeDismissals(dismissals) {
|
|
|
65774
65857
|
({ finding, reason }) => `${finding.flow} \u2014 ${finding.description}${reason ? ` (reason: ${reason})` : ""}`
|
|
65775
65858
|
);
|
|
65776
65859
|
}
|
|
65777
|
-
function emitStageEnd2(
|
|
65778
|
-
|
|
65860
|
+
function emitStageEnd2(context) {
|
|
65861
|
+
context.config?.onEvent?.({
|
|
65862
|
+
type: "STAGE_END",
|
|
65863
|
+
agent: "consolidator",
|
|
65864
|
+
durationMs: Date.now() - context.start
|
|
65865
|
+
});
|
|
65779
65866
|
}
|
|
65780
|
-
function
|
|
65781
|
-
|
|
65782
|
-
return (0, import_neverthrow13.okAsync)({ findings: [], dismissed: [] });
|
|
65783
|
-
}
|
|
65784
|
-
const start = Date.now();
|
|
65785
|
-
config3?.onEvent?.({ type: "STAGE_START", agent: "consolidator" });
|
|
65786
|
-
const prompt = buildConsolidationPrompt({
|
|
65867
|
+
function buildPrompt(input) {
|
|
65868
|
+
return buildConsolidationPrompt({
|
|
65787
65869
|
metadataFindings: input.metadataFindings,
|
|
65788
65870
|
visualFindings: input.visualFindings,
|
|
65789
65871
|
dismissals: serializeDismissals(input.dismissals)
|
|
65790
65872
|
});
|
|
65791
|
-
|
|
65792
|
-
|
|
65873
|
+
}
|
|
65874
|
+
function runPipeline(input, context) {
|
|
65875
|
+
const pool = { metadataFindings: input.metadataFindings, visualFindings: input.visualFindings };
|
|
65876
|
+
return consolidateFindings(buildPrompt(input), context.config?.onEvent).andThen((raw) => attachAllConfidences(raw, pool)).map((result) => {
|
|
65877
|
+
emitStageEnd2(context);
|
|
65793
65878
|
return result;
|
|
65794
65879
|
}).mapErr((error48) => {
|
|
65795
|
-
emitStageEnd2(
|
|
65880
|
+
emitStageEnd2(context);
|
|
65796
65881
|
return error48;
|
|
65797
65882
|
});
|
|
65798
65883
|
}
|
|
65884
|
+
function runConsolidator(input, config3) {
|
|
65885
|
+
if (input.metadataFindings.length === 0 && input.visualFindings.length === 0) {
|
|
65886
|
+
return (0, import_neverthrow13.okAsync)({ findings: [], dismissed: [] });
|
|
65887
|
+
}
|
|
65888
|
+
const start = Date.now();
|
|
65889
|
+
config3?.onEvent?.({ type: "STAGE_START", agent: "consolidator" });
|
|
65890
|
+
return runPipeline(input, { config: config3, start });
|
|
65891
|
+
}
|
|
65799
65892
|
|
|
65800
65893
|
// ../../packages/pipeline/dist/index.js
|
|
65801
|
-
var import_neverthrow31 = __toESM(require_index_cjs(), 1);
|
|
65802
|
-
var import_neverthrow32 = __toESM(require_index_cjs(), 1);
|
|
65803
|
-
var import_node_fs3 = require("node:fs");
|
|
65804
65894
|
var import_neverthrow33 = __toESM(require_index_cjs(), 1);
|
|
65805
|
-
var
|
|
65895
|
+
var import_neverthrow34 = __toESM(require_index_cjs(), 1);
|
|
65896
|
+
var import_node_fs3 = require("node:fs");
|
|
65897
|
+
var import_neverthrow35 = __toESM(require_index_cjs(), 1);
|
|
65898
|
+
var import_promises17 = require("node:timers/promises");
|
|
65806
65899
|
|
|
65807
65900
|
// ../../agents/explorer/dist/index.js
|
|
65808
65901
|
var import_promises9 = require("node:timers/promises");
|
|
65809
|
-
var import_neverthrow15 = __toESM(require_index_cjs(), 1);
|
|
65810
65902
|
var import_neverthrow16 = __toESM(require_index_cjs(), 1);
|
|
65903
|
+
var import_neverthrow17 = __toESM(require_index_cjs(), 1);
|
|
65811
65904
|
var import_promises10 = require("node:fs/promises");
|
|
65812
65905
|
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
65813
|
-
var import_neverthrow17 = __toESM(require_index_cjs(), 1);
|
|
65814
|
-
var import_node_child_process3 = require("node:child_process");
|
|
65815
|
-
var import_promises11 = require("node:fs/promises");
|
|
65816
65906
|
var import_neverthrow18 = __toESM(require_index_cjs(), 1);
|
|
65817
|
-
var
|
|
65818
|
-
var import_node_child_process4 = require("node:child_process");
|
|
65819
|
-
var import_node_fs = require("node:fs");
|
|
65907
|
+
var import_promises11 = require("node:fs/promises");
|
|
65820
65908
|
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
65909
|
+
var import_neverthrow19 = __toESM(require_index_cjs(), 1);
|
|
65910
|
+
var import_node_child_process3 = require("node:child_process");
|
|
65911
|
+
var import_promises12 = require("node:fs/promises");
|
|
65821
65912
|
var import_neverthrow20 = __toESM(require_index_cjs(), 1);
|
|
65822
65913
|
var import_neverthrow21 = __toESM(require_index_cjs(), 1);
|
|
65823
|
-
var
|
|
65914
|
+
var import_node_child_process4 = require("node:child_process");
|
|
65915
|
+
var import_node_fs = require("node:fs");
|
|
65824
65916
|
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
65825
65917
|
var import_neverthrow22 = __toESM(require_index_cjs(), 1);
|
|
65918
|
+
var import_neverthrow23 = __toESM(require_index_cjs(), 1);
|
|
65919
|
+
var import_promises13 = require("node:fs/promises");
|
|
65920
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
65921
|
+
var import_neverthrow24 = __toESM(require_index_cjs(), 1);
|
|
65922
|
+
function buildFinding(input, screenshotPath) {
|
|
65923
|
+
return {
|
|
65924
|
+
...input,
|
|
65925
|
+
agent: "explorer",
|
|
65926
|
+
screenshots: [screenshotPath]
|
|
65927
|
+
};
|
|
65928
|
+
}
|
|
65929
|
+
var REPORT_FINDING_TOOL_NAME = "mcp__mobile-ios__report_finding";
|
|
65930
|
+
var REPORT_FINDING_DESCRIPTION = `Report a single finding the moment you observe it. Call this immediately when a finding condition is triggered \u2014 before taking any further actions. The current screen is captured automatically and attached to the finding. Do not pass screenshot paths. Do not batch findings for the end of the run.`;
|
|
65931
|
+
var safeWriteFile = (0, import_neverthrow18.fromAsyncThrowable)(
|
|
65932
|
+
import_promises10.writeFile,
|
|
65933
|
+
(cause) => ({ type: "WRITE_FAILED", cause })
|
|
65934
|
+
);
|
|
65935
|
+
async function persistScreenshot(params) {
|
|
65936
|
+
const filePath = import_node_path4.default.join(
|
|
65937
|
+
params.screenshotsDirectory,
|
|
65938
|
+
`finding-${String(params.findingIndex)}.png`
|
|
65939
|
+
);
|
|
65940
|
+
return safeWriteFile(filePath, Buffer.from(params.data, "base64")).match(
|
|
65941
|
+
() => filePath,
|
|
65942
|
+
() => ""
|
|
65943
|
+
);
|
|
65944
|
+
}
|
|
65945
|
+
function emitFindingEvent(params) {
|
|
65946
|
+
params.onEvent?.({
|
|
65947
|
+
type: "FINDING_REPORTED",
|
|
65948
|
+
agent: "explorer",
|
|
65949
|
+
finding: params.finding,
|
|
65950
|
+
findingIndex: params.findingIndex,
|
|
65951
|
+
screenshotPath: params.screenshotPath
|
|
65952
|
+
});
|
|
65953
|
+
}
|
|
65954
|
+
async function resolveScreenshotPath(params) {
|
|
65955
|
+
if (params.screenshotsDir === void 0) {
|
|
65956
|
+
return "";
|
|
65957
|
+
}
|
|
65958
|
+
return persistScreenshot({
|
|
65959
|
+
screenshotsDirectory: params.screenshotsDir,
|
|
65960
|
+
findingIndex: params.findingIndex,
|
|
65961
|
+
data: params.data
|
|
65962
|
+
});
|
|
65963
|
+
}
|
|
65964
|
+
async function recordFinding(params) {
|
|
65965
|
+
const screenshotPath = await resolveScreenshotPath({
|
|
65966
|
+
screenshotsDir: params.screenshotsDir,
|
|
65967
|
+
findingIndex: params.findingIndex,
|
|
65968
|
+
data: params.screenshotData
|
|
65969
|
+
});
|
|
65970
|
+
const finding = buildFinding(params.input, screenshotPath);
|
|
65971
|
+
params.findings.push(finding);
|
|
65972
|
+
emitFindingEvent({
|
|
65973
|
+
onEvent: params.onEvent,
|
|
65974
|
+
finding,
|
|
65975
|
+
findingIndex: params.findingIndex,
|
|
65976
|
+
screenshotPath
|
|
65977
|
+
});
|
|
65978
|
+
return { content: [{ type: "text", text: "ok" }] };
|
|
65979
|
+
}
|
|
65980
|
+
function screenshotErrorResult(cause) {
|
|
65981
|
+
return {
|
|
65982
|
+
content: [{ type: "text", text: `Screenshot failed: ${String(cause)}` }],
|
|
65983
|
+
isError: true
|
|
65984
|
+
};
|
|
65985
|
+
}
|
|
65986
|
+
function createHandler(context) {
|
|
65987
|
+
const counter = context.findingCounter;
|
|
65988
|
+
const { findings, onEvent, screenshotsDir, udid } = context;
|
|
65989
|
+
return async (input) => {
|
|
65990
|
+
const screenshotResult = await captureScreenshot(udid);
|
|
65991
|
+
if (screenshotResult.isErr()) {
|
|
65992
|
+
return screenshotErrorResult(screenshotResult.error.cause);
|
|
65993
|
+
}
|
|
65994
|
+
const findingIndex = counter.value;
|
|
65995
|
+
counter.value += 1;
|
|
65996
|
+
return recordFinding({
|
|
65997
|
+
findings,
|
|
65998
|
+
onEvent,
|
|
65999
|
+
screenshotsDir,
|
|
66000
|
+
input,
|
|
66001
|
+
screenshotData: screenshotResult.value,
|
|
66002
|
+
findingIndex
|
|
66003
|
+
});
|
|
66004
|
+
};
|
|
66005
|
+
}
|
|
66006
|
+
function createReportFindingTool(context) {
|
|
66007
|
+
const handler2 = createHandler(context);
|
|
66008
|
+
return _x("report_finding", REPORT_FINDING_DESCRIPTION, findingInputSchema.shape, handler2);
|
|
66009
|
+
}
|
|
65826
66010
|
var VIEW_UI_DESCRIPTION = `Capture current screen state: accessibility tree (element labels, positions, attributes) and screenshot in one call. Use when you need to tap an element, assert element presence or labels, check attributes, or track screen identity via <screen_id>.
|
|
65827
66011
|
|
|
65828
66012
|
The result begins with a <screen_id> tag containing the current screen identifier. Use this to detect screen changes and track navigation history.
|
|
@@ -65831,14 +66015,14 @@ Do not call \`screenshot\` immediately before or after this tool for the same st
|
|
|
65831
66015
|
|
|
65832
66016
|
IMPORTANT: Snapshot coordinates and screenshot pixels are in the same logical point space. Do not apply any scaling factor (no 2x retina adjustment).`;
|
|
65833
66017
|
var VIEW_UI_TOOL_NAME = "mcp__mobile-ios__view_ui";
|
|
65834
|
-
async function
|
|
66018
|
+
async function persistScreenshot2(params) {
|
|
65835
66019
|
const targetSnapshot = params.snapshot;
|
|
65836
|
-
const screenshotPath =
|
|
65837
|
-
const
|
|
65838
|
-
|
|
66020
|
+
const screenshotPath = import_node_path5.default.join(params.screenshotsDirectory, `${params.screenLabel}.png`);
|
|
66021
|
+
const safeWriteFile2 = (0, import_neverthrow19.fromAsyncThrowable)(
|
|
66022
|
+
import_promises11.writeFile,
|
|
65839
66023
|
(cause) => ({ type: "WRITE_FAILED", cause })
|
|
65840
66024
|
);
|
|
65841
|
-
const writeResult =
|
|
66025
|
+
const writeResult = safeWriteFile2(screenshotPath, Buffer.from(params.data, "base64"));
|
|
65842
66026
|
const succeeded = await writeResult.match(
|
|
65843
66027
|
() => true,
|
|
65844
66028
|
() => false
|
|
@@ -65899,16 +66083,16 @@ function buildSnapshotRecord(rawElements, { stepIndex, context }) {
|
|
|
65899
66083
|
}
|
|
65900
66084
|
async function handleScreenshotData(data, params) {
|
|
65901
66085
|
if (params.context.screenshotsDir !== void 0) {
|
|
65902
|
-
const safeWrite2 = (0,
|
|
65903
|
-
|
|
66086
|
+
const safeWrite2 = (0, import_neverthrow19.fromAsyncThrowable)(
|
|
66087
|
+
import_promises11.writeFile,
|
|
65904
66088
|
(cause) => ({ type: "WRITE_FAILED", cause })
|
|
65905
66089
|
);
|
|
65906
|
-
const snapshotPath =
|
|
66090
|
+
const snapshotPath = import_node_path5.default.join(params.context.screenshotsDir, `${params.screenLabel}.txt`);
|
|
65907
66091
|
await safeWrite2(snapshotPath, params.formatted).match(
|
|
65908
66092
|
() => true,
|
|
65909
66093
|
() => false
|
|
65910
66094
|
);
|
|
65911
|
-
await
|
|
66095
|
+
await persistScreenshot2({
|
|
65912
66096
|
snapshot: params.snapshot,
|
|
65913
66097
|
data,
|
|
65914
66098
|
screenLabel: params.screenLabel,
|
|
@@ -66002,7 +66186,7 @@ function captureThinkingOrText(blk, state) {
|
|
|
66002
66186
|
}
|
|
66003
66187
|
}
|
|
66004
66188
|
function captureToolUse(blk, state) {
|
|
66005
|
-
if (typeof blk.name === "string") {
|
|
66189
|
+
if (typeof blk.name === "string" && blk.name !== REPORT_FINDING_TOOL_NAME) {
|
|
66006
66190
|
state.onEvent?.({
|
|
66007
66191
|
type: "TOOL_CALL",
|
|
66008
66192
|
agent: "explorer",
|
|
@@ -66013,10 +66197,6 @@ function captureToolUse(blk, state) {
|
|
|
66013
66197
|
if (typeof blk.id === "string" && typeof blk.name === "string") {
|
|
66014
66198
|
state.pendingToolCallNames.set(blk.id, blk.name);
|
|
66015
66199
|
}
|
|
66016
|
-
if (typeof blk.name === "string" && blk.name.endsWith("set_output")) {
|
|
66017
|
-
state.captureInput(blk.input);
|
|
66018
|
-
state.closeQueue();
|
|
66019
|
-
}
|
|
66020
66200
|
}
|
|
66021
66201
|
function extractResultText(block) {
|
|
66022
66202
|
const typed = block;
|
|
@@ -66032,7 +66212,7 @@ function extractResultText(block) {
|
|
|
66032
66212
|
}
|
|
66033
66213
|
function emitToolResultEvent(emission) {
|
|
66034
66214
|
const { block, toolName, blk, state } = emission;
|
|
66035
|
-
if (toolName === VIEW_UI_TOOL_NAME) {
|
|
66215
|
+
if (toolName === VIEW_UI_TOOL_NAME || toolName === REPORT_FINDING_TOOL_NAME) {
|
|
66036
66216
|
return;
|
|
66037
66217
|
}
|
|
66038
66218
|
const resultText = extractResultText(block);
|
|
@@ -66084,23 +66264,23 @@ function processMessage(message, state) {
|
|
|
66084
66264
|
}
|
|
66085
66265
|
if (message.type === "result") {
|
|
66086
66266
|
if (message.subtype !== "success" && !state.timedOut.value && !state.aborted.value) {
|
|
66087
|
-
return (0,
|
|
66267
|
+
return (0, import_neverthrow17.err)(message.errors.join("; "));
|
|
66088
66268
|
}
|
|
66089
|
-
return (0,
|
|
66269
|
+
return (0, import_neverthrow17.ok)(true);
|
|
66090
66270
|
}
|
|
66091
|
-
return (0,
|
|
66271
|
+
return (0, import_neverthrow17.ok)(false);
|
|
66092
66272
|
}
|
|
66093
66273
|
async function processMessages(queryRunner, state) {
|
|
66094
66274
|
for await (const message of queryRunner) {
|
|
66095
66275
|
const result = processMessage(message, state);
|
|
66096
66276
|
if (result.isErr()) {
|
|
66097
|
-
return (0,
|
|
66277
|
+
return (0, import_neverthrow17.err)(result.error);
|
|
66098
66278
|
}
|
|
66099
66279
|
if (result.value) {
|
|
66100
66280
|
break;
|
|
66101
66281
|
}
|
|
66102
66282
|
}
|
|
66103
|
-
return (0,
|
|
66283
|
+
return (0, import_neverthrow17.ok)(null);
|
|
66104
66284
|
}
|
|
66105
66285
|
var MessageQueue = class {
|
|
66106
66286
|
pending = [];
|
|
@@ -66165,26 +66345,25 @@ function spawnDetached(options2) {
|
|
|
66165
66345
|
off: child.off.bind(child)
|
|
66166
66346
|
};
|
|
66167
66347
|
}
|
|
66168
|
-
function
|
|
66169
|
-
config: config3,
|
|
66170
|
-
|
|
66171
|
-
mobileIosServer,
|
|
66172
|
-
allowedTools
|
|
66173
|
-
}) {
|
|
66174
|
-
const base = {
|
|
66348
|
+
function buildBaseOptions(context) {
|
|
66349
|
+
const { config: config3, mobileIosServer, allowedTools } = context;
|
|
66350
|
+
return {
|
|
66175
66351
|
mcpServers: {
|
|
66176
66352
|
...config3.mcpServers,
|
|
66177
|
-
"mobile-ios": mobileIosServer
|
|
66178
|
-
output: outputTools.server
|
|
66353
|
+
"mobile-ios": mobileIosServer
|
|
66179
66354
|
},
|
|
66180
66355
|
allowedTools,
|
|
66181
66356
|
tools: [],
|
|
66182
66357
|
permissionMode: "bypassPermissions",
|
|
66183
66358
|
allowDangerouslySkipPermissions: true,
|
|
66184
66359
|
spawnClaudeCodeProcess: spawnDetached,
|
|
66360
|
+
thinking: { type: "adaptive" },
|
|
66185
66361
|
...config3.cwd ? { cwd: config3.cwd } : {}
|
|
66186
66362
|
};
|
|
66187
|
-
|
|
66363
|
+
}
|
|
66364
|
+
function buildQueryOptions(context) {
|
|
66365
|
+
const base = buildBaseOptions(context);
|
|
66366
|
+
if (!context.config.signal) {
|
|
66188
66367
|
return { options: base, linkedController: void 0 };
|
|
66189
66368
|
}
|
|
66190
66369
|
const linkedController = new AbortController();
|
|
@@ -66203,14 +66382,14 @@ function buildSendMessageFunction(inputQueue) {
|
|
|
66203
66382
|
}
|
|
66204
66383
|
function buildAgentState({
|
|
66205
66384
|
config: config3,
|
|
66206
|
-
outputTools,
|
|
66207
66385
|
inputQueue
|
|
66208
66386
|
}) {
|
|
66209
66387
|
return {
|
|
66210
66388
|
pendingToolCallNames: /* @__PURE__ */ new Map(),
|
|
66211
66389
|
snapshots: [],
|
|
66212
66390
|
stepCounter: { value: 0 },
|
|
66213
|
-
|
|
66391
|
+
findings: [],
|
|
66392
|
+
findingCounter: { value: 0 },
|
|
66214
66393
|
sendMessage: buildSendMessageFunction(inputQueue),
|
|
66215
66394
|
closeQueue: () => {
|
|
66216
66395
|
inputQueue.close();
|
|
@@ -66228,28 +66407,34 @@ function buildMobileIosServer(config3, state) {
|
|
|
66228
66407
|
onEvent: config3.onEvent,
|
|
66229
66408
|
screenshotsDir: config3.screenshotsDir
|
|
66230
66409
|
});
|
|
66231
|
-
|
|
66410
|
+
const reportFindingTool = createReportFindingTool({
|
|
66411
|
+
udid: config3.udid,
|
|
66412
|
+
findings: state.findings,
|
|
66413
|
+
findingCounter: state.findingCounter,
|
|
66414
|
+
onEvent: config3.onEvent,
|
|
66415
|
+
screenshotsDir: config3.screenshotsDir
|
|
66416
|
+
});
|
|
66417
|
+
return createMobileIosServer(config3.udid ?? "booted", [viewUiTool, reportFindingTool]);
|
|
66232
66418
|
}
|
|
66233
|
-
function setupQuery(config3
|
|
66419
|
+
function setupQuery(config3) {
|
|
66234
66420
|
const allowedTools = [
|
|
66235
66421
|
...config3.allowedTools ?? [],
|
|
66236
|
-
...outputTools.allowedToolNames,
|
|
66237
66422
|
VIEW_UI_TOOL_NAME,
|
|
66423
|
+
REPORT_FINDING_TOOL_NAME,
|
|
66238
66424
|
WAIT_SECONDS_TOOL_NAME
|
|
66239
|
-
].filter((
|
|
66425
|
+
].filter((tool3) => typeof tool3 === "string");
|
|
66240
66426
|
const inputQueue = new MessageQueue();
|
|
66241
|
-
const state = buildAgentState({ config: config3,
|
|
66427
|
+
const state = buildAgentState({ config: config3, inputQueue });
|
|
66242
66428
|
const mobileIosServer = buildMobileIosServer(config3, state);
|
|
66243
66429
|
const { options: options2, linkedController } = buildQueryOptions({
|
|
66244
66430
|
config: config3,
|
|
66245
|
-
outputTools,
|
|
66246
66431
|
mobileIosServer,
|
|
66247
66432
|
allowedTools
|
|
66248
66433
|
});
|
|
66249
66434
|
return { inputQueue, state, options: options2, linkedController };
|
|
66250
66435
|
}
|
|
66251
|
-
var DEFAULT_GRACE_PERIOD_MS =
|
|
66252
|
-
var SOFT_DEADLINE_MESSAGE = "Your time limit has been reached.
|
|
66436
|
+
var DEFAULT_GRACE_PERIOD_MS = 1e4;
|
|
66437
|
+
var SOFT_DEADLINE_MESSAGE = "Your time limit has been reached. Do not take any further actions.";
|
|
66253
66438
|
function buildInterruptErrorEvent(agent, error48) {
|
|
66254
66439
|
const message = `interrupt failed: ${error48 instanceof Error ? error48.message : String(error48)}`;
|
|
66255
66440
|
const stack = error48 instanceof Error ? error48.stack : void 0;
|
|
@@ -66308,18 +66493,14 @@ function startTimeout(timeoutMs, context) {
|
|
|
66308
66493
|
const gracePeriodMs = context.gracePeriodMs ?? DEFAULT_GRACE_PERIOD_MS;
|
|
66309
66494
|
return startActiveTimeout({ timeoutMs, gracePeriodMs, context });
|
|
66310
66495
|
}
|
|
66311
|
-
var EXPLORER_FINDING_SCHEMA = findingSchema.omit({ agent: true });
|
|
66312
66496
|
var INTERRUPT_DRAIN_TIMEOUT_MS = 1e4;
|
|
66313
66497
|
async function interruptOrTimeout(queryRunner) {
|
|
66314
66498
|
await Promise.race([queryRunner.interrupt(), (0, import_promises9.setTimeout)(INTERRUPT_DRAIN_TIMEOUT_MS)]);
|
|
66315
66499
|
}
|
|
66316
|
-
var safeInterruptOrTimeout =
|
|
66500
|
+
var safeInterruptOrTimeout = import_neverthrow16.ResultAsync.fromThrowable(
|
|
66317
66501
|
interruptOrTimeout,
|
|
66318
66502
|
(error48) => error48
|
|
66319
66503
|
);
|
|
66320
|
-
function stampExplorerAgent(raw) {
|
|
66321
|
-
return { ...raw, agent: "explorer" };
|
|
66322
|
-
}
|
|
66323
66504
|
async function drainInterruptThenAbort(context) {
|
|
66324
66505
|
const { queryRunner, state, linkedController, reason } = context;
|
|
66325
66506
|
const result = await safeInterruptOrTimeout(queryRunner);
|
|
@@ -66365,24 +66546,23 @@ function startQueryTimers(config3, context) {
|
|
|
66365
66546
|
}
|
|
66366
66547
|
function awaitMessagesAndResolve({ queryRunner, state }, { cleanup: cleanup2, getOutput }) {
|
|
66367
66548
|
const messagesPromise = processMessages(queryRunner, state);
|
|
66368
|
-
return
|
|
66549
|
+
return import_neverthrow16.ResultAsync.fromPromise(messagesPromise, String).andThen((innerResult) => {
|
|
66369
66550
|
cleanup2();
|
|
66370
66551
|
if (innerResult.isErr()) {
|
|
66371
|
-
return (0,
|
|
66552
|
+
return (0, import_neverthrow16.err)(innerResult.error);
|
|
66372
66553
|
}
|
|
66373
|
-
return (0,
|
|
66554
|
+
return (0, import_neverthrow16.ok)(getOutput());
|
|
66374
66555
|
}).orElse((sdkError) => {
|
|
66375
66556
|
cleanup2();
|
|
66376
66557
|
if (!state.timedOut.value && !state.aborted.value) {
|
|
66377
|
-
return (0,
|
|
66558
|
+
return (0, import_neverthrow16.err)(sdkError);
|
|
66378
66559
|
}
|
|
66379
|
-
return (0,
|
|
66560
|
+
return (0, import_neverthrow16.ok)(getOutput());
|
|
66380
66561
|
});
|
|
66381
66562
|
}
|
|
66382
66563
|
function executeQuery({
|
|
66383
66564
|
prompt,
|
|
66384
66565
|
config: config3,
|
|
66385
|
-
outputTools,
|
|
66386
66566
|
setup: { inputQueue, state, options: options2, linkedController }
|
|
66387
66567
|
}) {
|
|
66388
66568
|
inputQueue.enqueue({
|
|
@@ -66390,35 +66570,32 @@ function executeQuery({
|
|
|
66390
66570
|
message: { role: "user", content: prompt },
|
|
66391
66571
|
parent_tool_use_id: null
|
|
66392
66572
|
});
|
|
66393
|
-
const queryRunnerResult = (0,
|
|
66573
|
+
const queryRunnerResult = (0, import_neverthrow16.fromThrowable)(Qs, String)({ prompt: inputQueue, options: options2 });
|
|
66394
66574
|
if (queryRunnerResult.isErr()) {
|
|
66395
|
-
return (0,
|
|
66575
|
+
return (0, import_neverthrow16.errAsync)(queryRunnerResult.error);
|
|
66396
66576
|
}
|
|
66397
66577
|
const queryRunner = queryRunnerResult.value;
|
|
66398
66578
|
const cleanup2 = startQueryTimers(config3, { state, queryRunner, inputQueue, linkedController });
|
|
66399
66579
|
const getOutput = () => ({
|
|
66400
|
-
findings:
|
|
66401
|
-
(raw) => stampExplorerAgent(raw)
|
|
66402
|
-
),
|
|
66580
|
+
findings: state.findings,
|
|
66403
66581
|
snapshots: state.snapshots
|
|
66404
66582
|
});
|
|
66405
66583
|
return awaitMessagesAndResolve({ queryRunner, state }, { cleanup: cleanup2, getOutput });
|
|
66406
66584
|
}
|
|
66407
66585
|
function runQuery(prompt, config3) {
|
|
66408
|
-
const
|
|
66409
|
-
|
|
66410
|
-
return executeQuery({ prompt, config: config3, outputTools, setup });
|
|
66586
|
+
const setup = setupQuery(config3);
|
|
66587
|
+
return executeQuery({ prompt, config: config3, setup });
|
|
66411
66588
|
}
|
|
66412
66589
|
function collectAgentOutput(prompt, config3) {
|
|
66413
66590
|
return runQuery(prompt, config3).mapErr((cause) => ({ type: "QUERY_FAILED", cause }));
|
|
66414
66591
|
}
|
|
66415
66592
|
function spawnRecorder(outputPath) {
|
|
66416
|
-
const safeMkdirSync = (0,
|
|
66417
|
-
const safeSpawn2 = (0,
|
|
66593
|
+
const safeMkdirSync = (0, import_neverthrow22.fromThrowable)(import_node_fs.mkdirSync, (cause) => cause);
|
|
66594
|
+
const safeSpawn2 = (0, import_neverthrow22.fromThrowable)(
|
|
66418
66595
|
(command, arguments_) => (0, import_node_child_process4.spawn)(command, arguments_),
|
|
66419
66596
|
(cause) => cause
|
|
66420
66597
|
);
|
|
66421
|
-
const mkdirResult = safeMkdirSync(
|
|
66598
|
+
const mkdirResult = safeMkdirSync(import_node_path6.default.dirname(outputPath), { recursive: true });
|
|
66422
66599
|
if (mkdirResult.isErr()) {
|
|
66423
66600
|
return mkdirResult.error;
|
|
66424
66601
|
}
|
|
@@ -66441,7 +66618,7 @@ function earlyExitError(code) {
|
|
|
66441
66618
|
function waitForRecordingStart(proc) {
|
|
66442
66619
|
const { stderr } = proc;
|
|
66443
66620
|
if (!stderr) {
|
|
66444
|
-
return (0,
|
|
66621
|
+
return (0, import_neverthrow22.errAsync)({ type: "SPAWN_FAILED", cause: new RangeError("proc has no stderr pipe") });
|
|
66445
66622
|
}
|
|
66446
66623
|
const { promise: promise2, resolve, reject } = Promise.withResolvers();
|
|
66447
66624
|
proc.once("error", reject);
|
|
@@ -66457,7 +66634,7 @@ function waitForRecordingStart(proc) {
|
|
|
66457
66634
|
resolve({ process: proc, startedAt: Date.now() });
|
|
66458
66635
|
}
|
|
66459
66636
|
});
|
|
66460
|
-
return
|
|
66637
|
+
return import_neverthrow22.ResultAsync.fromPromise(
|
|
66461
66638
|
promise2,
|
|
66462
66639
|
(cause) => ({ type: "SPAWN_FAILED", cause })
|
|
66463
66640
|
);
|
|
@@ -66465,7 +66642,7 @@ function waitForRecordingStart(proc) {
|
|
|
66465
66642
|
function startRecording(outputPath) {
|
|
66466
66643
|
const procOrError = spawnRecorder(outputPath);
|
|
66467
66644
|
if (procOrError instanceof Error) {
|
|
66468
|
-
return (0,
|
|
66645
|
+
return (0, import_neverthrow22.errAsync)({ type: "SPAWN_FAILED", cause: procOrError });
|
|
66469
66646
|
}
|
|
66470
66647
|
return waitForRecordingStart(procOrError);
|
|
66471
66648
|
}
|
|
@@ -66480,7 +66657,7 @@ function stopRecording(handle) {
|
|
|
66480
66657
|
} else {
|
|
66481
66658
|
resolve(true);
|
|
66482
66659
|
}
|
|
66483
|
-
return
|
|
66660
|
+
return import_neverthrow22.ResultAsync.fromPromise(
|
|
66484
66661
|
promise2,
|
|
66485
66662
|
(cause) => ({ type: "STOP_FAILED", cause })
|
|
66486
66663
|
);
|
|
@@ -66493,7 +66670,7 @@ function runWithRecording(handle, collectOutput) {
|
|
|
66493
66670
|
return collectOutput().andThen(
|
|
66494
66671
|
({ findings, snapshots }) => stopRecording(handle).mapErr(toRecordingError).map(() => ({ findings, snapshots }))
|
|
66495
66672
|
).orElse(
|
|
66496
|
-
(error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0,
|
|
66673
|
+
(error48) => stopRecording(handle).mapErr(toRecordingError).andThen(() => (0, import_neverthrow21.errAsync)(error48)).orElse(() => (0, import_neverthrow21.errAsync)(error48))
|
|
66497
66674
|
);
|
|
66498
66675
|
}
|
|
66499
66676
|
function startAndRun(params) {
|
|
@@ -66540,9 +66717,21 @@ var LOADING_STATE_RULE = `Transient loading state: when the screen shows spinner
|
|
|
66540
66717
|
var EXPECTED_CONTENT_MISSING_RULE = `Expected content missing: when \`view_ui\` shows no loading indicator yet omits an element named or strongly implied by spec or app context \u2014 and its absence is not semantically consistent with the current screen \u2014 call \`wait_seconds\` with 2\u20135 seconds and retry \`view_ui\` up to 2 times; if element remains absent, emit a \`missing-content\` finding stating what was expected and what was observed`;
|
|
66541
66718
|
var CLIPPED_ELEMENT_RULE = `Never tap an element tagged \`[clipped-top]\`, \`[clipped-bottom]\`, \`[clipped-left]\`, or \`[clipped-right]\` \u2014 scroll to fully reveal it first, then re-call \`view_ui\` before tapping`;
|
|
66542
66719
|
var SCROLL_FOLD_RULE = `Scrollable lists: elements outside the visible viewport are absent from the a11y tree by design \u2014 this applies to elements below the fold in vertical lists AND elements clipped off-left or off-right in horizontal lists \u2014 scroll or swipe in the appropriate axis to reveal before asserting presence or absence; never emit a finding solely because list items, rows, or tabs are missing from the tree on a scrollable screen; if swipe attempts yield no position change across 2+ cycles, apply the scroll-stall path in STUCK_LOOP_RULE.`;
|
|
66720
|
+
var CONFIDENCE_RUBRIC_SECTION = `## Confidence
|
|
66721
|
+
|
|
66722
|
+
Write the description (what you saw vs. expected, where, when) before committing to a confidence label.
|
|
66723
|
+
|
|
66724
|
+
- HIGH \u2014 definite bug or deviation; the evidence is unambiguous
|
|
66725
|
+
- MEDIUM \u2014 probable bug, but could be intentional behavior you cannot verify
|
|
66726
|
+
- LOW \u2014 speculative; only include when freestyle/low-confidence triggers require it`;
|
|
66543
66727
|
var FINDING_TAXONOMY_SECTION = `## Finding Types
|
|
66544
66728
|
|
|
66545
|
-
You may emit only these trigger types: \`back-nav-failure\`, \`dead-end\`, \`stuck-modal\`, \`stuck-loop\`, \`missing-a11y-element\`, \`missing-content\`, \`spec-deviation\`, \`destructive-only-exit\`. Do NOT emit \`design-system-violation\`, \`motion-regression\`, \`continuity-regression\`, \`interaction-regression\`, or \`loading-regression\` \u2014 those belong to other agents
|
|
66729
|
+
You may emit only these trigger types: \`back-nav-failure\`, \`dead-end\`, \`stuck-modal\`, \`stuck-loop\`, \`missing-a11y-element\`, \`missing-content\`, \`spec-deviation\`, \`destructive-only-exit\`. Do NOT emit \`design-system-violation\`, \`motion-regression\`, \`continuity-regression\`, \`interaction-regression\`, or \`loading-regression\` \u2014 those belong to other agents.
|
|
66730
|
+
|
|
66731
|
+
${CONFIDENCE_RUBRIC_SECTION}`;
|
|
66732
|
+
var REPORTING_FINDINGS_SECTION = `## Reporting Findings
|
|
66733
|
+
|
|
66734
|
+
CRITICAL: When you observe a finding, call \`report_finding\` IMMEDIATELY \u2014 before taking any further actions. Do not batch findings. Do not wait until the end of the run. Each \`report_finding\` call atomically records one finding with the current screen attached; the server captures the screenshot. Do not pass screenshot paths or step indices. If you are uncertain whether something warrants a finding, do not report it \u2014 \`report_finding\` is for confirmed observations only.`;
|
|
66546
66735
|
var A11Y_FALLBACK_RULE = `Missing a11y element: if you intend to tap or interact with a UI element and that element is absent from the most recent \`view_ui\` a11y tree \u2014 visible in the screenshot does NOT imply interactable; the a11y tree is authoritative \u2014 do NOT estimate its coordinates from the screenshot, do NOT attempt any pixel-based tap, do NOT retry at different coordinates, do NOT long-press or swipe in the element's visual region as a fallback; a failed pixel tap is never an \`interaction-regression\` \u2014 it is a \`missing-a11y-element\` \u2014 instead, emit a \`missing-a11y-element\` finding that states: (1) your intent (what you were trying to do), (2) the approximate visual region where the element appeared (coords/size from the screenshot), (3) nearby labeled elements from the a11y tree that serve as landmarks \u2014 then continue: in freestyle mode keep exploring other reachable screens; in spec mode advance to the next step`;
|
|
66547
66736
|
var OUTCOME_LITERAL_RULE = `When verifying a step outcome or assertion, interpret all quantifiers literally and apply them exhaustively: any keyword that imposes a universal or count-bound constraint \u2014 including but not limited to \`only\`, \`all\`, \`every\`, \`each\`, \`both\`, \`no\`, \`none\`, \`neither\`, \`exactly N\`, \`at least N\`, \`fewer than N\`, \`more than N\` \u2014 a single counter-example observed in \`view_ui\` or \`screenshot\` constitutes a failed constraint; this rule applies only when the outcome text contains a universal or count-bound quantifier; positive-existence outcomes (\`X appears\`, \`Y becomes active\`, \`screen is visible\`) are not subject to counter-example scanning and are governed by SPEC_STEP_READING_SECTION; on a scrollable list, scroll through the full list before concluding pass or fail on a universal quantifier \u2014 apply SCROLL_FOLD_RULE to reveal all items, then evaluate across the complete visible set; if the screen shows any loading indicator at the time of observation, apply LOADING_STATE_RULE first and re-verify after resolution before emitting; do NOT soften (\`mostly\`, \`essentially\`, \`largely\`) and do NOT narrow the target class post-hoc to exclude the counter-example; when the counter-evidence is an element absent from the a11y tree, A11Y_FALLBACK_RULE takes precedence and determines the finding type (\`missing-a11y-element\`) \u2014 OUTCOME_LITERAL_RULE governs unwanted-presence violations only; if one item violates the constraint, emit \`spec-deviation\` immediately with: (a) the literal outcome text, (b) the specific element(s) that violate it, (c) the constraint keyword that is broken.`;
|
|
66548
66737
|
var ANTI_RATIONALIZATION_RULE = `During outcome verification, monitor your own reasoning for reconciliation hypotheses: if you generate any reasoning that re-frames, redefines, or reinterprets the observed counter-example or target class in order to produce agreement with the spec outcome \u2014 regardless of phrasing \u2014 treat that reasoning as a deviation signal, not a resolution; stop, do NOT mark the step complete, and emit \`spec-deviation\` with: (a) the literal outcome text, (b) the specific observation that triggered the hypothesis, (c) the reconciliation reasoning itself verbatim; before marking any quantifier-bearing outcome complete, state explicitly in your reasoning: \`No reconciliation hypothesis generated. Counter-examples found: [list or none].\` If you cannot make that statement honestly, a hypothesis exists \u2014 emit \`spec-deviation\`; when outcome verification is ambiguous and no reconciliation hypothesis is generated, still default to emitting \`spec-deviation\`; silence is not a pass.`;
|
|
@@ -66677,9 +66866,7 @@ ${FINDING_TAXONOMY_SECTION}
|
|
|
66677
66866
|
|
|
66678
66867
|
${specContent}${environmentSection}
|
|
66679
66868
|
|
|
66680
|
-
|
|
66681
|
-
|
|
66682
|
-
CRITICAL: Call \`set_output\` each time your findings change \u2014 when you discover something new, confirm a false positive, or revise a finding. Each call replaces the previous output entirely, so always pass the full current list. Do not reply in plain text.`;
|
|
66869
|
+
${REPORTING_FINDINGS_SECTION}`;
|
|
66683
66870
|
}
|
|
66684
66871
|
var SPEC_MODE_TEMPLATE = (specContent, options2) => {
|
|
66685
66872
|
const contextBlock = buildContextSections(options2.appContext, options2.initialState);
|
|
@@ -66723,9 +66910,7 @@ ${DEAD_END_SECTION}
|
|
|
66723
66910
|
|
|
66724
66911
|
${FINDING_TAXONOMY_SECTION}${environmentSection}
|
|
66725
66912
|
|
|
66726
|
-
|
|
66727
|
-
|
|
66728
|
-
CRITICAL: Call \`set_output\` each time your findings change \u2014 when you discover something new, confirm a false positive, or revise a finding. Each call replaces the previous output entirely, so always pass the full current list. Do not reply in plain text.`;
|
|
66913
|
+
${REPORTING_FINDINGS_SECTION}`;
|
|
66729
66914
|
}
|
|
66730
66915
|
var FREESTYLE_TEMPLATE = (options2) => {
|
|
66731
66916
|
const { appContext, initialState: initialState2, buildEnv } = options2 ?? {};
|
|
@@ -66776,29 +66961,29 @@ var INLINE_ASSERTION_DELIMITER = " \u2192 ";
|
|
|
66776
66961
|
var NUMBERED_STEP_PREFIX = /^\d+\.\s+/;
|
|
66777
66962
|
function parseTagsValue(value) {
|
|
66778
66963
|
if (!value.startsWith("[") || !value.endsWith("]")) {
|
|
66779
|
-
return (0,
|
|
66964
|
+
return (0, import_neverthrow23.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid tags format: ${value}` });
|
|
66780
66965
|
}
|
|
66781
|
-
return (0,
|
|
66966
|
+
return (0, import_neverthrow23.ok)(
|
|
66782
66967
|
value.slice(1, -1).split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0)
|
|
66783
66968
|
);
|
|
66784
66969
|
}
|
|
66785
66970
|
function parseTimeoutValue(value) {
|
|
66786
66971
|
const parsed = Number(value);
|
|
66787
66972
|
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
66788
|
-
return (0,
|
|
66973
|
+
return (0, import_neverthrow23.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid timeout: ${value}` });
|
|
66789
66974
|
}
|
|
66790
|
-
return (0,
|
|
66975
|
+
return (0, import_neverthrow23.ok)(parsed);
|
|
66791
66976
|
}
|
|
66792
66977
|
function parseFrontmatterLine(line) {
|
|
66793
66978
|
const colonIndex = line.indexOf(":");
|
|
66794
66979
|
if (colonIndex === -1) {
|
|
66795
|
-
return (0,
|
|
66980
|
+
return (0, import_neverthrow23.err)({ type: "MALFORMED_FRONTMATTER", cause: `Invalid line: ${line}` });
|
|
66796
66981
|
}
|
|
66797
66982
|
const key = line.slice(0, colonIndex).trim();
|
|
66798
66983
|
const value = line.slice(colonIndex + 1).trim();
|
|
66799
66984
|
switch (key) {
|
|
66800
66985
|
case "description": {
|
|
66801
|
-
return (0,
|
|
66986
|
+
return (0, import_neverthrow23.ok)({ description: value });
|
|
66802
66987
|
}
|
|
66803
66988
|
case "tags": {
|
|
66804
66989
|
return parseTagsValue(value).map((tags) => ({ tags }));
|
|
@@ -66807,7 +66992,7 @@ function parseFrontmatterLine(line) {
|
|
|
66807
66992
|
return parseTimeoutValue(value).map((timeout) => ({ timeout }));
|
|
66808
66993
|
}
|
|
66809
66994
|
default: {
|
|
66810
|
-
return (0,
|
|
66995
|
+
return (0, import_neverthrow23.ok)({});
|
|
66811
66996
|
}
|
|
66812
66997
|
}
|
|
66813
66998
|
}
|
|
@@ -66826,18 +67011,18 @@ function mergePartials(partials) {
|
|
|
66826
67011
|
}
|
|
66827
67012
|
function combineFrontmatterLines(lines) {
|
|
66828
67013
|
const lineResults = lines.filter((line) => line.trim().length > 0).map((line) => parseFrontmatterLine(line));
|
|
66829
|
-
return
|
|
67014
|
+
return import_neverthrow23.Result.combine(lineResults).map((partials) => mergePartials(partials)).map((merged) => normalizeFrontmatter(merged));
|
|
66830
67015
|
}
|
|
66831
67016
|
function extractFrontmatter(content) {
|
|
66832
67017
|
const trimmed = content.trimStart();
|
|
66833
67018
|
if (!trimmed.startsWith(FRONTMATTER_FENCE)) {
|
|
66834
|
-
return (0,
|
|
67019
|
+
return (0, import_neverthrow23.ok)({ frontmatter: emptyFrontmatter(), body: content });
|
|
66835
67020
|
}
|
|
66836
67021
|
const afterOpenFence = trimmed.slice(FRONTMATTER_FENCE.length);
|
|
66837
67022
|
const closeIndex = afterOpenFence.indexOf(`
|
|
66838
67023
|
${FRONTMATTER_FENCE}`);
|
|
66839
67024
|
if (closeIndex === -1) {
|
|
66840
|
-
return (0,
|
|
67025
|
+
return (0, import_neverthrow23.err)({ type: "MALFORMED_FRONTMATTER", cause: "Unclosed frontmatter fence" });
|
|
66841
67026
|
}
|
|
66842
67027
|
const rawFrontmatter = afterOpenFence.slice(0, closeIndex);
|
|
66843
67028
|
const body = afterOpenFence.slice(closeIndex + FRONTMATTER_FENCE.length + 1);
|
|
@@ -66879,13 +67064,13 @@ function parseTestSpec(name, content) {
|
|
|
66879
67064
|
const sections = splitIntoSections(body);
|
|
66880
67065
|
const setup = sections.Setup;
|
|
66881
67066
|
if (setup === void 0) {
|
|
66882
|
-
return (0,
|
|
67067
|
+
return (0, import_neverthrow23.err)({ type: "MISSING_SETUP_SECTION" });
|
|
66883
67068
|
}
|
|
66884
67069
|
const stepsSection = sections.Steps;
|
|
66885
67070
|
if (stepsSection === void 0) {
|
|
66886
|
-
return (0,
|
|
67071
|
+
return (0, import_neverthrow23.err)({ type: "MISSING_STEPS_SECTION" });
|
|
66887
67072
|
}
|
|
66888
|
-
return (0,
|
|
67073
|
+
return (0, import_neverthrow23.ok)({
|
|
66889
67074
|
name,
|
|
66890
67075
|
frontmatter,
|
|
66891
67076
|
setup,
|
|
@@ -66912,8 +67097,8 @@ function direntToSpecEntry(directory, entry) {
|
|
|
66912
67097
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
66913
67098
|
return [
|
|
66914
67099
|
{
|
|
66915
|
-
path:
|
|
66916
|
-
name:
|
|
67100
|
+
path: import_node_path7.default.join(directory, entry.name),
|
|
67101
|
+
name: import_node_path7.default.basename(entry.name, import_node_path7.default.extname(entry.name)),
|
|
66917
67102
|
required: true
|
|
66918
67103
|
}
|
|
66919
67104
|
];
|
|
@@ -66921,7 +67106,7 @@ function direntToSpecEntry(directory, entry) {
|
|
|
66921
67106
|
if (entry.isDirectory()) {
|
|
66922
67107
|
return [
|
|
66923
67108
|
{
|
|
66924
|
-
path:
|
|
67109
|
+
path: import_node_path7.default.join(directory, entry.name, "spec.md"),
|
|
66925
67110
|
name: entry.name,
|
|
66926
67111
|
required: false
|
|
66927
67112
|
}
|
|
@@ -66930,25 +67115,25 @@ function direntToSpecEntry(directory, entry) {
|
|
|
66930
67115
|
return [];
|
|
66931
67116
|
}
|
|
66932
67117
|
function scanDirectory(directory) {
|
|
66933
|
-
const safeReaddir3 = (0,
|
|
66934
|
-
async () => (0,
|
|
67118
|
+
const safeReaddir3 = (0, import_neverthrow24.fromAsyncThrowable)(
|
|
67119
|
+
async () => (0, import_promises13.readdir)(directory, { withFileTypes: true }),
|
|
66935
67120
|
(cause) => ({ type: "DIR_READ_FAILED", dir: directory, cause })
|
|
66936
67121
|
);
|
|
66937
|
-
return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0,
|
|
67122
|
+
return safeReaddir3().orElse((error48) => isNotFound(error48.cause) ? (0, import_neverthrow24.okAsync)([]) : (0, import_neverthrow24.errAsync)(error48)).map(
|
|
66938
67123
|
(entries) => entries.flatMap((entry) => direntToSpecEntry(directory, entry))
|
|
66939
67124
|
);
|
|
66940
67125
|
}
|
|
66941
67126
|
function readEntries(entries) {
|
|
66942
|
-
return
|
|
67127
|
+
return import_neverthrow24.ResultAsync.combine(entries.map((entry) => readEntry(entry))).map(
|
|
66943
67128
|
(results) => results.flat()
|
|
66944
67129
|
);
|
|
66945
67130
|
}
|
|
66946
67131
|
function readEntry(entry) {
|
|
66947
|
-
const safeReadFile6 = (0,
|
|
66948
|
-
async () => (0,
|
|
67132
|
+
const safeReadFile6 = (0, import_neverthrow24.fromAsyncThrowable)(
|
|
67133
|
+
async () => (0, import_promises13.readFile)(entry.path, "utf8"),
|
|
66949
67134
|
(cause) => ({ type: "FILE_READ_FAILED", path: entry.path, cause })
|
|
66950
67135
|
);
|
|
66951
|
-
return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0,
|
|
67136
|
+
return safeReadFile6().map((content) => [{ name: entry.name, content }]).orElse((error48) => entry.required ? (0, import_neverthrow24.errAsync)(error48) : (0, import_neverthrow24.okAsync)([]));
|
|
66952
67137
|
}
|
|
66953
67138
|
function specNameFromPath(filePath) {
|
|
66954
67139
|
const parts = filePath.split("/");
|
|
@@ -66956,7 +67141,7 @@ function specNameFromPath(filePath) {
|
|
|
66956
67141
|
if (fileName === "spec.md" && parts.length >= 2) {
|
|
66957
67142
|
return parts.at(-2) ?? fileName;
|
|
66958
67143
|
}
|
|
66959
|
-
return
|
|
67144
|
+
return import_node_path7.default.basename(fileName, import_node_path7.default.extname(fileName));
|
|
66960
67145
|
}
|
|
66961
67146
|
function filterByNames(specs, specNames) {
|
|
66962
67147
|
if (!specNames || specNames.length === 0) {
|
|
@@ -66965,11 +67150,11 @@ function filterByNames(specs, specNames) {
|
|
|
66965
67150
|
return specs.filter((spec) => specNames.includes(spec.name));
|
|
66966
67151
|
}
|
|
66967
67152
|
function resolveSpecs(config3, repoRoot = process.cwd()) {
|
|
66968
|
-
const source = config3.specFiles && config3.specFiles.length > 0 ? loadFromFiles(config3.specFiles) : loadFromDirectory(
|
|
67153
|
+
const source = config3.specFiles && config3.specFiles.length > 0 ? loadFromFiles(config3.specFiles) : loadFromDirectory(import_node_path7.default.join(repoRoot, "openspec", "specs"));
|
|
66969
67154
|
return source.map((specs) => filterByNames(specs, config3.specNames));
|
|
66970
67155
|
}
|
|
66971
67156
|
var ISO_DATE_LENGTH = 10;
|
|
66972
|
-
function
|
|
67157
|
+
function buildPrompt2(safeConfig, specs) {
|
|
66973
67158
|
return generateExplorerPrompt({
|
|
66974
67159
|
mode: safeConfig.mode,
|
|
66975
67160
|
specs,
|
|
@@ -66979,7 +67164,7 @@ function buildPrompt(safeConfig, specs) {
|
|
|
66979
67164
|
});
|
|
66980
67165
|
}
|
|
66981
67166
|
function parseSpecs(resolvedSpecs) {
|
|
66982
|
-
return
|
|
67167
|
+
return import_neverthrow20.Result.combine(
|
|
66983
67168
|
resolvedSpecs.map(
|
|
66984
67169
|
(spec) => parseTestSpec(spec.name, spec.content).mapErr(
|
|
66985
67170
|
(cause) => ({ type: "SPEC_PARSE_FAILED", specName: spec.name, cause })
|
|
@@ -67034,16 +67219,16 @@ function collectAndFinalize({
|
|
|
67034
67219
|
}
|
|
67035
67220
|
function resolveAndParseSpecs(safeConfig) {
|
|
67036
67221
|
if (safeConfig.mode === "freestyle") {
|
|
67037
|
-
return (0,
|
|
67222
|
+
return (0, import_neverthrow20.okAsync)([]);
|
|
67038
67223
|
}
|
|
67039
67224
|
return resolveSpecs(safeConfig).mapErr((cause) => ({ type: "SPEC_RESOLVE_FAILED", cause })).andThen((specs) => parseSpecs(specs));
|
|
67040
67225
|
}
|
|
67041
|
-
function
|
|
67226
|
+
function runPipeline2({
|
|
67042
67227
|
safeConfig,
|
|
67043
67228
|
runPaths,
|
|
67044
67229
|
start
|
|
67045
67230
|
}) {
|
|
67046
|
-
return resolveAndParseSpecs(safeConfig).map((parsedSpecs) =>
|
|
67231
|
+
return resolveAndParseSpecs(safeConfig).map((parsedSpecs) => buildPrompt2(safeConfig, parsedSpecs)).map((prompt) => {
|
|
67047
67232
|
safeConfig.onEvent?.({ type: "SYSTEM_PROMPT", agent: "explorer", prompt });
|
|
67048
67233
|
return prompt;
|
|
67049
67234
|
}).andThen((prompt) => collectAndFinalize({ safeConfig, prompt, runPaths, start }));
|
|
@@ -67057,11 +67242,11 @@ function runExplorer(config3) {
|
|
|
67057
67242
|
date: date5
|
|
67058
67243
|
});
|
|
67059
67244
|
if (runPathsResult.isErr()) {
|
|
67060
|
-
return (0,
|
|
67245
|
+
return (0, import_neverthrow20.errAsync)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
|
|
67061
67246
|
}
|
|
67062
67247
|
const runPaths = runPathsResult.value;
|
|
67063
67248
|
if (config3.signal?.aborted) {
|
|
67064
|
-
return (0,
|
|
67249
|
+
return (0, import_neverthrow20.okAsync)(toArtifacts({ findings: [], snapshots: [] }, runPaths));
|
|
67065
67250
|
}
|
|
67066
67251
|
const safeConfig = {
|
|
67067
67252
|
...config3,
|
|
@@ -67069,25 +67254,25 @@ function runExplorer(config3) {
|
|
|
67069
67254
|
onEvent: config3.onEvent === void 0 ? void 0 : safeHandler(config3.onEvent)
|
|
67070
67255
|
};
|
|
67071
67256
|
safeConfig.onEvent?.({ type: "STAGE_START", agent: "explorer" });
|
|
67072
|
-
return
|
|
67073
|
-
(0,
|
|
67074
|
-
).andThen(() =>
|
|
67257
|
+
return import_neverthrow20.ResultAsync.fromSafePromise(
|
|
67258
|
+
(0, import_promises12.mkdir)(runPaths.screenshotsDir, { recursive: true }).catch(() => null)
|
|
67259
|
+
).andThen(() => runPipeline2({ safeConfig, runPaths, start }));
|
|
67075
67260
|
}
|
|
67076
67261
|
|
|
67077
67262
|
// ../../packages/pipeline/dist/index.js
|
|
67078
|
-
var
|
|
67263
|
+
var import_neverthrow36 = __toESM(require_index_cjs(), 1);
|
|
67079
67264
|
|
|
67080
67265
|
// ../../agents/inspector/dist/index.js
|
|
67081
|
-
var import_neverthrow23 = __toESM(require_index_cjs(), 1);
|
|
67082
|
-
var import_promises13 = require("node:fs/promises");
|
|
67083
|
-
var import_neverthrow24 = __toESM(require_index_cjs(), 1);
|
|
67084
67266
|
var import_neverthrow25 = __toESM(require_index_cjs(), 1);
|
|
67267
|
+
var import_promises14 = require("node:fs/promises");
|
|
67085
67268
|
var import_neverthrow26 = __toESM(require_index_cjs(), 1);
|
|
67086
67269
|
var import_neverthrow27 = __toESM(require_index_cjs(), 1);
|
|
67087
|
-
var import_sharp2 = __toESM(require("sharp"), 1);
|
|
67088
67270
|
var import_neverthrow28 = __toESM(require_index_cjs(), 1);
|
|
67089
|
-
var
|
|
67090
|
-
var
|
|
67271
|
+
var import_neverthrow29 = __toESM(require_index_cjs(), 1);
|
|
67272
|
+
var import_sharp2 = __toESM(require("sharp"), 1);
|
|
67273
|
+
var import_neverthrow30 = __toESM(require_index_cjs(), 1);
|
|
67274
|
+
var import_promises15 = require("node:fs/promises");
|
|
67275
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
67091
67276
|
|
|
67092
67277
|
// ../../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs
|
|
67093
67278
|
function isNothing(subject) {
|
|
@@ -68052,7 +68237,7 @@ var directiveHandlers = {
|
|
|
68052
68237
|
}
|
|
68053
68238
|
try {
|
|
68054
68239
|
prefix = decodeURIComponent(prefix);
|
|
68055
|
-
} catch (
|
|
68240
|
+
} catch (err26) {
|
|
68056
68241
|
throwError(state, "tag prefix is malformed: " + prefix);
|
|
68057
68242
|
}
|
|
68058
68243
|
state.tagMap[handle] = prefix;
|
|
@@ -68733,7 +68918,7 @@ function readTagProperty(state) {
|
|
|
68733
68918
|
}
|
|
68734
68919
|
try {
|
|
68735
68920
|
tagName = decodeURIComponent(tagName);
|
|
68736
|
-
} catch (
|
|
68921
|
+
} catch (err26) {
|
|
68737
68922
|
throwError(state, "tag name is malformed: " + tagName);
|
|
68738
68923
|
}
|
|
68739
68924
|
if (isVerbatim) {
|
|
@@ -69714,7 +69899,7 @@ var jsYaml = {
|
|
|
69714
69899
|
};
|
|
69715
69900
|
|
|
69716
69901
|
// ../../agents/inspector/dist/index.js
|
|
69717
|
-
var
|
|
69902
|
+
var import_neverthrow31 = __toESM(require_index_cjs(), 1);
|
|
69718
69903
|
var MS_PER_DAY = 864e5;
|
|
69719
69904
|
function dequeue(context, current) {
|
|
69720
69905
|
if (current.remainingQueue.length === 0 || context.activeCount + current.events.length >= context.maxConcurrency) {
|
|
@@ -69752,20 +69937,21 @@ function scheduleNext(state, maxConcurrency) {
|
|
|
69752
69937
|
{ events: [], remainingQueue: state.queue }
|
|
69753
69938
|
);
|
|
69754
69939
|
}
|
|
69755
|
-
var CONFIDENCE_HIGH = 0.9;
|
|
69756
|
-
var CONFIDENCE_MEDIUM = 0.6;
|
|
69757
|
-
var CONFIDENCE_LOW = 0.3;
|
|
69758
69940
|
function toTriggerType(type2) {
|
|
69759
69941
|
return type2 === "localization-issue" ? "localization-issue" : "visual-regression";
|
|
69760
69942
|
}
|
|
69761
|
-
function
|
|
69762
|
-
|
|
69763
|
-
|
|
69764
|
-
|
|
69765
|
-
|
|
69766
|
-
|
|
69943
|
+
function severityToConfidence(severity) {
|
|
69944
|
+
switch (severity) {
|
|
69945
|
+
case "high": {
|
|
69946
|
+
return "HIGH";
|
|
69947
|
+
}
|
|
69948
|
+
case "medium": {
|
|
69949
|
+
return "MEDIUM";
|
|
69950
|
+
}
|
|
69951
|
+
case "low": {
|
|
69952
|
+
return "LOW";
|
|
69953
|
+
}
|
|
69767
69954
|
}
|
|
69768
|
-
return CONFIDENCE_LOW;
|
|
69769
69955
|
}
|
|
69770
69956
|
function parseJson(raw) {
|
|
69771
69957
|
return JSON.parse(raw);
|
|
@@ -69785,13 +69971,13 @@ function mapRawFinding(item) {
|
|
|
69785
69971
|
triggerType: toTriggerType(item.type),
|
|
69786
69972
|
flow: "",
|
|
69787
69973
|
steps: [],
|
|
69788
|
-
confidence:
|
|
69974
|
+
confidence: severityToConfidence(item.severity),
|
|
69789
69975
|
description: `[${item.element}] ${item.description}`,
|
|
69790
69976
|
screenshots: [],
|
|
69791
69977
|
agent: "inspector"
|
|
69792
69978
|
};
|
|
69793
69979
|
}
|
|
69794
|
-
var safeJsonParse3 = (0,
|
|
69980
|
+
var safeJsonParse3 = (0, import_neverthrow28.fromThrowable)(parseJson);
|
|
69795
69981
|
function parseClaudeResponse(raw) {
|
|
69796
69982
|
const parseResult = safeJsonParse3(raw);
|
|
69797
69983
|
if (parseResult.isErr()) {
|
|
@@ -69818,7 +70004,7 @@ async function downscaleBuffer(buffer) {
|
|
|
69818
70004
|
return (0, import_sharp2.default)(buffer).resize({ width: targetWidth }).toBuffer();
|
|
69819
70005
|
}
|
|
69820
70006
|
function downscale(buffer) {
|
|
69821
|
-
return (0,
|
|
70007
|
+
return (0, import_neverthrow29.fromAsyncThrowable)(
|
|
69822
70008
|
downscaleBuffer,
|
|
69823
70009
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
69824
70010
|
)(buffer);
|
|
@@ -69893,7 +70079,7 @@ async function fetchClaudeText({
|
|
|
69893
70079
|
return block?.type === "text" ? block.text : "";
|
|
69894
70080
|
}
|
|
69895
70081
|
function callClaude(options2) {
|
|
69896
|
-
return (0,
|
|
70082
|
+
return (0, import_neverthrow27.fromAsyncThrowable)(
|
|
69897
70083
|
fetchClaudeText,
|
|
69898
70084
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
69899
70085
|
)(options2);
|
|
@@ -69905,9 +70091,9 @@ function toFindings(text) {
|
|
|
69905
70091
|
const cleaned = stripCodeFences(text);
|
|
69906
70092
|
const findings = parseClaudeResponse(cleaned);
|
|
69907
70093
|
if (!findings) {
|
|
69908
|
-
return (0,
|
|
70094
|
+
return (0, import_neverthrow27.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: cleaned });
|
|
69909
70095
|
}
|
|
69910
|
-
return (0,
|
|
70096
|
+
return (0, import_neverthrow27.okAsync)(findings);
|
|
69911
70097
|
}
|
|
69912
70098
|
function buildResolveMessages(screenshotBase64, artboardNames) {
|
|
69913
70099
|
return [
|
|
@@ -69944,12 +70130,12 @@ async function fetchResolveName({
|
|
|
69944
70130
|
}
|
|
69945
70131
|
function resolveArtboard(screenshot, artboardNames) {
|
|
69946
70132
|
if (artboardNames.length === 0) {
|
|
69947
|
-
return (0,
|
|
70133
|
+
return (0, import_neverthrow27.okAsync)(void 0);
|
|
69948
70134
|
}
|
|
69949
70135
|
const anthropic = new Anthropic();
|
|
69950
70136
|
return downscale(screenshot).andThen((scaled) => {
|
|
69951
70137
|
const screenshotBase64 = scaled.toString("base64");
|
|
69952
|
-
return (0,
|
|
70138
|
+
return (0, import_neverthrow27.fromAsyncThrowable)(
|
|
69953
70139
|
fetchResolveName,
|
|
69954
70140
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
69955
70141
|
)({ anthropic, screenshotBase64, artboardNames }).map((name) => {
|
|
@@ -69977,8 +70163,6 @@ var MAX_TOKENS22 = 2048;
|
|
|
69977
70163
|
var CANDIDATES_MAX_TOKENS = 64;
|
|
69978
70164
|
var MAX_CANDIDATES = 3;
|
|
69979
70165
|
var TEMPERATURE2 = 0;
|
|
69980
|
-
var CONFIDENCE_MEDIUM2 = 0.6;
|
|
69981
|
-
var CONFIDENCE_LOW2 = 0.3;
|
|
69982
70166
|
var DESIGN_CONTEXT_SYSTEM_PROMPT = `You are a visual QA engineer performing design-system inference. You will receive multiple candidate artboards followed by an actual screenshot.
|
|
69983
70167
|
|
|
69984
70168
|
Infer the design system (color palette, typography scale, component patterns) from the candidate artboards. Then compare the screenshot against the inferred design system.
|
|
@@ -70008,11 +70192,17 @@ function isRawConservativeFinding(value) {
|
|
|
70008
70192
|
const object2 = value;
|
|
70009
70193
|
return typeof object2.type === "string" && typeof object2.element === "string" && typeof object2.description === "string" && typeof object2.severity === "string" && isValidConservativeSeverity(object2.severity);
|
|
70010
70194
|
}
|
|
70011
|
-
|
|
70012
|
-
|
|
70013
|
-
|
|
70014
|
-
|
|
70015
|
-
|
|
70195
|
+
function conservativeSeverityToConfidence(severity) {
|
|
70196
|
+
switch (severity) {
|
|
70197
|
+
case "medium": {
|
|
70198
|
+
return "MEDIUM";
|
|
70199
|
+
}
|
|
70200
|
+
case "low": {
|
|
70201
|
+
return "LOW";
|
|
70202
|
+
}
|
|
70203
|
+
}
|
|
70204
|
+
}
|
|
70205
|
+
var safeJsonParse22 = (0, import_neverthrow30.fromThrowable)(JSON.parse);
|
|
70016
70206
|
function resolveNamesFromParsed(parsed, artboardNames) {
|
|
70017
70207
|
return parsed.filter((name) => typeof name === "string").map((name) => {
|
|
70018
70208
|
const lower = name.toLowerCase();
|
|
@@ -70075,7 +70265,7 @@ function parseConservativeResponse(raw) {
|
|
|
70075
70265
|
triggerType: "design-system-violation",
|
|
70076
70266
|
flow: "",
|
|
70077
70267
|
steps: [],
|
|
70078
|
-
confidence:
|
|
70268
|
+
confidence: conservativeSeverityToConfidence(item.severity),
|
|
70079
70269
|
description: `[${item.element}] ${item.description}`,
|
|
70080
70270
|
screenshots: [],
|
|
70081
70271
|
agent: "inspector"
|
|
@@ -70101,9 +70291,9 @@ async function fetchDesignContextText({
|
|
|
70101
70291
|
function toDesignContextFindings(text) {
|
|
70102
70292
|
const findings = parseConservativeResponse(text);
|
|
70103
70293
|
if (!findings) {
|
|
70104
|
-
return (0,
|
|
70294
|
+
return (0, import_neverthrow30.errAsync)({ type: "CLAUDE_RESPONSE_INVALID", raw: text });
|
|
70105
70295
|
}
|
|
70106
|
-
return (0,
|
|
70296
|
+
return (0, import_neverthrow30.okAsync)(findings);
|
|
70107
70297
|
}
|
|
70108
70298
|
async function downscaleAll(buffers) {
|
|
70109
70299
|
return Promise.all(buffers.map(async (buf) => downscaleBuffer(buf)));
|
|
@@ -70129,12 +70319,12 @@ Artboards: ${artboardNames.join(", ")}`
|
|
|
70129
70319
|
}
|
|
70130
70320
|
function findCandidates(screenshot, artboardNames) {
|
|
70131
70321
|
if (artboardNames.length === 0) {
|
|
70132
|
-
return (0,
|
|
70322
|
+
return (0, import_neverthrow30.okAsync)([]);
|
|
70133
70323
|
}
|
|
70134
70324
|
const anthropic = new Anthropic();
|
|
70135
70325
|
return downscale(screenshot).andThen((scaled) => {
|
|
70136
70326
|
const screenshotBase64 = scaled.toString("base64");
|
|
70137
|
-
return (0,
|
|
70327
|
+
return (0, import_neverthrow30.fromAsyncThrowable)(
|
|
70138
70328
|
fetchCandidateNames,
|
|
70139
70329
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
70140
70330
|
)({ anthropic, screenshotBase64, artboardNames });
|
|
@@ -70158,7 +70348,7 @@ function buildDesignContextMessages(screenshotBase64, artboardBase64s) {
|
|
|
70158
70348
|
}
|
|
70159
70349
|
];
|
|
70160
70350
|
}
|
|
70161
|
-
var downscaleAllBuffers = (0,
|
|
70351
|
+
var downscaleAllBuffers = (0, import_neverthrow30.fromAsyncThrowable)(
|
|
70162
70352
|
downscaleAll,
|
|
70163
70353
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
70164
70354
|
);
|
|
@@ -70168,7 +70358,7 @@ function compareWithDesignContext(screenshot, artboards) {
|
|
|
70168
70358
|
const screenshotBase64 = scaledScreenshot.toString("base64");
|
|
70169
70359
|
return downscaleAllBuffers(artboards).andThen((scaledArtboards) => {
|
|
70170
70360
|
const artboardBase64s = scaledArtboards.map((buf) => buf.toString("base64"));
|
|
70171
|
-
return (0,
|
|
70361
|
+
return (0, import_neverthrow30.fromAsyncThrowable)(
|
|
70172
70362
|
fetchDesignContextText,
|
|
70173
70363
|
(cause) => ({ type: "CLAUDE_API_FAILED", cause })
|
|
70174
70364
|
)({ anthropic, screenshotBase64, artboardBase64s }).andThen(toDesignContextFindings);
|
|
@@ -70402,8 +70592,8 @@ async function initArtboardNames({ designStore, config: config3, state }) {
|
|
|
70402
70592
|
);
|
|
70403
70593
|
}
|
|
70404
70594
|
function readScreenshot(screenshotPath, stepIndex) {
|
|
70405
|
-
return
|
|
70406
|
-
|
|
70595
|
+
return import_neverthrow26.ResultAsync.fromThrowable(
|
|
70596
|
+
import_promises14.readFile,
|
|
70407
70597
|
(cause) => ({ type: "SCREENSHOT_READ_FAILED", stepIndex, cause })
|
|
70408
70598
|
)(screenshotPath);
|
|
70409
70599
|
}
|
|
@@ -70475,7 +70665,7 @@ function buildInspector(state, context) {
|
|
|
70475
70665
|
const { promise: promise2, resolve } = Promise.withResolvers();
|
|
70476
70666
|
state.setResolve(resolve);
|
|
70477
70667
|
applyTryResolve(state);
|
|
70478
|
-
return (0,
|
|
70668
|
+
return (0, import_neverthrow25.fromSafePromise)(promise2);
|
|
70479
70669
|
}
|
|
70480
70670
|
};
|
|
70481
70671
|
}
|
|
@@ -70524,14 +70714,14 @@ function parseMeta(raw) {
|
|
|
70524
70714
|
return {};
|
|
70525
70715
|
}
|
|
70526
70716
|
async function readAndParseSidecar(sidecarPath) {
|
|
70527
|
-
const raw = await (0,
|
|
70717
|
+
const raw = await (0, import_promises15.readFile)(sidecarPath, "utf8");
|
|
70528
70718
|
return parseMeta(raw);
|
|
70529
70719
|
}
|
|
70530
70720
|
function readSidecarFile(sidecarPath) {
|
|
70531
|
-
return (0,
|
|
70721
|
+
return (0, import_neverthrow31.fromAsyncThrowable)(
|
|
70532
70722
|
readAndParseSidecar,
|
|
70533
70723
|
() => ({})
|
|
70534
|
-
)(sidecarPath).orElse(() => (0,
|
|
70724
|
+
)(sidecarPath).orElse(() => (0, import_neverthrow31.okAsync)({}));
|
|
70535
70725
|
}
|
|
70536
70726
|
function isEnoent(error48) {
|
|
70537
70727
|
return error48?.code === "ENOENT";
|
|
@@ -70540,13 +70730,13 @@ function wrapFsError(cause) {
|
|
|
70540
70730
|
return { type: "FS_ERROR", cause };
|
|
70541
70731
|
}
|
|
70542
70732
|
function toFsError(fsError) {
|
|
70543
|
-
return (0,
|
|
70733
|
+
return (0, import_neverthrow31.errAsync)(fsError);
|
|
70544
70734
|
}
|
|
70545
70735
|
function missingBuffer() {
|
|
70546
|
-
return (0,
|
|
70736
|
+
return (0, import_neverthrow31.okAsync)(void 0);
|
|
70547
70737
|
}
|
|
70548
70738
|
function missingArtboard() {
|
|
70549
|
-
return (0,
|
|
70739
|
+
return (0, import_neverthrow31.okAsync)(void 0);
|
|
70550
70740
|
}
|
|
70551
70741
|
var FsDesignStore = class {
|
|
70552
70742
|
designsDirectory;
|
|
@@ -70554,12 +70744,12 @@ var FsDesignStore = class {
|
|
|
70554
70744
|
this.designsDirectory = designsDirectory;
|
|
70555
70745
|
}
|
|
70556
70746
|
listArtboards() {
|
|
70557
|
-
return (0,
|
|
70558
|
-
|
|
70747
|
+
return (0, import_neverthrow31.fromAsyncThrowable)(
|
|
70748
|
+
import_promises15.readdir,
|
|
70559
70749
|
wrapFsError
|
|
70560
70750
|
)(this.designsDirectory).orElse((fsError) => {
|
|
70561
70751
|
if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
|
|
70562
|
-
return (0,
|
|
70752
|
+
return (0, import_neverthrow31.okAsync)([]);
|
|
70563
70753
|
}
|
|
70564
70754
|
return toFsError(fsError);
|
|
70565
70755
|
}).map(
|
|
@@ -70567,10 +70757,10 @@ var FsDesignStore = class {
|
|
|
70567
70757
|
);
|
|
70568
70758
|
}
|
|
70569
70759
|
getArtboard(filename) {
|
|
70570
|
-
const pngPath =
|
|
70571
|
-
const sidecarPath =
|
|
70572
|
-
return (0,
|
|
70573
|
-
|
|
70760
|
+
const pngPath = import_node_path8.default.join(this.designsDirectory, `${filename}.png`);
|
|
70761
|
+
const sidecarPath = import_node_path8.default.join(this.designsDirectory, `${filename}.meta.yaml`);
|
|
70762
|
+
return (0, import_neverthrow31.fromAsyncThrowable)(
|
|
70763
|
+
import_promises15.readFile,
|
|
70574
70764
|
wrapFsError
|
|
70575
70765
|
)(pngPath).orElse((fsError) => {
|
|
70576
70766
|
if (fsError.type === "FS_ERROR" && isEnoent(fsError.cause)) {
|
|
@@ -70591,21 +70781,21 @@ var FsDesignStore = class {
|
|
|
70591
70781
|
// ../../packages/pipeline/dist/index.js
|
|
70592
70782
|
var RETRY_MAX_ATTEMPTS = 3;
|
|
70593
70783
|
var RETRY_BASE_DELAY_MS = 1e3;
|
|
70594
|
-
var CONFIDENCE_THRESHOLD =
|
|
70784
|
+
var CONFIDENCE_THRESHOLD = "HIGH";
|
|
70595
70785
|
function filterByConfidence(findings, threshold) {
|
|
70596
70786
|
return {
|
|
70597
|
-
kept: findings.filter((finding) => finding.confidence
|
|
70598
|
-
dropped: findings.filter((finding) => finding.confidence
|
|
70787
|
+
kept: findings.filter((finding) => meetsConfidenceThreshold(finding.confidence, threshold)),
|
|
70788
|
+
dropped: findings.filter((finding) => !meetsConfidenceThreshold(finding.confidence, threshold)).map((finding) => ({ finding, reason: "low-confidence" }))
|
|
70599
70789
|
};
|
|
70600
70790
|
}
|
|
70601
70791
|
function attemptRetry(options2) {
|
|
70602
70792
|
const { factory, config: config3, delayFunction, onRetry, attempt } = options2;
|
|
70603
70793
|
return factory().orElse((error48) => {
|
|
70604
70794
|
if (attempt >= config3.maxAttempts) {
|
|
70605
|
-
return (0,
|
|
70795
|
+
return (0, import_neverthrow34.errAsync)(error48);
|
|
70606
70796
|
}
|
|
70607
70797
|
const delay = config3.baseDelayMs * Math.pow(2, attempt - 1);
|
|
70608
|
-
return
|
|
70798
|
+
return import_neverthrow34.ResultAsync.fromPromise(
|
|
70609
70799
|
(onRetry?.({ attempt, maxAttempts: config3.maxAttempts, delayMs: delay, error: error48 }), delayFunction(delay)),
|
|
70610
70800
|
() => error48
|
|
70611
70801
|
).andThen(
|
|
@@ -70625,7 +70815,7 @@ function withRetry(factory, options2) {
|
|
|
70625
70815
|
var CONSOLIDATOR_AGENT = "consolidator";
|
|
70626
70816
|
function analyserFallback(artifacts, onEvent) {
|
|
70627
70817
|
onEvent?.({ type: "AGENT_FAILED_NON_CRITICAL", agent: "analyser", attempts: RETRY_MAX_ATTEMPTS });
|
|
70628
|
-
return (0,
|
|
70818
|
+
return (0, import_neverthrow33.okAsync)(artifacts.findings);
|
|
70629
70819
|
}
|
|
70630
70820
|
function runAnalyserWithRetry(params) {
|
|
70631
70821
|
const { artifacts, config: config3, onEvent } = params;
|
|
@@ -70635,7 +70825,7 @@ function runAnalyserWithRetry(params) {
|
|
|
70635
70825
|
),
|
|
70636
70826
|
{
|
|
70637
70827
|
config: { maxAttempts: RETRY_MAX_ATTEMPTS, baseDelayMs: RETRY_BASE_DELAY_MS },
|
|
70638
|
-
delayFunction:
|
|
70828
|
+
delayFunction: import_promises16.setTimeout,
|
|
70639
70829
|
onRetry: ({ attempt, maxAttempts, delayMs, error: error48 }) => {
|
|
70640
70830
|
onEvent?.({
|
|
70641
70831
|
type: "AGENT_RETRY",
|
|
@@ -70655,7 +70845,7 @@ function resolveVisualFindings({
|
|
|
70655
70845
|
onEvent
|
|
70656
70846
|
}) {
|
|
70657
70847
|
if (config3.analyser === void 0 || config3.signal?.aborted) {
|
|
70658
|
-
return (0,
|
|
70848
|
+
return (0, import_neverthrow33.okAsync)(artifacts.findings);
|
|
70659
70849
|
}
|
|
70660
70850
|
return runAnalyserWithRetry({ artifacts, config: config3, onEvent });
|
|
70661
70851
|
}
|
|
@@ -70665,7 +70855,7 @@ function unmergedFallback(allFindings, onEvent) {
|
|
|
70665
70855
|
agent: CONSOLIDATOR_AGENT,
|
|
70666
70856
|
message: "Consolidation failed, returning unmerged findings"
|
|
70667
70857
|
});
|
|
70668
|
-
return (0,
|
|
70858
|
+
return (0, import_neverthrow33.okAsync)({ findings: allFindings, dismissed: [] });
|
|
70669
70859
|
}
|
|
70670
70860
|
function mergeWithFallback(options2) {
|
|
70671
70861
|
const {
|
|
@@ -70692,7 +70882,7 @@ function consolidate(options2) {
|
|
|
70692
70882
|
const { artifacts, inspectorFindings, runId, dismissals, config: config3, consolidatorConfig, onEvent } = options2;
|
|
70693
70883
|
return resolveVisualFindings({ artifacts, config: config3, onEvent }).andThen((visualFindings) => {
|
|
70694
70884
|
if (config3.signal?.aborted) {
|
|
70695
|
-
return (0,
|
|
70885
|
+
return (0, import_neverthrow33.okAsync)({ findings: artifacts.findings, dismissed: [] });
|
|
70696
70886
|
}
|
|
70697
70887
|
return mergeWithFallback({
|
|
70698
70888
|
artifacts,
|
|
@@ -70705,8 +70895,8 @@ function consolidate(options2) {
|
|
|
70705
70895
|
});
|
|
70706
70896
|
});
|
|
70707
70897
|
}
|
|
70708
|
-
var safeReadFile = (0,
|
|
70709
|
-
var safeParseJson2 = (0,
|
|
70898
|
+
var safeReadFile = (0, import_neverthrow35.fromThrowable)((filePath) => (0, import_node_fs3.readFileSync)(filePath, "utf8"));
|
|
70899
|
+
var safeParseJson2 = (0, import_neverthrow35.fromThrowable)(JSON.parse);
|
|
70710
70900
|
function isEnoent2(error48) {
|
|
70711
70901
|
if (!(error48 instanceof Error)) {
|
|
70712
70902
|
return false;
|
|
@@ -70718,19 +70908,19 @@ function loadDismissals(filePath) {
|
|
|
70718
70908
|
const readResult = safeReadFile(filePath);
|
|
70719
70909
|
if (readResult.isErr()) {
|
|
70720
70910
|
if (isEnoent2(readResult.error)) {
|
|
70721
|
-
return (0,
|
|
70911
|
+
return (0, import_neverthrow35.ok)([]);
|
|
70722
70912
|
}
|
|
70723
|
-
return (0,
|
|
70913
|
+
return (0, import_neverthrow35.err)({ type: "DISMISSALS_LOAD_FAILED", cause: readResult.error });
|
|
70724
70914
|
}
|
|
70725
70915
|
return safeParseJson2(readResult.value).mapErr((cause) => ({ type: "DISMISSALS_LOAD_FAILED", cause })).andThen((data) => {
|
|
70726
70916
|
const store = data;
|
|
70727
70917
|
if (!Array.isArray(store.dismissed)) {
|
|
70728
|
-
return (0,
|
|
70918
|
+
return (0, import_neverthrow35.err)({
|
|
70729
70919
|
type: "DISMISSALS_LOAD_FAILED",
|
|
70730
70920
|
cause: "invalid shape: dismissed is not an array"
|
|
70731
70921
|
});
|
|
70732
70922
|
}
|
|
70733
|
-
return (0,
|
|
70923
|
+
return (0, import_neverthrow35.ok)(store.dismissed);
|
|
70734
70924
|
});
|
|
70735
70925
|
}
|
|
70736
70926
|
function toInspectorStepEvent(event) {
|
|
@@ -70817,14 +71007,14 @@ function runExplorerWithTeardown(explorerConfig, udid) {
|
|
|
70817
71007
|
return runExplorer(explorerConfig).mapErr((cause) => ({ type: "EXPLORER_FAILED", cause })).andThen(
|
|
70818
71008
|
(artifacts) => disableTouchIndicators(udid).mapErr(toSimulatorError).map(() => artifacts)
|
|
70819
71009
|
).orElse(
|
|
70820
|
-
(error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0,
|
|
71010
|
+
(error48) => disableTouchIndicators(udid).mapErr(toSimulatorError).andThen(() => (0, import_neverthrow36.errAsync)(error48)).orElse(() => (0, import_neverthrow36.errAsync)(error48))
|
|
70821
71011
|
);
|
|
70822
71012
|
}
|
|
70823
71013
|
function runExplorerWithRetry(options2) {
|
|
70824
71014
|
const { explorerConfig, udid, onEvent } = options2;
|
|
70825
71015
|
return withRetry(() => runExplorerWithTeardown(explorerConfig, udid), {
|
|
70826
71016
|
config: { maxAttempts: RETRY_MAX_ATTEMPTS, baseDelayMs: RETRY_BASE_DELAY_MS },
|
|
70827
|
-
delayFunction:
|
|
71017
|
+
delayFunction: import_promises17.setTimeout,
|
|
70828
71018
|
onRetry: ({ attempt, maxAttempts, delayMs, error: error48 }) => {
|
|
70829
71019
|
onEvent?.({
|
|
70830
71020
|
type: "AGENT_RETRY",
|
|
@@ -70843,12 +71033,12 @@ async function drainAfterExplorer(options2) {
|
|
|
70843
71033
|
inspector?.close();
|
|
70844
71034
|
const inspectorFindings = inspector ? await collectInspectorFindings({ inspector, onEvent, totalSteps: enqueuedCount.value }) : [];
|
|
70845
71035
|
if (explorerResult.isErr()) {
|
|
70846
|
-
return (0,
|
|
71036
|
+
return (0, import_neverthrow36.err)(explorerResult.error);
|
|
70847
71037
|
}
|
|
70848
|
-
return (0,
|
|
71038
|
+
return (0, import_neverthrow36.ok)({ artifacts: explorerResult.value, inspectorFindings });
|
|
70849
71039
|
}
|
|
70850
71040
|
function runExplorerAndDrain(options2) {
|
|
70851
|
-
return
|
|
71041
|
+
return import_neverthrow36.ResultAsync.fromSafePromise(drainAfterExplorer(options2)).andThen((result) => result);
|
|
70852
71042
|
}
|
|
70853
71043
|
function createDefaultMcpServers(udid) {
|
|
70854
71044
|
return {
|
|
@@ -70860,7 +71050,7 @@ function runAnalysis(artifacts, config3) {
|
|
|
70860
71050
|
}
|
|
70861
71051
|
var ISO_DATE_LENGTH2 = 10;
|
|
70862
71052
|
var RUN_ID_PAD_LENGTH = 4;
|
|
70863
|
-
var safeReaddirSync = (0,
|
|
71053
|
+
var safeReaddirSync = (0, import_neverthrow32.fromThrowable)((directory) => (0, import_node_fs2.readdirSync)(directory));
|
|
70864
71054
|
function nextRunId(outputDirectory, date5) {
|
|
70865
71055
|
const entries = safeReaddirSync(`${outputDirectory}/${date5}`).unwrapOr([]);
|
|
70866
71056
|
let max = 0;
|
|
@@ -70872,7 +71062,7 @@ function nextRunId(outputDirectory, date5) {
|
|
|
70872
71062
|
}
|
|
70873
71063
|
return String(max + 1).padStart(RUN_ID_PAD_LENGTH, "0");
|
|
70874
71064
|
}
|
|
70875
|
-
var writeOutputFile = (0,
|
|
71065
|
+
var writeOutputFile = (0, import_neverthrow32.fromThrowable)(
|
|
70876
71066
|
(params) => {
|
|
70877
71067
|
const { findingsPath, outputDirectory, json: json3 } = params;
|
|
70878
71068
|
(0, import_node_fs2.mkdirSync)(outputDirectory, { recursive: true });
|
|
@@ -70885,15 +71075,15 @@ function validatePipelineConfig(config3) {
|
|
|
70885
71075
|
const runId = config3.runId ?? nextRunId(config3.outputDir, date5);
|
|
70886
71076
|
const runPathsResult = resolveRunPaths({ outputDirectory: config3.outputDir, runId, date: date5 });
|
|
70887
71077
|
if (runPathsResult.isErr()) {
|
|
70888
|
-
return (0,
|
|
71078
|
+
return (0, import_neverthrow32.err)({ type: "RUN_PATHS_FAILED", cause: runPathsResult.error });
|
|
70889
71079
|
}
|
|
70890
71080
|
const dismissalsResult = loadDismissals(
|
|
70891
71081
|
dismissalsPath(config3.outputDir, process.env.QA_DISMISSALS_PATH)
|
|
70892
71082
|
);
|
|
70893
71083
|
if (dismissalsResult.isErr()) {
|
|
70894
|
-
return (0,
|
|
71084
|
+
return (0, import_neverthrow32.err)(dismissalsResult.error);
|
|
70895
71085
|
}
|
|
70896
|
-
return (0,
|
|
71086
|
+
return (0, import_neverthrow32.ok)({ runId, date: date5, runPaths: runPathsResult.value, dismissals: dismissalsResult.value });
|
|
70897
71087
|
}
|
|
70898
71088
|
function buildExplorerConfig({
|
|
70899
71089
|
config: config3,
|
|
@@ -70931,11 +71121,11 @@ function buildOutput(consolidationResult, options2) {
|
|
|
70931
71121
|
function buildPipelineSetup(config3) {
|
|
70932
71122
|
const validatedResult = validatePipelineConfig(config3);
|
|
70933
71123
|
if (validatedResult.isErr()) {
|
|
70934
|
-
return (0,
|
|
71124
|
+
return (0, import_neverthrow32.err)(validatedResult.error);
|
|
70935
71125
|
}
|
|
70936
71126
|
const { runId, date: date5, runPaths, dismissals } = validatedResult.value;
|
|
70937
71127
|
const { inspector, explorerOnEvent, enqueuedCount } = buildInspectorSetup(config3);
|
|
70938
|
-
return (0,
|
|
71128
|
+
return (0, import_neverthrow32.ok)({
|
|
70939
71129
|
runId,
|
|
70940
71130
|
udid: config3.simulatorUdid ?? "booted",
|
|
70941
71131
|
runPaths,
|
|
@@ -70977,16 +71167,16 @@ function executePipeline(setup, config3) {
|
|
|
70977
71167
|
})
|
|
70978
71168
|
);
|
|
70979
71169
|
}
|
|
70980
|
-
function
|
|
71170
|
+
function runPipeline3(config3) {
|
|
70981
71171
|
const setupResult = buildPipelineSetup(config3);
|
|
70982
71172
|
if (setupResult.isErr()) {
|
|
70983
|
-
return (0,
|
|
71173
|
+
return (0, import_neverthrow32.errAsync)(setupResult.error);
|
|
70984
71174
|
}
|
|
70985
71175
|
return executePipeline(setupResult.value, config3);
|
|
70986
71176
|
}
|
|
70987
71177
|
|
|
70988
71178
|
// src/commands/analyse-command.ts
|
|
70989
|
-
var
|
|
71179
|
+
var import_neverthrow38 = __toESM(require_index_cjs(), 1);
|
|
70990
71180
|
|
|
70991
71181
|
// src/commands/item-events.ts
|
|
70992
71182
|
function emitItemStart(identity, at) {
|
|
@@ -71022,7 +71212,7 @@ function emitItemFailed(input) {
|
|
|
71022
71212
|
}
|
|
71023
71213
|
|
|
71024
71214
|
// src/shell/debug-agent-events.ts
|
|
71025
|
-
var
|
|
71215
|
+
var import_neverthrow37 = __toESM(require_index_cjs(), 1);
|
|
71026
71216
|
|
|
71027
71217
|
// src/constants.ts
|
|
71028
71218
|
var MOBILE_IOS_TOOLS = [
|
|
@@ -71105,7 +71295,7 @@ function tryStringify(value) {
|
|
|
71105
71295
|
const result = JSON.stringify(value);
|
|
71106
71296
|
return result ?? UNSERIALIZABLE;
|
|
71107
71297
|
}
|
|
71108
|
-
var safeStringify = (0,
|
|
71298
|
+
var safeStringify = (0, import_neverthrow37.fromThrowable)(tryStringify, () => ({
|
|
71109
71299
|
type: "STRINGIFY_FAILED"
|
|
71110
71300
|
}));
|
|
71111
71301
|
function toolKey(scope, event) {
|
|
@@ -71326,7 +71516,7 @@ function buildArtifacts(videoPath) {
|
|
|
71326
71516
|
return { videoPath, findings: [], snapshots: [] };
|
|
71327
71517
|
}
|
|
71328
71518
|
async function checkVideoPathExists(videoPath) {
|
|
71329
|
-
const safeAccess = (0,
|
|
71519
|
+
const safeAccess = (0, import_neverthrow38.fromAsyncThrowable)(import_promises18.access, () => ({ type: "FILE_NOT_FOUND" }));
|
|
71330
71520
|
const result = await safeAccess(videoPath);
|
|
71331
71521
|
return result.isOk();
|
|
71332
71522
|
}
|
|
@@ -71421,7 +71611,7 @@ async function runAnalyseCommand(input) {
|
|
|
71421
71611
|
}
|
|
71422
71612
|
|
|
71423
71613
|
// src/core/completion-generator.ts
|
|
71424
|
-
var
|
|
71614
|
+
var import_neverthrow39 = __toESM(require_index_cjs(), 1);
|
|
71425
71615
|
function extractLongFlags(flags) {
|
|
71426
71616
|
return flags.split(/[\s,]+/).filter((token) => token.startsWith("--"));
|
|
71427
71617
|
}
|
|
@@ -71511,9 +71701,9 @@ complete -F _xqa_completion xqa`;
|
|
|
71511
71701
|
}
|
|
71512
71702
|
function generateCompletion(commands, shell) {
|
|
71513
71703
|
if (shell !== "bash" && shell !== "zsh") {
|
|
71514
|
-
return (0,
|
|
71704
|
+
return (0, import_neverthrow39.err)({ type: "UNSUPPORTED_SHELL", shell });
|
|
71515
71705
|
}
|
|
71516
|
-
return (0,
|
|
71706
|
+
return (0, import_neverthrow39.ok)(shell === "zsh" ? generateZshCompletion(commands) : generateBashCompletion(commands));
|
|
71517
71707
|
}
|
|
71518
71708
|
|
|
71519
71709
|
// src/commands/completion-command.ts
|
|
@@ -71546,33 +71736,33 @@ function runCompletionCommand(program3, shell) {
|
|
|
71546
71736
|
}
|
|
71547
71737
|
|
|
71548
71738
|
// src/commands/explore-command.ts
|
|
71549
|
-
var
|
|
71739
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
71550
71740
|
|
|
71551
71741
|
// src/core/last-path.ts
|
|
71552
71742
|
var import_node_fs4 = require("node:fs");
|
|
71553
|
-
var
|
|
71554
|
-
var
|
|
71743
|
+
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
71744
|
+
var import_neverthrow40 = __toESM(require_index_cjs(), 1);
|
|
71555
71745
|
function resolveLastPath(argument, stateContent) {
|
|
71556
71746
|
if (argument !== void 0) {
|
|
71557
|
-
return (0,
|
|
71747
|
+
return (0, import_neverthrow40.ok)(argument);
|
|
71558
71748
|
}
|
|
71559
71749
|
const trimmed = stateContent?.trim();
|
|
71560
71750
|
if (trimmed) {
|
|
71561
|
-
return (0,
|
|
71751
|
+
return (0, import_neverthrow40.ok)(trimmed);
|
|
71562
71752
|
}
|
|
71563
|
-
return (0,
|
|
71753
|
+
return (0, import_neverthrow40.err)({ type: "NO_ARG_AND_NO_STATE" });
|
|
71564
71754
|
}
|
|
71565
71755
|
function lastPathFilePath(xqaDirectoryectory) {
|
|
71566
|
-
return
|
|
71756
|
+
return import_node_path9.default.join(xqaDirectoryectory, "last-findings-path");
|
|
71567
71757
|
}
|
|
71568
71758
|
function writeLastPath(xqaDirectory, findingsPath) {
|
|
71569
71759
|
(0, import_node_fs4.writeFileSync)(lastPathFilePath(xqaDirectory), findingsPath);
|
|
71570
71760
|
}
|
|
71571
71761
|
|
|
71572
71762
|
// src/shell/app-context.ts
|
|
71573
|
-
var
|
|
71574
|
-
var
|
|
71575
|
-
var
|
|
71763
|
+
var import_promises19 = require("node:fs/promises");
|
|
71764
|
+
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
71765
|
+
var import_neverthrow41 = __toESM(require_index_cjs(), 1);
|
|
71576
71766
|
var HTML_COMMENT_PATTERN = /<!--[\s\S]*?-->/g;
|
|
71577
71767
|
function isEnoentError(value) {
|
|
71578
71768
|
return value !== null && typeof value === "object" && "code" in value && value.code === "ENOENT";
|
|
@@ -71582,10 +71772,10 @@ function toAppContextError(cause) {
|
|
|
71582
71772
|
}
|
|
71583
71773
|
function absentContext() {
|
|
71584
71774
|
const absent = void 0;
|
|
71585
|
-
return (0,
|
|
71775
|
+
return (0, import_neverthrow41.ok)(absent);
|
|
71586
71776
|
}
|
|
71587
|
-
var safeReadFile2 =
|
|
71588
|
-
async (filePath) => (0,
|
|
71777
|
+
var safeReadFile2 = import_neverthrow41.ResultAsync.fromThrowable(
|
|
71778
|
+
async (filePath) => (0, import_promises19.readFile)(filePath, "utf8"),
|
|
71589
71779
|
toAppContextError
|
|
71590
71780
|
);
|
|
71591
71781
|
function stripAndNormalize(content) {
|
|
@@ -71593,12 +71783,12 @@ function stripAndNormalize(content) {
|
|
|
71593
71783
|
return stripped.length === 0 ? void 0 : stripped;
|
|
71594
71784
|
}
|
|
71595
71785
|
function readContextFile(xqaDirectory, filename) {
|
|
71596
|
-
const filePath =
|
|
71786
|
+
const filePath = import_node_path10.default.join(xqaDirectory, filename);
|
|
71597
71787
|
return safeReadFile2(filePath).map((content) => stripAndNormalize(content)).orElse((error48) => {
|
|
71598
71788
|
if (isEnoentError(error48.cause)) {
|
|
71599
71789
|
return absentContext();
|
|
71600
71790
|
}
|
|
71601
|
-
return (0,
|
|
71791
|
+
return (0, import_neverthrow41.err)(error48);
|
|
71602
71792
|
});
|
|
71603
71793
|
}
|
|
71604
71794
|
function readAppContext(xqaDirectory) {
|
|
@@ -71647,12 +71837,12 @@ function buildPipelineConfig({
|
|
|
71647
71837
|
simulatorUdid
|
|
71648
71838
|
}) {
|
|
71649
71839
|
const base = {
|
|
71650
|
-
outputDir:
|
|
71840
|
+
outputDir: import_node_path11.default.join(xqaDirectory, "output"),
|
|
71651
71841
|
runId: config3.QA_RUN_ID,
|
|
71652
71842
|
simulatorUdid,
|
|
71653
71843
|
onEvent,
|
|
71654
71844
|
signal: input.signal,
|
|
71655
|
-
inspector: { designsDirectory:
|
|
71845
|
+
inspector: { designsDirectory: import_node_path11.default.join(xqaDirectory, "designs") },
|
|
71656
71846
|
explorer
|
|
71657
71847
|
};
|
|
71658
71848
|
if (!config3.GOOGLE_GENERATIVE_AI_API_KEY) {
|
|
@@ -71714,7 +71904,7 @@ function runExplorePipeline(state, contexts) {
|
|
|
71714
71904
|
appContext: contexts.appContext,
|
|
71715
71905
|
initialState: contexts.exploreContext
|
|
71716
71906
|
});
|
|
71717
|
-
void
|
|
71907
|
+
void runPipeline3(
|
|
71718
71908
|
buildPipelineConfig({
|
|
71719
71909
|
input,
|
|
71720
71910
|
config: config3,
|
|
@@ -71794,21 +71984,21 @@ function runExploreCommand(input, options2) {
|
|
|
71794
71984
|
|
|
71795
71985
|
// src/commands/init-command.ts
|
|
71796
71986
|
var import_node_fs6 = require("node:fs");
|
|
71797
|
-
var
|
|
71987
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
71798
71988
|
|
|
71799
71989
|
// src/commands/install-skills.ts
|
|
71800
71990
|
var import_node_child_process5 = require("node:child_process");
|
|
71801
71991
|
var import_node_fs5 = require("node:fs");
|
|
71802
|
-
var
|
|
71992
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
71803
71993
|
var import_node_url = require("node:url");
|
|
71804
71994
|
function resolveSkillsRoot() {
|
|
71805
|
-
const packageDistributionDirectory =
|
|
71806
|
-
return
|
|
71995
|
+
const packageDistributionDirectory = import_node_path12.default.dirname((0, import_node_url.fileURLToPath)(__importMetaUrl));
|
|
71996
|
+
return import_node_path12.default.join(packageDistributionDirectory, "skills");
|
|
71807
71997
|
}
|
|
71808
71998
|
function installSkills() {
|
|
71809
71999
|
const skillsRoot = resolveSkillsRoot();
|
|
71810
72000
|
for (const skill of (0, import_node_fs5.readdirSync)(skillsRoot)) {
|
|
71811
|
-
(0, import_node_child_process5.spawnSync)("npx", ["skills", "add",
|
|
72001
|
+
(0, import_node_child_process5.spawnSync)("npx", ["skills", "add", import_node_path12.default.join(skillsRoot, skill), "-y"], {
|
|
71812
72002
|
stdio: "inherit"
|
|
71813
72003
|
});
|
|
71814
72004
|
}
|
|
@@ -71860,7 +72050,7 @@ Scope applies from the starting screen. If the focus area requires navigation, d
|
|
|
71860
72050
|
-->
|
|
71861
72051
|
`;
|
|
71862
72052
|
function runInitCommand() {
|
|
71863
|
-
const xqaDirectory =
|
|
72053
|
+
const xqaDirectory = import_node_path13.default.join(process.cwd(), ".xqa");
|
|
71864
72054
|
installSkills();
|
|
71865
72055
|
if ((0, import_node_fs6.existsSync)(xqaDirectory)) {
|
|
71866
72056
|
process.stdout.write(`Skills updated. .xqa already exists, skipping project init.
|
|
@@ -71868,12 +72058,12 @@ function runInitCommand() {
|
|
|
71868
72058
|
return;
|
|
71869
72059
|
}
|
|
71870
72060
|
(0, import_node_fs6.mkdirSync)(xqaDirectory);
|
|
71871
|
-
(0, import_node_fs6.writeFileSync)(
|
|
71872
|
-
(0, import_node_fs6.writeFileSync)(
|
|
71873
|
-
(0, import_node_fs6.writeFileSync)(
|
|
72061
|
+
(0, import_node_fs6.writeFileSync)(import_node_path13.default.join(xqaDirectory, ".gitignore"), GITIGNORE_CONTENT);
|
|
72062
|
+
(0, import_node_fs6.writeFileSync)(import_node_path13.default.join(xqaDirectory, "app.md"), APP_TEMPLATE);
|
|
72063
|
+
(0, import_node_fs6.writeFileSync)(import_node_path13.default.join(xqaDirectory, "explore.md"), EXPLORE_TEMPLATE);
|
|
71874
72064
|
for (const subdir of ["designs", "specs", "suites"]) {
|
|
71875
|
-
(0, import_node_fs6.mkdirSync)(
|
|
71876
|
-
(0, import_node_fs6.writeFileSync)(
|
|
72065
|
+
(0, import_node_fs6.mkdirSync)(import_node_path13.default.join(xqaDirectory, subdir));
|
|
72066
|
+
(0, import_node_fs6.writeFileSync)(import_node_path13.default.join(xqaDirectory, subdir, ".gitkeep"), "");
|
|
71877
72067
|
}
|
|
71878
72068
|
process.stdout.write(`Initialized xqa project: ${xqaDirectory}
|
|
71879
72069
|
`);
|
|
@@ -71885,8 +72075,8 @@ function runInitCommand() {
|
|
|
71885
72075
|
|
|
71886
72076
|
// src/commands/review-command.ts
|
|
71887
72077
|
var import_node_fs7 = require("node:fs");
|
|
71888
|
-
var
|
|
71889
|
-
var
|
|
72078
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
72079
|
+
var import_neverthrow43 = __toESM(require_index_cjs(), 1);
|
|
71890
72080
|
|
|
71891
72081
|
// ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@22.19.15/node_modules/@inquirer/core/dist/esm/lib/key.js
|
|
71892
72082
|
var isUpKey = (key, keybindings = []) => (
|
|
@@ -73224,7 +73414,7 @@ var esm_default2 = createPrompt((config3, done) => {
|
|
|
73224
73414
|
var import_chardet = __toESM(require_lib2(), 1);
|
|
73225
73415
|
var import_child_process3 = require("child_process");
|
|
73226
73416
|
var import_fs3 = require("fs");
|
|
73227
|
-
var
|
|
73417
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
73228
73418
|
var import_node_os3 = __toESM(require("node:os"), 1);
|
|
73229
73419
|
var import_node_crypto2 = require("node:crypto");
|
|
73230
73420
|
var import_iconv_lite = __toESM(require_lib3(), 1);
|
|
@@ -73268,9 +73458,9 @@ var RemoveFileError = class extends Error {
|
|
|
73268
73458
|
// ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@22.19.15/node_modules/@inquirer/external-editor/dist/esm/index.js
|
|
73269
73459
|
function editAsync(text = "", callback, fileOptions) {
|
|
73270
73460
|
const editor = new ExternalEditor(text, fileOptions);
|
|
73271
|
-
editor.runAsync((
|
|
73272
|
-
if (
|
|
73273
|
-
setImmediate(callback,
|
|
73461
|
+
editor.runAsync((err26, result) => {
|
|
73462
|
+
if (err26) {
|
|
73463
|
+
setImmediate(callback, err26, void 0);
|
|
73274
73464
|
} else {
|
|
73275
73465
|
try {
|
|
73276
73466
|
editor.cleanup();
|
|
@@ -73360,8 +73550,8 @@ var ExternalEditor = class {
|
|
|
73360
73550
|
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
|
73361
73551
|
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
|
73362
73552
|
const filename = `${prefix}${id}${postfix}`;
|
|
73363
|
-
const candidate =
|
|
73364
|
-
const baseResolved =
|
|
73553
|
+
const candidate = import_node_path14.default.resolve(baseDir, filename);
|
|
73554
|
+
const baseResolved = import_node_path14.default.resolve(baseDir) + import_node_path14.default.sep;
|
|
73365
73555
|
if (!candidate.startsWith(baseResolved)) {
|
|
73366
73556
|
throw new Error("Resolved temporary file escaped the base directory");
|
|
73367
73557
|
}
|
|
@@ -74291,11 +74481,10 @@ var esm_default11 = createPrompt((config3, done) => {
|
|
|
74291
74481
|
});
|
|
74292
74482
|
|
|
74293
74483
|
// src/review-session.ts
|
|
74294
|
-
var
|
|
74295
|
-
var CONFIDENCE_PERCENT = 100;
|
|
74484
|
+
var import_neverthrow42 = __toESM(require_index_cjs(), 1);
|
|
74296
74485
|
var FLOW_COL_WIDTH = 35;
|
|
74297
74486
|
var TRIGGER_COL_WIDTH = 16;
|
|
74298
|
-
var CONFIDENCE_COL_WIDTH =
|
|
74487
|
+
var CONFIDENCE_COL_WIDTH = 6;
|
|
74299
74488
|
var COL_SEPARATOR_WIDTH = 6;
|
|
74300
74489
|
var FIXED_COLS_WIDTH = FLOW_COL_WIDTH + TRIGGER_COL_WIDTH + CONFIDENCE_COL_WIDTH + COL_SEPARATOR_WIDTH;
|
|
74301
74490
|
var DEFAULT_TERMINAL_WIDTH = 80;
|
|
@@ -74362,7 +74551,7 @@ function applyDismissal(dismissal, state) {
|
|
|
74362
74551
|
state.stagedKeys.add(key);
|
|
74363
74552
|
}
|
|
74364
74553
|
async function selectFinding(findings, state) {
|
|
74365
|
-
const activeSorted = findings.filter((finding) => !state.dismissedKeys.has(dismissalKey(finding))).toSorted((fa, fb2) => fa.confidence
|
|
74554
|
+
const activeSorted = findings.filter((finding) => !state.dismissedKeys.has(dismissalKey(finding))).toSorted((fa, fb2) => compareConfidence(fa.confidence, fb2.confidence));
|
|
74366
74555
|
const reconsidered = activeSorted.filter(
|
|
74367
74556
|
(finding) => state.undoneKeys.has(dismissalKey(finding))
|
|
74368
74557
|
);
|
|
@@ -74401,9 +74590,7 @@ function buildChoiceName(finding, state) {
|
|
|
74401
74590
|
const maxDescWidth = terminalWidth - CURSOR_MARGIN - FIXED_COLS_WIDTH - suffix.length;
|
|
74402
74591
|
const flow = source_default.bold(finding.flow.padEnd(FLOW_COL_WIDTH));
|
|
74403
74592
|
const triggerType = source_default.dim(finding.triggerType.padEnd(TRIGGER_COL_WIDTH));
|
|
74404
|
-
const confidence =
|
|
74405
|
-
CONFIDENCE_COL_WIDTH
|
|
74406
|
-
);
|
|
74593
|
+
const confidence = finding.confidence.padEnd(CONFIDENCE_COL_WIDTH);
|
|
74407
74594
|
const rawDescription = finding.description.split(".")[0] ?? finding.description;
|
|
74408
74595
|
const description = rawDescription.length > maxDescWidth ? `${rawDescription.slice(0, maxDescWidth - ELLIPSIS_LENGTH)}...` : rawDescription;
|
|
74409
74596
|
return `${flow} ${triggerType} ${confidence} ${description}${suffix ? source_default.dim(suffix) : ""}`;
|
|
@@ -74417,10 +74604,8 @@ function printDetail(finding) {
|
|
|
74417
74604
|
process.stdout.write(` ${String(index + 1)}. ${step}
|
|
74418
74605
|
`);
|
|
74419
74606
|
}
|
|
74420
|
-
process.stdout.write(
|
|
74421
|
-
|
|
74422
|
-
`
|
|
74423
|
-
);
|
|
74607
|
+
process.stdout.write(`${source_default.bold("\nConfidence: ")}${finding.confidence}
|
|
74608
|
+
`);
|
|
74424
74609
|
if (finding.screenshots.length > 0) {
|
|
74425
74610
|
process.stdout.write(source_default.bold("\nScreenshots:\n"));
|
|
74426
74611
|
for (const screenshot of finding.screenshots) {
|
|
@@ -74444,15 +74629,15 @@ async function runInteractiveLoop(findings, existing) {
|
|
|
74444
74629
|
}
|
|
74445
74630
|
return { staged: state.staged, undoneKeys: state.undoneKeys };
|
|
74446
74631
|
}
|
|
74447
|
-
var safeRunInteractiveLoop = (0,
|
|
74632
|
+
var safeRunInteractiveLoop = (0, import_neverthrow42.fromAsyncThrowable)(
|
|
74448
74633
|
runInteractiveLoop,
|
|
74449
74634
|
(error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "exit-prompt" : "unexpected"
|
|
74450
74635
|
);
|
|
74451
74636
|
|
|
74452
74637
|
// src/commands/review-command.ts
|
|
74453
|
-
var safeReadFile3 = (0,
|
|
74454
|
-
var safeParseJson3 = (0,
|
|
74455
|
-
var safeWrite = (0,
|
|
74638
|
+
var safeReadFile3 = (0, import_neverthrow43.fromThrowable)((filePath) => (0, import_node_fs7.readFileSync)(filePath, "utf8"));
|
|
74639
|
+
var safeParseJson3 = (0, import_neverthrow43.fromThrowable)(JSON.parse);
|
|
74640
|
+
var safeWrite = (0, import_neverthrow43.fromThrowable)((filePath, content) => {
|
|
74456
74641
|
(0, import_node_fs7.writeFileSync)(filePath, content);
|
|
74457
74642
|
});
|
|
74458
74643
|
function readLastPath(xqaDirectory) {
|
|
@@ -74469,13 +74654,13 @@ function isPipelineOutput(data) {
|
|
|
74469
74654
|
function readFindings(filePath) {
|
|
74470
74655
|
const readResult = safeReadFile3(filePath);
|
|
74471
74656
|
if (readResult.isErr()) {
|
|
74472
|
-
return (0,
|
|
74657
|
+
return (0, import_neverthrow43.err)("not-found");
|
|
74473
74658
|
}
|
|
74474
74659
|
return safeParseJson3(readResult.value).mapErr(() => "invalid").andThen((data) => {
|
|
74475
74660
|
if (!isPipelineOutput(data)) {
|
|
74476
|
-
return (0,
|
|
74661
|
+
return (0, import_neverthrow43.err)("invalid");
|
|
74477
74662
|
}
|
|
74478
|
-
return (0,
|
|
74663
|
+
return (0, import_neverthrow43.ok)(data);
|
|
74479
74664
|
});
|
|
74480
74665
|
}
|
|
74481
74666
|
function loadExistingDismissals(filePath) {
|
|
@@ -74548,7 +74733,7 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
|
|
|
74548
74733
|
"No findings path provided and no last path found. Run: xqa review <findings-path>\n"
|
|
74549
74734
|
);
|
|
74550
74735
|
process.exit(1);
|
|
74551
|
-
return (0,
|
|
74736
|
+
return (0, import_neverthrow43.err)();
|
|
74552
74737
|
}
|
|
74553
74738
|
const resolvedPath = resolvedPathResult.value;
|
|
74554
74739
|
const findingsResult = readFindings(resolvedPath);
|
|
@@ -74561,9 +74746,9 @@ function resolveAndReadFindings(findingsPath, xqaDirectory) {
|
|
|
74561
74746
|
`);
|
|
74562
74747
|
}
|
|
74563
74748
|
process.exit(1);
|
|
74564
|
-
return (0,
|
|
74749
|
+
return (0, import_neverthrow43.err)();
|
|
74565
74750
|
}
|
|
74566
|
-
return (0,
|
|
74751
|
+
return (0, import_neverthrow43.ok)({ resolvedPath, output: findingsResult.value });
|
|
74567
74752
|
}
|
|
74568
74753
|
async function runReviewLoop({
|
|
74569
74754
|
findings,
|
|
@@ -74591,7 +74776,7 @@ async function executeReview({
|
|
|
74591
74776
|
return;
|
|
74592
74777
|
}
|
|
74593
74778
|
const dismissalsFilePath = dismissalsPath(
|
|
74594
|
-
|
|
74779
|
+
import_node_path15.default.dirname(xqaDirectory),
|
|
74595
74780
|
process.env.QA_DISMISSALS_PATH
|
|
74596
74781
|
);
|
|
74597
74782
|
await runReviewLoop({
|
|
@@ -74614,16 +74799,16 @@ async function runReviewCommand(findingsPath, xqaDirectory) {
|
|
|
74614
74799
|
}
|
|
74615
74800
|
|
|
74616
74801
|
// src/commands/spec-command.ts
|
|
74617
|
-
var
|
|
74802
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
74618
74803
|
|
|
74619
74804
|
// src/spec-slug.ts
|
|
74620
|
-
var
|
|
74805
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
74621
74806
|
var SPECS_DIR = "specs";
|
|
74622
74807
|
function stripExtensions(filename) {
|
|
74623
74808
|
return filename.replace(/\.test\.md$/, "").replace(/\.[^.]+$/, "");
|
|
74624
74809
|
}
|
|
74625
74810
|
function deriveSpecSlug(specFilePath) {
|
|
74626
|
-
const parts = specFilePath.split(
|
|
74811
|
+
const parts = specFilePath.split(import_node_path16.default.sep);
|
|
74627
74812
|
const specsIndex = parts.lastIndexOf(SPECS_DIR);
|
|
74628
74813
|
if (specsIndex !== -1) {
|
|
74629
74814
|
const relativeParts = parts.slice(specsIndex + 1);
|
|
@@ -74631,17 +74816,17 @@ function deriveSpecSlug(specFilePath) {
|
|
|
74631
74816
|
relativeParts[relativeParts.length - 1] = stripExtensions(last);
|
|
74632
74817
|
return relativeParts.join("__");
|
|
74633
74818
|
}
|
|
74634
|
-
return stripExtensions(
|
|
74819
|
+
return stripExtensions(import_node_path16.default.basename(specFilePath));
|
|
74635
74820
|
}
|
|
74636
74821
|
|
|
74637
74822
|
// src/commands/spec-resolver.ts
|
|
74638
74823
|
var import_node_fs8 = require("node:fs");
|
|
74639
|
-
var
|
|
74640
|
-
var
|
|
74824
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
74825
|
+
var import_neverthrow45 = __toESM(require_index_cjs(), 1);
|
|
74641
74826
|
|
|
74642
74827
|
// src/spec-frontmatter.ts
|
|
74643
74828
|
var import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
74644
|
-
var
|
|
74829
|
+
var import_neverthrow44 = __toESM(require_index_cjs(), 1);
|
|
74645
74830
|
|
|
74646
74831
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
74647
74832
|
var external_exports2 = {};
|
|
@@ -75381,8 +75566,8 @@ var ZodType2 = class {
|
|
|
75381
75566
|
} : {
|
|
75382
75567
|
issues: ctx.common.issues
|
|
75383
75568
|
};
|
|
75384
|
-
} catch (
|
|
75385
|
-
if (
|
|
75569
|
+
} catch (err26) {
|
|
75570
|
+
if (err26?.message?.toLowerCase()?.includes("encountered")) {
|
|
75386
75571
|
this["~standard"].async = true;
|
|
75387
75572
|
}
|
|
75388
75573
|
ctx.common = {
|
|
@@ -78689,45 +78874,45 @@ var frontmatterSchema = external_exports2.object({
|
|
|
78689
78874
|
feature: external_exports2.string().min(1),
|
|
78690
78875
|
timeout: external_exports2.number().int().positive().optional()
|
|
78691
78876
|
});
|
|
78692
|
-
var safeParseMatter = (0,
|
|
78877
|
+
var safeParseMatter = (0, import_neverthrow44.fromThrowable)(
|
|
78693
78878
|
import_gray_matter.default,
|
|
78694
78879
|
(cause) => ({ type: "SPEC_FRONTMATTER_INVALID", cause })
|
|
78695
78880
|
);
|
|
78696
78881
|
function validate(data) {
|
|
78697
78882
|
const parsed = frontmatterSchema.safeParse(data);
|
|
78698
78883
|
if (!parsed.success) {
|
|
78699
|
-
return (0,
|
|
78884
|
+
return (0, import_neverthrow44.err)({ type: "SPEC_FRONTMATTER_INVALID", cause: parsed.error });
|
|
78700
78885
|
}
|
|
78701
78886
|
const { feature, timeout } = parsed.data;
|
|
78702
78887
|
if (timeout === void 0) {
|
|
78703
|
-
return (0,
|
|
78888
|
+
return (0, import_neverthrow44.ok)({ feature });
|
|
78704
78889
|
}
|
|
78705
|
-
return (0,
|
|
78890
|
+
return (0, import_neverthrow44.ok)({ feature, timeoutSeconds: timeout });
|
|
78706
78891
|
}
|
|
78707
78892
|
function parseSpecFrontmatter(raw) {
|
|
78708
78893
|
return safeParseMatter(raw).andThen((parsed) => validate(parsed.data));
|
|
78709
78894
|
}
|
|
78710
78895
|
|
|
78711
78896
|
// src/commands/spec-resolver.ts
|
|
78712
|
-
var safeReadFile4 = (0,
|
|
78713
|
-
var safeReaddir = (0,
|
|
78897
|
+
var safeReadFile4 = (0, import_neverthrow45.fromThrowable)((filePath) => (0, import_node_fs8.readFileSync)(filePath, "utf8"));
|
|
78898
|
+
var safeReaddir = (0, import_neverthrow45.fromThrowable)(
|
|
78714
78899
|
(directory) => (0, import_node_fs8.readdirSync)(directory, { recursive: true, encoding: "utf8" })
|
|
78715
78900
|
);
|
|
78716
78901
|
var CANCEL = "xqa:cancel";
|
|
78717
|
-
var safeSelect =
|
|
78902
|
+
var safeSelect = import_neverthrow45.ResultAsync.fromThrowable(
|
|
78718
78903
|
esm_default11,
|
|
78719
78904
|
(error48) => error48 instanceof Error && error48.name === "ExitPromptError" ? "cancelled" : "failed"
|
|
78720
78905
|
);
|
|
78721
78906
|
function findSpecFiles(xqaDirectory) {
|
|
78722
|
-
const specsDirectory =
|
|
78723
|
-
return safeReaddir(specsDirectory).unwrapOr([]).filter((file2) => file2.endsWith(".test.md")).map((file2) =>
|
|
78907
|
+
const specsDirectory = import_node_path17.default.join(xqaDirectory, "specs");
|
|
78908
|
+
return safeReaddir(specsDirectory).unwrapOr([]).filter((file2) => file2.endsWith(".test.md")).map((file2) => import_node_path17.default.join(specsDirectory, file2));
|
|
78724
78909
|
}
|
|
78725
78910
|
async function promptForSpec(specFiles, xqaDirectory) {
|
|
78726
78911
|
const result = await safeSelect({
|
|
78727
78912
|
message: "Select a spec",
|
|
78728
78913
|
choices: [
|
|
78729
78914
|
...specFiles.map((specFile) => ({
|
|
78730
|
-
name:
|
|
78915
|
+
name: import_node_path17.default.relative(xqaDirectory, specFile),
|
|
78731
78916
|
value: specFile
|
|
78732
78917
|
})),
|
|
78733
78918
|
new Separator(),
|
|
@@ -78786,10 +78971,10 @@ function buildSpecExplorer(input, context) {
|
|
|
78786
78971
|
}
|
|
78787
78972
|
function buildPipelineConfig2({ input, context, onEvent }) {
|
|
78788
78973
|
return {
|
|
78789
|
-
outputDir:
|
|
78974
|
+
outputDir: import_node_path18.default.join(context.xqaDirectory, "output", context.slug),
|
|
78790
78975
|
signal: input.signal,
|
|
78791
78976
|
onEvent,
|
|
78792
|
-
inspector: { designsDirectory:
|
|
78977
|
+
inspector: { designsDirectory: import_node_path18.default.join(context.xqaDirectory, "designs") },
|
|
78793
78978
|
explorer: buildSpecExplorer(input, context)
|
|
78794
78979
|
};
|
|
78795
78980
|
}
|
|
@@ -78833,7 +79018,7 @@ async function executeSpec(input, context) {
|
|
|
78833
79018
|
const identity = {
|
|
78834
79019
|
display: createSoloDisplay(input.verbose),
|
|
78835
79020
|
itemId: "spec",
|
|
78836
|
-
itemName:
|
|
79021
|
+
itemName: import_node_path18.default.basename(context.absolutePath, ".test.md"),
|
|
78837
79022
|
simulatorUdid: ""
|
|
78838
79023
|
};
|
|
78839
79024
|
const startedAt = Date.now();
|
|
@@ -78844,7 +79029,7 @@ async function executeSpec(input, context) {
|
|
|
78844
79029
|
};
|
|
78845
79030
|
const onEvent = debugLogger.wrapAgentHandler(baseHandler);
|
|
78846
79031
|
const { onSuccess, onError } = handleSpecResult({ identity, startedAt }, context);
|
|
78847
|
-
const result = await
|
|
79032
|
+
const result = await runPipeline3(buildPipelineConfig2({ input, context, onEvent }));
|
|
78848
79033
|
result.match(onSuccess, onError);
|
|
78849
79034
|
}
|
|
78850
79035
|
function handleAppContextError(error48) {
|
|
@@ -78874,7 +79059,7 @@ async function resolveSpecContext(input, options2) {
|
|
|
78874
79059
|
if (resolvedSpecFile === void 0) {
|
|
78875
79060
|
return;
|
|
78876
79061
|
}
|
|
78877
|
-
const absolutePath =
|
|
79062
|
+
const absolutePath = import_node_path18.default.resolve(resolvedSpecFile);
|
|
78878
79063
|
const frontmatter = readAndParseSpec(absolutePath);
|
|
78879
79064
|
if (frontmatter === void 0) {
|
|
78880
79065
|
return;
|
|
@@ -78895,7 +79080,7 @@ async function runSpecCommand(input, options2) {
|
|
|
78895
79080
|
}
|
|
78896
79081
|
|
|
78897
79082
|
// ../../agents/triager/dist/index.js
|
|
78898
|
-
var
|
|
79083
|
+
var import_neverthrow46 = __toESM(require_index_cjs(), 1);
|
|
78899
79084
|
|
|
78900
79085
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@3.25.76/node_modules/@anthropic-ai/sdk/internal/tslib.mjs
|
|
78901
79086
|
function __classPrivateFieldSet2(receiver, state, value, kind, f6) {
|
|
@@ -78928,34 +79113,34 @@ var uuid43 = function() {
|
|
|
78928
79113
|
};
|
|
78929
79114
|
|
|
78930
79115
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@3.25.76/node_modules/@anthropic-ai/sdk/internal/errors.mjs
|
|
78931
|
-
function isAbortError2(
|
|
78932
|
-
return typeof
|
|
78933
|
-
("name" in
|
|
78934
|
-
"message" in
|
|
78935
|
-
}
|
|
78936
|
-
var castToError2 = (
|
|
78937
|
-
if (
|
|
78938
|
-
return
|
|
78939
|
-
if (typeof
|
|
79116
|
+
function isAbortError2(err26) {
|
|
79117
|
+
return typeof err26 === "object" && err26 !== null && // Spec-compliant fetch implementations
|
|
79118
|
+
("name" in err26 && err26.name === "AbortError" || // Expo fetch
|
|
79119
|
+
"message" in err26 && String(err26.message).includes("FetchRequestCanceledException"));
|
|
79120
|
+
}
|
|
79121
|
+
var castToError2 = (err26) => {
|
|
79122
|
+
if (err26 instanceof Error)
|
|
79123
|
+
return err26;
|
|
79124
|
+
if (typeof err26 === "object" && err26 !== null) {
|
|
78940
79125
|
try {
|
|
78941
|
-
if (Object.prototype.toString.call(
|
|
78942
|
-
const error48 = new Error(
|
|
78943
|
-
if (
|
|
78944
|
-
error48.stack =
|
|
78945
|
-
if (
|
|
78946
|
-
error48.cause =
|
|
78947
|
-
if (
|
|
78948
|
-
error48.name =
|
|
79126
|
+
if (Object.prototype.toString.call(err26) === "[object Error]") {
|
|
79127
|
+
const error48 = new Error(err26.message, err26.cause ? { cause: err26.cause } : {});
|
|
79128
|
+
if (err26.stack)
|
|
79129
|
+
error48.stack = err26.stack;
|
|
79130
|
+
if (err26.cause && !error48.cause)
|
|
79131
|
+
error48.cause = err26.cause;
|
|
79132
|
+
if (err26.name)
|
|
79133
|
+
error48.name = err26.name;
|
|
78949
79134
|
return error48;
|
|
78950
79135
|
}
|
|
78951
79136
|
} catch {
|
|
78952
79137
|
}
|
|
78953
79138
|
try {
|
|
78954
|
-
return new Error(JSON.stringify(
|
|
79139
|
+
return new Error(JSON.stringify(err26));
|
|
78955
79140
|
} catch {
|
|
78956
79141
|
}
|
|
78957
79142
|
}
|
|
78958
|
-
return new Error(
|
|
79143
|
+
return new Error(err26);
|
|
78959
79144
|
};
|
|
78960
79145
|
|
|
78961
79146
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.87.0_zod@3.25.76/node_modules/@anthropic-ai/sdk/core/error.mjs
|
|
@@ -79085,7 +79270,7 @@ var validatePositiveInteger2 = (name, n3) => {
|
|
|
79085
79270
|
var safeJSON2 = (text) => {
|
|
79086
79271
|
try {
|
|
79087
79272
|
return JSON.parse(text);
|
|
79088
|
-
} catch (
|
|
79273
|
+
} catch (err26) {
|
|
79089
79274
|
return void 0;
|
|
79090
79275
|
}
|
|
79091
79276
|
};
|
|
@@ -79649,8 +79834,8 @@ var Stream2 = class _Stream {
|
|
|
79649
79834
|
return ctrl.close();
|
|
79650
79835
|
const bytes = encodeUTF82(JSON.stringify(value) + "\n");
|
|
79651
79836
|
ctrl.enqueue(bytes);
|
|
79652
|
-
} catch (
|
|
79653
|
-
ctrl.error(
|
|
79837
|
+
} catch (err26) {
|
|
79838
|
+
ctrl.error(err26);
|
|
79654
79839
|
}
|
|
79655
79840
|
},
|
|
79656
79841
|
async cancel() {
|
|
@@ -81557,8 +81742,8 @@ var BetaMessageStream2 = class _BetaMessageStream {
|
|
|
81557
81742
|
if (jsonBuf) {
|
|
81558
81743
|
try {
|
|
81559
81744
|
newContent.input = partialParse2(jsonBuf);
|
|
81560
|
-
} catch (
|
|
81561
|
-
const error48 = new AnthropicError2(`Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: ${
|
|
81745
|
+
} catch (err26) {
|
|
81746
|
+
const error48 = new AnthropicError2(`Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: ${err26}. JSON: ${jsonBuf}`);
|
|
81562
81747
|
__classPrivateFieldGet2(this, _BetaMessageStream_handleError2, "f").call(this, error48);
|
|
81563
81748
|
}
|
|
81564
81749
|
}
|
|
@@ -81620,17 +81805,17 @@ var BetaMessageStream2 = class _BetaMessageStream {
|
|
|
81620
81805
|
}
|
|
81621
81806
|
readQueue.length = 0;
|
|
81622
81807
|
});
|
|
81623
|
-
this.on("abort", (
|
|
81808
|
+
this.on("abort", (err26) => {
|
|
81624
81809
|
done = true;
|
|
81625
81810
|
for (const reader of readQueue) {
|
|
81626
|
-
reader.reject(
|
|
81811
|
+
reader.reject(err26);
|
|
81627
81812
|
}
|
|
81628
81813
|
readQueue.length = 0;
|
|
81629
81814
|
});
|
|
81630
|
-
this.on("error", (
|
|
81815
|
+
this.on("error", (err26) => {
|
|
81631
81816
|
done = true;
|
|
81632
81817
|
for (const reader of readQueue) {
|
|
81633
|
-
reader.reject(
|
|
81818
|
+
reader.reject(err26);
|
|
81634
81819
|
}
|
|
81635
81820
|
readQueue.length = 0;
|
|
81636
81821
|
});
|
|
@@ -83873,17 +84058,17 @@ var MessageStream2 = class _MessageStream {
|
|
|
83873
84058
|
}
|
|
83874
84059
|
readQueue.length = 0;
|
|
83875
84060
|
});
|
|
83876
|
-
this.on("abort", (
|
|
84061
|
+
this.on("abort", (err26) => {
|
|
83877
84062
|
done = true;
|
|
83878
84063
|
for (const reader of readQueue) {
|
|
83879
|
-
reader.reject(
|
|
84064
|
+
reader.reject(err26);
|
|
83880
84065
|
}
|
|
83881
84066
|
readQueue.length = 0;
|
|
83882
84067
|
});
|
|
83883
|
-
this.on("error", (
|
|
84068
|
+
this.on("error", (err26) => {
|
|
83884
84069
|
done = true;
|
|
83885
84070
|
for (const reader of readQueue) {
|
|
83886
|
-
reader.reject(
|
|
84071
|
+
reader.reject(err26);
|
|
83887
84072
|
}
|
|
83888
84073
|
readQueue.length = 0;
|
|
83889
84074
|
});
|
|
@@ -84463,7 +84648,7 @@ var BaseAnthropic2 = class {
|
|
|
84463
84648
|
}
|
|
84464
84649
|
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
84465
84650
|
loggerFor2(this).info(`${responseInfo} - ${retryMessage}`);
|
|
84466
|
-
const errText = await response.text().catch((
|
|
84651
|
+
const errText = await response.text().catch((err27) => castToError2(err27).message);
|
|
84467
84652
|
const errJSON = safeJSON2(errText);
|
|
84468
84653
|
const errMessage = errJSON ? void 0 : errText;
|
|
84469
84654
|
loggerFor2(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails2({
|
|
@@ -84474,8 +84659,8 @@ var BaseAnthropic2 = class {
|
|
|
84474
84659
|
message: errMessage,
|
|
84475
84660
|
durationMs: Date.now() - startTime
|
|
84476
84661
|
}));
|
|
84477
|
-
const
|
|
84478
|
-
throw
|
|
84662
|
+
const err26 = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
84663
|
+
throw err26;
|
|
84479
84664
|
}
|
|
84480
84665
|
loggerFor2(this).info(responseInfo);
|
|
84481
84666
|
loggerFor2(this).debug(`[${requestLogID}] response start`, formatRequestDetails2({
|
|
@@ -84686,7 +84871,7 @@ Anthropic2.Models = Models4;
|
|
|
84686
84871
|
Anthropic2.Beta = Beta2;
|
|
84687
84872
|
|
|
84688
84873
|
// ../../agents/triager/dist/index.js
|
|
84689
|
-
var
|
|
84874
|
+
var import_neverthrow47 = __toESM(require_index_cjs(), 1);
|
|
84690
84875
|
|
|
84691
84876
|
// ../../node_modules/.pnpm/balanced-match@4.0.4/node_modules/balanced-match/dist/esm/index.js
|
|
84692
84877
|
var balanced = (a3, b, str3) => {
|
|
@@ -86492,16 +86677,16 @@ minimatch.unescape = unescape2;
|
|
|
86492
86677
|
|
|
86493
86678
|
// ../../agents/triager/dist/index.js
|
|
86494
86679
|
var MAX_TOKENS3 = 1024;
|
|
86680
|
+
var THINKING_BUDGET_TOKENS = 1024;
|
|
86495
86681
|
var TEMPERATURE3 = 0;
|
|
86496
86682
|
var TOOL_NAME = "select_test_groups";
|
|
86683
|
+
var pickSchema = external_exports2.object({
|
|
86684
|
+
groupId: external_exports2.string(),
|
|
86685
|
+
reason: external_exports2.string(),
|
|
86686
|
+
confidence: external_exports2.enum(["HIGH", "MEDIUM", "LOW"])
|
|
86687
|
+
});
|
|
86497
86688
|
var toolInputSchema = external_exports2.object({
|
|
86498
|
-
picks: external_exports2.array(
|
|
86499
|
-
external_exports2.object({
|
|
86500
|
-
groupId: external_exports2.string(),
|
|
86501
|
-
score: external_exports2.number(),
|
|
86502
|
-
reason: external_exports2.string()
|
|
86503
|
-
})
|
|
86504
|
-
)
|
|
86689
|
+
picks: external_exports2.array(pickSchema)
|
|
86505
86690
|
});
|
|
86506
86691
|
var TOOL_DEFINITION = {
|
|
86507
86692
|
name: TOOL_NAME,
|
|
@@ -86515,16 +86700,17 @@ var TOOL_DEFINITION = {
|
|
|
86515
86700
|
type: "object",
|
|
86516
86701
|
properties: {
|
|
86517
86702
|
groupId: { type: "string" },
|
|
86518
|
-
|
|
86519
|
-
|
|
86703
|
+
reason: { type: "string" },
|
|
86704
|
+
confidence: { type: "string", enum: ["HIGH", "MEDIUM", "LOW"] }
|
|
86520
86705
|
},
|
|
86521
|
-
required: ["groupId", "
|
|
86706
|
+
required: ["groupId", "reason", "confidence"]
|
|
86522
86707
|
}
|
|
86523
86708
|
}
|
|
86524
86709
|
},
|
|
86525
86710
|
required: ["picks"]
|
|
86526
86711
|
}
|
|
86527
86712
|
};
|
|
86713
|
+
var GRADER_SYSTEM_PROMPT = "Act as a senior QA auditor reviewing another engineer's test selection. For each pick below, confirm HIGH, confirm MEDIUM, or downgrade to LOW. Require citing the file path driving your verdict. Respond via the select_test_groups tool.";
|
|
86528
86714
|
function findToolUseInput(response) {
|
|
86529
86715
|
const block = response.content.find((entry) => entry.type === "tool_use");
|
|
86530
86716
|
if (block?.type !== "tool_use") {
|
|
@@ -86538,63 +86724,79 @@ function serialiseResponse(response) {
|
|
|
86538
86724
|
function parseToolResponse(response) {
|
|
86539
86725
|
const input = findToolUseInput(response);
|
|
86540
86726
|
if (input === void 0) {
|
|
86541
|
-
return (0,
|
|
86727
|
+
return (0, import_neverthrow47.err)({ type: "AI_INVALID_RESPONSE", raw: serialiseResponse(response) });
|
|
86542
86728
|
}
|
|
86543
86729
|
const parsed = toolInputSchema.safeParse(input);
|
|
86544
86730
|
if (!parsed.success) {
|
|
86545
|
-
return (0,
|
|
86731
|
+
return (0, import_neverthrow47.err)({ type: "AI_INVALID_RESPONSE", raw: JSON.stringify(input) });
|
|
86546
86732
|
}
|
|
86547
|
-
return (0,
|
|
86733
|
+
return (0, import_neverthrow47.ok)(parsed.data.picks);
|
|
86734
|
+
}
|
|
86735
|
+
function filterKnownGroupIds(picks, validGroupIds) {
|
|
86736
|
+
const validIds = new Set(validGroupIds);
|
|
86737
|
+
return picks.filter((pick2) => validIds.has(pick2.groupId));
|
|
86548
86738
|
}
|
|
86549
86739
|
async function fetchSelection(options2) {
|
|
86550
|
-
const { anthropic, prompt, model } = options2;
|
|
86551
|
-
|
|
86740
|
+
const { anthropic, prompt, model, systemPrompt } = options2;
|
|
86741
|
+
const base = {
|
|
86552
86742
|
model,
|
|
86553
86743
|
max_tokens: MAX_TOKENS3,
|
|
86554
86744
|
temperature: TEMPERATURE3,
|
|
86745
|
+
thinking: { type: "enabled", budget_tokens: THINKING_BUDGET_TOKENS },
|
|
86555
86746
|
tools: [TOOL_DEFINITION],
|
|
86556
86747
|
tool_choice: { type: "tool", name: TOOL_NAME },
|
|
86557
86748
|
messages: [{ role: "user", content: prompt }]
|
|
86558
|
-
}
|
|
86749
|
+
};
|
|
86750
|
+
if (systemPrompt !== void 0) {
|
|
86751
|
+
return anthropic.messages.create({ ...base, system: systemPrompt });
|
|
86752
|
+
}
|
|
86753
|
+
return anthropic.messages.create(base);
|
|
86754
|
+
}
|
|
86755
|
+
function buildGraderPrompt(originalPicks, basePrompt) {
|
|
86756
|
+
const picksText = originalPicks.map((pick2) => `- groupId: ${pick2.groupId}
|
|
86757
|
+
reason: ${pick2.reason}`).join("\n");
|
|
86758
|
+
return `${basePrompt}
|
|
86759
|
+
|
|
86760
|
+
## Picks Under Review
|
|
86761
|
+
|
|
86762
|
+
${picksText}`;
|
|
86559
86763
|
}
|
|
86560
86764
|
function selectGroups(options2) {
|
|
86561
86765
|
const anthropic = new Anthropic2({ apiKey: options2.apiKey });
|
|
86562
|
-
return (0,
|
|
86766
|
+
return (0, import_neverthrow47.fromAsyncThrowable)(
|
|
86563
86767
|
fetchSelection,
|
|
86564
86768
|
(cause) => ({ type: "AI_CALL_FAILED", cause })
|
|
86565
|
-
)({ anthropic, prompt: options2.prompt, model: options2.model }).andThen(parseToolResponse);
|
|
86769
|
+
)({ anthropic, prompt: options2.prompt, model: options2.model }).andThen(parseToolResponse).map((picks) => filterKnownGroupIds(picks, options2.validGroupIds));
|
|
86566
86770
|
}
|
|
86567
|
-
|
|
86568
|
-
|
|
86569
|
-
|
|
86771
|
+
function graderSelectGroups(options2) {
|
|
86772
|
+
const anthropic = new Anthropic2({ apiKey: options2.apiKey });
|
|
86773
|
+
const graderPrompt = buildGraderPrompt(options2.originalPicks, options2.prompt);
|
|
86774
|
+
return (0, import_neverthrow47.fromAsyncThrowable)(
|
|
86775
|
+
fetchSelection,
|
|
86776
|
+
(cause) => ({ type: "AI_CALL_FAILED", cause })
|
|
86777
|
+
)({ anthropic, prompt: graderPrompt, model: options2.model, systemPrompt: GRADER_SYSTEM_PROMPT }).andThen(parseToolResponse).map((picks) => filterKnownGroupIds(picks, options2.validGroupIds));
|
|
86778
|
+
}
|
|
86779
|
+
function resolveConfidence2(selected) {
|
|
86780
|
+
if (selected.some((pick2) => pick2.confidence === "HIGH")) {
|
|
86570
86781
|
return "high";
|
|
86571
86782
|
}
|
|
86572
|
-
if (selected.
|
|
86783
|
+
if (selected.some((pick2) => pick2.confidence === "MEDIUM")) {
|
|
86573
86784
|
return "medium";
|
|
86574
86785
|
}
|
|
86575
86786
|
return "low";
|
|
86576
86787
|
}
|
|
86577
|
-
function buildDecision(picks
|
|
86578
|
-
const selected = picks.filter((pick2) => pick2.
|
|
86579
|
-
const skipped = picks.filter((pick2) => pick2.
|
|
86788
|
+
function buildDecision(picks) {
|
|
86789
|
+
const selected = picks.filter((pick2) => pick2.confidence !== "LOW");
|
|
86790
|
+
const skipped = picks.filter((pick2) => pick2.confidence === "LOW");
|
|
86580
86791
|
return {
|
|
86581
86792
|
picks: selected,
|
|
86582
86793
|
skipped,
|
|
86583
|
-
confidence:
|
|
86794
|
+
confidence: resolveConfidence2(selected)
|
|
86584
86795
|
};
|
|
86585
86796
|
}
|
|
86586
|
-
var
|
|
86587
|
-
var
|
|
86797
|
+
var HIGH_MATCH_RATIO = 0.7;
|
|
86798
|
+
var MEDIUM_MATCH_RATIO = 0.3;
|
|
86588
86799
|
var REASON_SAMPLE_LIMIT = 3;
|
|
86589
|
-
function clampScore(value) {
|
|
86590
|
-
if (value < MIN_SCORE) {
|
|
86591
|
-
return MIN_SCORE;
|
|
86592
|
-
}
|
|
86593
|
-
if (value > MAX_SCORE) {
|
|
86594
|
-
return MAX_SCORE;
|
|
86595
|
-
}
|
|
86596
|
-
return value;
|
|
86597
|
-
}
|
|
86598
86800
|
function matchesAnyGlob(path27, patterns) {
|
|
86599
86801
|
return patterns.some((pattern) => minimatch(path27, pattern));
|
|
86600
86802
|
}
|
|
@@ -86605,6 +86807,19 @@ function formatReason(parts) {
|
|
|
86605
86807
|
const sample = parts.paths.slice(0, REASON_SAMPLE_LIMIT).join(", ");
|
|
86606
86808
|
return `matched ${String(parts.matches)}/${String(parts.total)} files: ${sample}`;
|
|
86607
86809
|
}
|
|
86810
|
+
function resolvePickConfidence(matches, total) {
|
|
86811
|
+
if (total === 0 || matches === 0) {
|
|
86812
|
+
return void 0;
|
|
86813
|
+
}
|
|
86814
|
+
const ratio = matches / total;
|
|
86815
|
+
if (ratio >= HIGH_MATCH_RATIO) {
|
|
86816
|
+
return "HIGH";
|
|
86817
|
+
}
|
|
86818
|
+
if (ratio >= MEDIUM_MATCH_RATIO) {
|
|
86819
|
+
return "MEDIUM";
|
|
86820
|
+
}
|
|
86821
|
+
return "LOW";
|
|
86822
|
+
}
|
|
86608
86823
|
function scoreGroup(diff, group) {
|
|
86609
86824
|
if (!group.covers || group.covers.length === 0) {
|
|
86610
86825
|
return void 0;
|
|
@@ -86612,28 +86827,62 @@ function scoreGroup(diff, group) {
|
|
|
86612
86827
|
const total = diff.files.length;
|
|
86613
86828
|
const matchingPaths = collectMatchingPaths(diff, group.covers);
|
|
86614
86829
|
const matches = matchingPaths.length;
|
|
86615
|
-
const
|
|
86830
|
+
const confidence = resolvePickConfidence(matches, total);
|
|
86831
|
+
if (confidence === void 0) {
|
|
86832
|
+
return void 0;
|
|
86833
|
+
}
|
|
86616
86834
|
return {
|
|
86617
86835
|
groupId: group.id,
|
|
86618
|
-
|
|
86836
|
+
confidence,
|
|
86619
86837
|
reason: formatReason({ matches, total, paths: matchingPaths })
|
|
86620
86838
|
};
|
|
86621
86839
|
}
|
|
86622
86840
|
function scoreGroups(diff, groups) {
|
|
86623
86841
|
return groups.map((group) => scoreGroup(diff, group)).filter((pick2) => pick2 !== void 0);
|
|
86624
86842
|
}
|
|
86625
|
-
var
|
|
86843
|
+
var MAX_BODY_CHARS = 400;
|
|
86844
|
+
var HEADER = `You are a QA engineer selecting which test groups to run against a pull request. Each group covers a product surface. Err toward inclusion \u2014 a missed regression is far worse than wasted CI minutes.`;
|
|
86626
86845
|
var INSTRUCTIONS = `Call the \`select_test_groups\` tool with an array of picks. For each selected group include:
|
|
86627
|
-
- \`groupId\`:
|
|
86628
|
-
- \`
|
|
86629
|
-
- \`
|
|
86846
|
+
- \`groupId\`: an id that appears verbatim in the Test Groups list below \u2014 do not invent, paraphrase, or infer ids
|
|
86847
|
+
- \`reason\`: cite the specific file path(s) and which \`covers\` glob or heuristic matched; write the reason first; only then commit to HIGH/MEDIUM/LOW
|
|
86848
|
+
- \`confidence\`: label using the rubric below
|
|
86849
|
+
|
|
86850
|
+
If no group is relevant, call the tool with \`picks: []\`.
|
|
86851
|
+
|
|
86852
|
+
### Confidence rubric
|
|
86853
|
+
|
|
86854
|
+
- HIGH: change clearly exercises this group \u2014 changed files are the primary implementation or directly call/are called by covered paths
|
|
86855
|
+
- MEDIUM: shared dependency or indirect but plausible \u2014 change modifies a shared dependency of covered paths or has a tangential but credible relationship
|
|
86856
|
+
- LOW: tangential \u2014 the heuristics would force inclusion but only as a safety net
|
|
86857
|
+
|
|
86858
|
+
### Selection heuristics
|
|
86859
|
+
|
|
86860
|
+
- Config or infra changes (\`*.yaml\`, \`*.json\`, \`Dockerfile\`, \`*.tf\`) fan out broadly \u2014 include integration and e2e groups
|
|
86861
|
+
- Shared utility changes (\`**/core/**\`, \`**/utils/**\`, \`**/shared/**\`) fan out to consumers \u2014 include every group that depends on them
|
|
86862
|
+
- Doc-only changes (\`*.md\`, \`*.mdx\`, \`docs/**\`) \u2014 return empty picks
|
|
86863
|
+
- Test-only changes (\`*.test.*\`, \`__tests__/**\`) \u2014 skip execution groups unless production code in the same diff requires them
|
|
86864
|
+
- Breaking API changes (deleted exports, renamed public types) \u2014 include every group (full regression)
|
|
86865
|
+
- Deleted files \u2014 groups that covered the deleted path must still run to verify no breakage
|
|
86866
|
+
|
|
86867
|
+
### Process
|
|
86868
|
+
|
|
86869
|
+
Before emitting picks, list the changed areas, then match each to candidate groups. If two groups overlap on the same file, include both and give the more specific one a higher confidence. When uncertain, include the group.`;
|
|
86630
86870
|
function formatFile(file2) {
|
|
86631
|
-
|
|
86871
|
+
const hunkCount = file2.hunks?.length ?? 0;
|
|
86872
|
+
const hunkSuffix = hunkCount > 0 ? ` (${String(hunkCount)} hunk(s))` : "";
|
|
86873
|
+
return `- [${file2.status}] ${file2.path}${hunkSuffix}`;
|
|
86874
|
+
}
|
|
86875
|
+
function formatBody(body) {
|
|
86876
|
+
if (!body) {
|
|
86877
|
+
return "Body: (none)";
|
|
86878
|
+
}
|
|
86879
|
+
const trimmed = body.length > MAX_BODY_CHARS ? `${body.slice(0, MAX_BODY_CHARS)}\u2026` : body;
|
|
86880
|
+
return `Body:
|
|
86881
|
+
${trimmed}`;
|
|
86632
86882
|
}
|
|
86633
86883
|
function formatDiffSection(diff) {
|
|
86634
86884
|
const title = diff.title ? `Title: ${diff.title}` : "Title: (none)";
|
|
86635
|
-
const body = diff.body
|
|
86636
|
-
${diff.body}` : "Body: (none)";
|
|
86885
|
+
const body = formatBody(diff.body);
|
|
86637
86886
|
const files = diff.files.map((file2) => formatFile(file2)).join("\n");
|
|
86638
86887
|
return `${title}
|
|
86639
86888
|
${body}
|
|
@@ -86659,20 +86908,40 @@ function formatGroupsSection(groups) {
|
|
|
86659
86908
|
function buildTriagerPrompt(diff, groups) {
|
|
86660
86909
|
return `${HEADER}
|
|
86661
86910
|
|
|
86911
|
+
## Instructions
|
|
86912
|
+
|
|
86913
|
+
${INSTRUCTIONS}
|
|
86914
|
+
|
|
86662
86915
|
## Change
|
|
86663
86916
|
|
|
86664
86917
|
${formatDiffSection(diff)}
|
|
86665
86918
|
|
|
86666
86919
|
## Test Groups
|
|
86667
86920
|
|
|
86668
|
-
${formatGroupsSection(groups)}
|
|
86669
|
-
|
|
86670
|
-
## Instructions
|
|
86671
|
-
|
|
86672
|
-
${INSTRUCTIONS}`;
|
|
86921
|
+
${formatGroupsSection(groups)}`;
|
|
86673
86922
|
}
|
|
86674
86923
|
var DEFAULT_MODEL2 = "claude-opus-4-6";
|
|
86675
|
-
var
|
|
86924
|
+
var CONFIDENCE_RANK = {
|
|
86925
|
+
HIGH: 2,
|
|
86926
|
+
MEDIUM: 1,
|
|
86927
|
+
LOW: 0
|
|
86928
|
+
};
|
|
86929
|
+
function applyGraderResults(mediumPicks, graderPicks) {
|
|
86930
|
+
const graderById = /* @__PURE__ */ new Map();
|
|
86931
|
+
for (const pick2 of graderPicks) {
|
|
86932
|
+
graderById.set(pick2.groupId, pick2);
|
|
86933
|
+
}
|
|
86934
|
+
return mediumPicks.flatMap((pick2) => {
|
|
86935
|
+
const graderResult = graderById.get(pick2.groupId);
|
|
86936
|
+
if (graderResult === void 0) {
|
|
86937
|
+
return [pick2];
|
|
86938
|
+
}
|
|
86939
|
+
if (graderResult.confidence === "LOW") {
|
|
86940
|
+
return [];
|
|
86941
|
+
}
|
|
86942
|
+
return [graderResult];
|
|
86943
|
+
});
|
|
86944
|
+
}
|
|
86676
86945
|
function buildContext2(options2) {
|
|
86677
86946
|
const { diff, groups, config: config3 } = options2;
|
|
86678
86947
|
return {
|
|
@@ -86680,10 +86949,27 @@ function buildContext2(options2) {
|
|
|
86680
86949
|
groups,
|
|
86681
86950
|
apiKey: config3?.apiKey ?? "",
|
|
86682
86951
|
model: config3?.model ?? DEFAULT_MODEL2,
|
|
86683
|
-
threshold: config3?.scoreThreshold ?? DEFAULT_SCORE_THRESHOLD,
|
|
86684
86952
|
useAi: config3?.useAi ?? true
|
|
86685
86953
|
};
|
|
86686
86954
|
}
|
|
86955
|
+
function mapAiError(error48) {
|
|
86956
|
+
switch (error48.type) {
|
|
86957
|
+
case "AI_CALL_FAILED": {
|
|
86958
|
+
return { type: "AI_CALL_FAILED", cause: error48.cause };
|
|
86959
|
+
}
|
|
86960
|
+
case "AI_INVALID_RESPONSE": {
|
|
86961
|
+
return { type: "AI_INVALID_RESPONSE", raw: error48.raw };
|
|
86962
|
+
}
|
|
86963
|
+
}
|
|
86964
|
+
}
|
|
86965
|
+
function mergePickPair(existing, incoming) {
|
|
86966
|
+
const existingRank = CONFIDENCE_RANK[existing.confidence];
|
|
86967
|
+
const incomingRank = CONFIDENCE_RANK[incoming.confidence];
|
|
86968
|
+
if (incomingRank > existingRank) {
|
|
86969
|
+
return incoming;
|
|
86970
|
+
}
|
|
86971
|
+
return existing;
|
|
86972
|
+
}
|
|
86687
86973
|
function mergePicks(staticPicks, aiPicks) {
|
|
86688
86974
|
const byId = /* @__PURE__ */ new Map();
|
|
86689
86975
|
for (const pick2 of staticPicks) {
|
|
@@ -86691,48 +86977,64 @@ function mergePicks(staticPicks, aiPicks) {
|
|
|
86691
86977
|
}
|
|
86692
86978
|
for (const pick2 of aiPicks) {
|
|
86693
86979
|
const existing = byId.get(pick2.groupId);
|
|
86694
|
-
if (
|
|
86980
|
+
if (existing === void 0) {
|
|
86695
86981
|
byId.set(pick2.groupId, pick2);
|
|
86982
|
+
} else {
|
|
86983
|
+
byId.set(pick2.groupId, mergePickPair(existing, pick2));
|
|
86696
86984
|
}
|
|
86697
86985
|
}
|
|
86698
86986
|
return [...byId.values()];
|
|
86699
86987
|
}
|
|
86988
|
+
function runGraderPass(options2) {
|
|
86989
|
+
const { context, prompt, mediumPicks, highPicks, skippedPicks } = options2;
|
|
86990
|
+
const validGroupIds = context.groups.map((group) => group.id);
|
|
86991
|
+
return graderSelectGroups({
|
|
86992
|
+
prompt,
|
|
86993
|
+
apiKey: context.apiKey,
|
|
86994
|
+
model: context.model,
|
|
86995
|
+
validGroupIds,
|
|
86996
|
+
originalPicks: mediumPicks
|
|
86997
|
+
}).mapErr(mapAiError).map((graderPicks) => {
|
|
86998
|
+
const survivingMedium = applyGraderResults(mediumPicks, graderPicks);
|
|
86999
|
+
const downgraded = mediumPicks.filter((pick2) => !survivingMedium.some((kept) => kept.groupId === pick2.groupId)).map((pick2) => ({ ...pick2, confidence: "LOW" }));
|
|
87000
|
+
return buildDecision([...highPicks, ...survivingMedium, ...skippedPicks, ...downgraded]);
|
|
87001
|
+
});
|
|
87002
|
+
}
|
|
87003
|
+
function runAiTiebreaker(context, staticPicks) {
|
|
87004
|
+
const prompt = buildTriagerPrompt(context.diff, context.groups);
|
|
87005
|
+
const validGroupIds = context.groups.map((group) => group.id);
|
|
87006
|
+
return selectGroups({ prompt, apiKey: context.apiKey, model: context.model, validGroupIds }).mapErr(mapAiError).map((aiPicks) => mergePicks(staticPicks, aiPicks)).andThen((merged) => {
|
|
87007
|
+
const highPicks = merged.filter((pick2) => pick2.confidence === "HIGH");
|
|
87008
|
+
const mediumPicks = merged.filter((pick2) => pick2.confidence === "MEDIUM");
|
|
87009
|
+
const skippedPicks = merged.filter((pick2) => pick2.confidence === "LOW");
|
|
87010
|
+
if (mediumPicks.length === 0) {
|
|
87011
|
+
return (0, import_neverthrow46.okAsync)(buildDecision(merged));
|
|
87012
|
+
}
|
|
87013
|
+
return runGraderPass({ context, prompt, mediumPicks, highPicks, skippedPicks });
|
|
87014
|
+
});
|
|
87015
|
+
}
|
|
86700
87016
|
function shouldSkipAi(context, decision) {
|
|
86701
87017
|
if (!context.useAi) {
|
|
86702
87018
|
return true;
|
|
86703
87019
|
}
|
|
86704
87020
|
return decision.confidence === "high";
|
|
86705
87021
|
}
|
|
86706
|
-
function mapAiError(error48) {
|
|
86707
|
-
switch (error48.type) {
|
|
86708
|
-
case "AI_CALL_FAILED": {
|
|
86709
|
-
return { type: "AI_CALL_FAILED", cause: error48.cause };
|
|
86710
|
-
}
|
|
86711
|
-
case "AI_INVALID_RESPONSE": {
|
|
86712
|
-
return { type: "AI_INVALID_RESPONSE", raw: error48.raw };
|
|
86713
|
-
}
|
|
86714
|
-
}
|
|
86715
|
-
}
|
|
86716
|
-
function runAiTiebreaker(context, staticPicks) {
|
|
86717
|
-
const prompt = buildTriagerPrompt(context.diff, context.groups);
|
|
86718
|
-
return selectGroups({ prompt, apiKey: context.apiKey, model: context.model }).mapErr(mapAiError).map((aiPicks) => mergePicks(staticPicks, aiPicks)).map((merged) => buildDecision(merged, context.threshold));
|
|
86719
|
-
}
|
|
86720
87022
|
function runTriager(options2) {
|
|
86721
87023
|
const { diff, groups, config: config3 } = options2;
|
|
86722
87024
|
if (groups.length === 0) {
|
|
86723
|
-
return (0,
|
|
87025
|
+
return (0, import_neverthrow46.errAsync)({ type: "NO_GROUPS" });
|
|
86724
87026
|
}
|
|
86725
87027
|
const context = buildContext2({ diff, groups, config: config3 });
|
|
86726
87028
|
const staticPicks = scoreGroups(diff, groups);
|
|
86727
|
-
const initial = buildDecision(staticPicks
|
|
87029
|
+
const initial = buildDecision(staticPicks);
|
|
86728
87030
|
if (shouldSkipAi(context, initial)) {
|
|
86729
|
-
return (0,
|
|
87031
|
+
return (0, import_neverthrow46.okAsync)(initial);
|
|
86730
87032
|
}
|
|
86731
87033
|
return runAiTiebreaker(context, staticPicks);
|
|
86732
87034
|
}
|
|
86733
87035
|
|
|
86734
87036
|
// src/commands/triage-command.ts
|
|
86735
|
-
var
|
|
87037
|
+
var import_neverthrow51 = __toESM(require_index_cjs(), 1);
|
|
86736
87038
|
|
|
86737
87039
|
// ../../node_modules/.pnpm/universal-user-agent@7.0.3/node_modules/universal-user-agent/index.js
|
|
86738
87040
|
function getUserAgent() {
|
|
@@ -87330,7 +87632,7 @@ async function getResponseData(response) {
|
|
|
87330
87632
|
try {
|
|
87331
87633
|
text = await response.text();
|
|
87332
87634
|
return JSON.parse(text);
|
|
87333
|
-
} catch (
|
|
87635
|
+
} catch (err26) {
|
|
87334
87636
|
return text;
|
|
87335
87637
|
}
|
|
87336
87638
|
} else if (mimetype.type.startsWith("text/") || mimetype.parameters.charset?.toLowerCase() === "utf-8") {
|
|
@@ -90282,7 +90584,7 @@ var Octokit2 = Octokit.plugin(requestLog, legacyRestEndpointMethods, paginateRes
|
|
|
90282
90584
|
);
|
|
90283
90585
|
|
|
90284
90586
|
// src/triage/github-pr-fetcher.ts
|
|
90285
|
-
var
|
|
90587
|
+
var import_neverthrow48 = __toESM(require_index_cjs(), 1);
|
|
90286
90588
|
var STATUS_MAP = {
|
|
90287
90589
|
added: "added",
|
|
90288
90590
|
modified: "modified",
|
|
@@ -90318,11 +90620,11 @@ async function runListFiles(octokit, options2) {
|
|
|
90318
90620
|
per_page: 100
|
|
90319
90621
|
});
|
|
90320
90622
|
}
|
|
90321
|
-
var safeGet =
|
|
90623
|
+
var safeGet = import_neverthrow48.ResultAsync.fromThrowable(
|
|
90322
90624
|
runPullRequestGet,
|
|
90323
90625
|
(cause) => ({ type: "PR_FETCH_FAILED", cause })
|
|
90324
90626
|
);
|
|
90325
|
-
var safeList =
|
|
90627
|
+
var safeList = import_neverthrow48.ResultAsync.fromThrowable(
|
|
90326
90628
|
runListFiles,
|
|
90327
90629
|
(cause) => ({ type: "PR_FETCH_FAILED", cause })
|
|
90328
90630
|
);
|
|
@@ -90336,13 +90638,13 @@ function toDiff(summary, files) {
|
|
|
90336
90638
|
}
|
|
90337
90639
|
function fetchPullRequestDiff(options2) {
|
|
90338
90640
|
const octokit = new Octokit2({ auth: options2.token });
|
|
90339
|
-
return
|
|
90641
|
+
return import_neverthrow48.ResultAsync.combine([safeGet(octokit, options2), safeList(octokit, options2)]).map(
|
|
90340
90642
|
([summary, files]) => toDiff(summary, files)
|
|
90341
90643
|
);
|
|
90342
90644
|
}
|
|
90343
90645
|
|
|
90344
90646
|
// src/triage/github-pr-labeller.ts
|
|
90345
|
-
var
|
|
90647
|
+
var import_neverthrow49 = __toESM(require_index_cjs(), 1);
|
|
90346
90648
|
async function runAddLabels(octokit, options2) {
|
|
90347
90649
|
await octokit.issues.addLabels({
|
|
90348
90650
|
owner: options2.owner,
|
|
@@ -90351,7 +90653,7 @@ async function runAddLabels(octokit, options2) {
|
|
|
90351
90653
|
labels: [...options2.labels]
|
|
90352
90654
|
});
|
|
90353
90655
|
}
|
|
90354
|
-
var safeAddLabels =
|
|
90656
|
+
var safeAddLabels = import_neverthrow49.ResultAsync.fromThrowable(
|
|
90355
90657
|
runAddLabels,
|
|
90356
90658
|
(cause) => ({ type: "LABEL_APPLY_FAILED", cause })
|
|
90357
90659
|
);
|
|
@@ -90382,9 +90684,9 @@ function formatXqaLabels(decision) {
|
|
|
90382
90684
|
}
|
|
90383
90685
|
|
|
90384
90686
|
// src/triage/suite-loader.ts
|
|
90385
|
-
var
|
|
90386
|
-
var
|
|
90387
|
-
var
|
|
90687
|
+
var import_promises20 = require("node:fs/promises");
|
|
90688
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
90689
|
+
var import_neverthrow50 = __toESM(require_index_cjs(), 1);
|
|
90388
90690
|
var SUITE_FILE_SUFFIX = ".suite.json";
|
|
90389
90691
|
var freestyleEntrySchema = external_exports2.object({
|
|
90390
90692
|
timeoutSeconds: external_exports2.number().int().positive()
|
|
@@ -90394,39 +90696,39 @@ var suiteFileSchema = external_exports2.object({
|
|
|
90394
90696
|
freestyle: external_exports2.array(freestyleEntrySchema).optional(),
|
|
90395
90697
|
hooks: external_exports2.record(external_exports2.unknown()).optional()
|
|
90396
90698
|
});
|
|
90397
|
-
var safeJsonParse4 = (0,
|
|
90699
|
+
var safeJsonParse4 = (0, import_neverthrow50.fromThrowable)(JSON.parse);
|
|
90398
90700
|
async function runReadFile(filePath) {
|
|
90399
|
-
return (0,
|
|
90701
|
+
return (0, import_promises20.readFile)(filePath, "utf8");
|
|
90400
90702
|
}
|
|
90401
90703
|
async function runStat(filePath) {
|
|
90402
|
-
return (0,
|
|
90704
|
+
return (0, import_promises20.stat)(filePath);
|
|
90403
90705
|
}
|
|
90404
90706
|
async function runReadDirectory(filePath) {
|
|
90405
|
-
return (0,
|
|
90707
|
+
return (0, import_promises20.readdir)(filePath);
|
|
90406
90708
|
}
|
|
90407
90709
|
function readSuiteFile(filePath) {
|
|
90408
|
-
const safeRead =
|
|
90710
|
+
const safeRead = import_neverthrow50.ResultAsync.fromThrowable(
|
|
90409
90711
|
runReadFile,
|
|
90410
90712
|
(cause) => ({ type: "SUITE_READ_FAILED", path: filePath, cause })
|
|
90411
90713
|
);
|
|
90412
90714
|
return safeRead(filePath);
|
|
90413
90715
|
}
|
|
90414
90716
|
function readSpecFile(filePath) {
|
|
90415
|
-
const safeRead =
|
|
90717
|
+
const safeRead = import_neverthrow50.ResultAsync.fromThrowable(
|
|
90416
90718
|
runReadFile,
|
|
90417
90719
|
() => ({ type: "SPEC_NOT_FOUND", path: filePath })
|
|
90418
90720
|
);
|
|
90419
90721
|
return safeRead(filePath);
|
|
90420
90722
|
}
|
|
90421
90723
|
function statDirectory(directory) {
|
|
90422
|
-
const safeStat =
|
|
90724
|
+
const safeStat = import_neverthrow50.ResultAsync.fromThrowable(
|
|
90423
90725
|
runStat,
|
|
90424
90726
|
() => ({ type: "SUITE_DIR_MISSING", path: directory })
|
|
90425
90727
|
);
|
|
90426
90728
|
return safeStat(directory);
|
|
90427
90729
|
}
|
|
90428
90730
|
function readDirectoryEntries(directory) {
|
|
90429
|
-
const safeReadDirectory =
|
|
90731
|
+
const safeReadDirectory = import_neverthrow50.ResultAsync.fromThrowable(
|
|
90430
90732
|
runReadDirectory,
|
|
90431
90733
|
(cause) => ({ type: "SUITE_READ_FAILED", path: directory, cause })
|
|
90432
90734
|
);
|
|
@@ -90435,34 +90737,34 @@ function readDirectoryEntries(directory) {
|
|
|
90435
90737
|
function listSuiteFiles(directory) {
|
|
90436
90738
|
return statDirectory(directory).andThen((stats) => {
|
|
90437
90739
|
if (!stats.isDirectory()) {
|
|
90438
|
-
return (0,
|
|
90740
|
+
return (0, import_neverthrow50.errAsync)({ type: "SUITE_DIR_MISSING", path: directory });
|
|
90439
90741
|
}
|
|
90440
90742
|
return readDirectoryEntries(directory);
|
|
90441
90743
|
}).map(
|
|
90442
|
-
(entries) => entries.filter((entry) => entry.endsWith(SUITE_FILE_SUFFIX)).map((entry) =>
|
|
90744
|
+
(entries) => entries.filter((entry) => entry.endsWith(SUITE_FILE_SUFFIX)).map((entry) => import_node_path19.default.resolve(directory, entry)).toSorted()
|
|
90443
90745
|
);
|
|
90444
90746
|
}
|
|
90445
90747
|
function parseSuiteFile(filePath, raw) {
|
|
90446
90748
|
const parsed = safeJsonParse4(raw);
|
|
90447
90749
|
if (parsed.isErr()) {
|
|
90448
|
-
return (0,
|
|
90750
|
+
return (0, import_neverthrow50.err)({ type: "SUITE_INVALID", path: filePath, cause: parsed.error });
|
|
90449
90751
|
}
|
|
90450
90752
|
const validated = suiteFileSchema.safeParse(parsed.value);
|
|
90451
90753
|
if (!validated.success) {
|
|
90452
|
-
return (0,
|
|
90754
|
+
return (0, import_neverthrow50.err)({ type: "SUITE_INVALID", path: filePath, cause: validated.error });
|
|
90453
90755
|
}
|
|
90454
|
-
return (0,
|
|
90756
|
+
return (0, import_neverthrow50.ok)(validated.data);
|
|
90455
90757
|
}
|
|
90456
90758
|
function suiteIdFromPath(filePath) {
|
|
90457
|
-
const name =
|
|
90759
|
+
const name = import_node_path19.default.basename(filePath);
|
|
90458
90760
|
return name.slice(0, name.length - SUITE_FILE_SUFFIX.length);
|
|
90459
90761
|
}
|
|
90460
90762
|
function loadSpecReference(xqaDirectory, specPath) {
|
|
90461
|
-
const absolute =
|
|
90763
|
+
const absolute = import_node_path19.default.resolve(xqaDirectory, specPath);
|
|
90462
90764
|
return readSpecFile(absolute).andThen((raw) => {
|
|
90463
90765
|
const parsed = parseSpecFrontmatter(raw);
|
|
90464
90766
|
if (parsed.isErr()) {
|
|
90465
|
-
return (0,
|
|
90767
|
+
return (0, import_neverthrow50.err)({
|
|
90466
90768
|
type: "SPEC_FRONTMATTER_INVALID",
|
|
90467
90769
|
path: absolute,
|
|
90468
90770
|
cause: parsed.error.cause
|
|
@@ -90470,19 +90772,19 @@ function loadSpecReference(xqaDirectory, specPath) {
|
|
|
90470
90772
|
}
|
|
90471
90773
|
const { feature, timeoutSeconds } = parsed.value;
|
|
90472
90774
|
if (timeoutSeconds === void 0) {
|
|
90473
|
-
return (0,
|
|
90775
|
+
return (0, import_neverthrow50.ok)({ path: specPath, feature });
|
|
90474
90776
|
}
|
|
90475
|
-
return (0,
|
|
90777
|
+
return (0, import_neverthrow50.ok)({ path: specPath, feature, timeoutSeconds });
|
|
90476
90778
|
});
|
|
90477
90779
|
}
|
|
90478
90780
|
function loadSpecReferences(xqaDirectory, specs) {
|
|
90479
90781
|
if (specs.length === 0) {
|
|
90480
|
-
return (0,
|
|
90782
|
+
return (0, import_neverthrow50.okAsync)([]);
|
|
90481
90783
|
}
|
|
90482
|
-
return
|
|
90784
|
+
return import_neverthrow50.ResultAsync.combine(specs.map((specPath) => loadSpecReference(xqaDirectory, specPath)));
|
|
90483
90785
|
}
|
|
90484
90786
|
function addSpecTokens(tokens, spec) {
|
|
90485
|
-
const stem =
|
|
90787
|
+
const stem = import_node_path19.default.basename(spec.path).replace(/\.test\.md$/u, "");
|
|
90486
90788
|
for (const part of stem.split(".")) {
|
|
90487
90789
|
if (part.length > 0) {
|
|
90488
90790
|
tokens.add(part);
|
|
@@ -90547,12 +90849,12 @@ function loadSuite(suiteFilePath, xqaDirectory) {
|
|
|
90547
90849
|
);
|
|
90548
90850
|
}
|
|
90549
90851
|
function loadXqaSuites(directory) {
|
|
90550
|
-
const xqaDirectory =
|
|
90852
|
+
const xqaDirectory = import_node_path19.default.dirname(import_node_path19.default.resolve(directory));
|
|
90551
90853
|
return listSuiteFiles(directory).andThen((files) => {
|
|
90552
90854
|
if (files.length === 0) {
|
|
90553
|
-
return (0,
|
|
90855
|
+
return (0, import_neverthrow50.okAsync)([]);
|
|
90554
90856
|
}
|
|
90555
|
-
return
|
|
90857
|
+
return import_neverthrow50.ResultAsync.combine(files.map((file2) => loadSuite(file2, xqaDirectory)));
|
|
90556
90858
|
});
|
|
90557
90859
|
}
|
|
90558
90860
|
|
|
@@ -90563,77 +90865,57 @@ function parseRepo(input) {
|
|
|
90563
90865
|
const parts = input.split("/");
|
|
90564
90866
|
const [owner, repo] = parts;
|
|
90565
90867
|
if (parts.length !== 2 || owner === void 0 || owner === "" || repo === void 0 || repo === "") {
|
|
90566
|
-
return (0,
|
|
90868
|
+
return (0, import_neverthrow51.err)({ type: "CLI_INVALID_ARG", message: `invalid --repo value: ${input}` });
|
|
90567
90869
|
}
|
|
90568
|
-
return (0,
|
|
90870
|
+
return (0, import_neverthrow51.ok)({ owner, repo });
|
|
90569
90871
|
}
|
|
90570
90872
|
function parsePrNumber(input) {
|
|
90571
90873
|
const parsed = Number.parseInt(input, 10);
|
|
90572
90874
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
90573
|
-
return (0,
|
|
90875
|
+
return (0, import_neverthrow51.err)({ type: "CLI_INVALID_ARG", message: `invalid --pr value: ${input}` });
|
|
90574
90876
|
}
|
|
90575
|
-
return (0,
|
|
90576
|
-
}
|
|
90577
|
-
function parseThresholdValue(input) {
|
|
90578
|
-
const parsed = Number.parseFloat(input);
|
|
90579
|
-
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
90580
|
-
return (0, import_neverthrow49.err)({ type: "CLI_INVALID_ARG", message: `invalid --threshold value: ${input}` });
|
|
90581
|
-
}
|
|
90582
|
-
return (0, import_neverthrow49.ok)(parsed);
|
|
90583
|
-
}
|
|
90584
|
-
function parseThreshold(input) {
|
|
90585
|
-
if (input === void 0) {
|
|
90586
|
-
return (0, import_neverthrow49.ok)(void 0);
|
|
90587
|
-
}
|
|
90588
|
-
return parseThresholdValue(input);
|
|
90877
|
+
return (0, import_neverthrow51.ok)(parsed);
|
|
90589
90878
|
}
|
|
90590
90879
|
function parseCliInputs(options2) {
|
|
90591
90880
|
const repoResult = parseRepo(options2.repo);
|
|
90592
90881
|
if (repoResult.isErr()) {
|
|
90593
|
-
return (0,
|
|
90882
|
+
return (0, import_neverthrow51.err)(repoResult.error);
|
|
90594
90883
|
}
|
|
90595
90884
|
const prResult = parsePrNumber(options2.pr);
|
|
90596
90885
|
if (prResult.isErr()) {
|
|
90597
|
-
return (0,
|
|
90598
|
-
}
|
|
90599
|
-
const thresholdResult = parseThreshold(options2.threshold);
|
|
90600
|
-
if (thresholdResult.isErr()) {
|
|
90601
|
-
return (0, import_neverthrow49.err)(thresholdResult.error);
|
|
90886
|
+
return (0, import_neverthrow51.err)(prResult.error);
|
|
90602
90887
|
}
|
|
90603
|
-
return (0,
|
|
90888
|
+
return (0, import_neverthrow51.ok)({
|
|
90604
90889
|
owner: repoResult.value.owner,
|
|
90605
90890
|
repo: repoResult.value.repo,
|
|
90606
|
-
prNumber: prResult.value
|
|
90607
|
-
threshold: thresholdResult.value
|
|
90891
|
+
prNumber: prResult.value
|
|
90608
90892
|
});
|
|
90609
90893
|
}
|
|
90610
90894
|
function buildInputs(options2, config3) {
|
|
90611
90895
|
if (config3.GITHUB_TOKEN === void 0) {
|
|
90612
|
-
return (0,
|
|
90896
|
+
return (0, import_neverthrow51.err)({ type: "CONFIG_MISSING", key: "GITHUB_TOKEN" });
|
|
90613
90897
|
}
|
|
90614
90898
|
const parsed = parseCliInputs(options2);
|
|
90615
90899
|
if (parsed.isErr()) {
|
|
90616
|
-
return (0,
|
|
90900
|
+
return (0, import_neverthrow51.err)(parsed.error);
|
|
90617
90901
|
}
|
|
90618
|
-
return (0,
|
|
90902
|
+
return (0, import_neverthrow51.ok)({
|
|
90619
90903
|
owner: parsed.value.owner,
|
|
90620
90904
|
repo: parsed.value.repo,
|
|
90621
90905
|
prNumber: parsed.value.prNumber,
|
|
90622
90906
|
suitesDir: options2.suitesDir ?? config3.XQA_SUITES_DIR,
|
|
90623
90907
|
applyLabels: options2.applyLabels === true,
|
|
90624
90908
|
model: options2.model,
|
|
90625
|
-
threshold: parsed.value.threshold,
|
|
90626
90909
|
anthropicApiKey: config3.ANTHROPIC_API_KEY,
|
|
90627
90910
|
githubToken: config3.GITHUB_TOKEN
|
|
90628
90911
|
});
|
|
90629
90912
|
}
|
|
90630
90913
|
function buildTriagerConfig(inputs) {
|
|
90631
90914
|
const base = { apiKey: inputs.anthropicApiKey };
|
|
90632
|
-
|
|
90633
|
-
|
|
90634
|
-
return withModel;
|
|
90915
|
+
if (inputs.model === void 0) {
|
|
90916
|
+
return base;
|
|
90635
90917
|
}
|
|
90636
|
-
return { ...
|
|
90918
|
+
return { ...base, model: inputs.model };
|
|
90637
90919
|
}
|
|
90638
90920
|
function callTriager(options2) {
|
|
90639
90921
|
const { inputs, groups, diff } = options2;
|
|
@@ -90643,7 +90925,7 @@ function callTriager(options2) {
|
|
|
90643
90925
|
}
|
|
90644
90926
|
function maybeApplyLabels(inputs, labels) {
|
|
90645
90927
|
if (!inputs.applyLabels || labels.length === 0) {
|
|
90646
|
-
return
|
|
90928
|
+
return import_neverthrow51.ResultAsync.fromSafePromise(Promise.resolve(labels));
|
|
90647
90929
|
}
|
|
90648
90930
|
return applyPullRequestLabels({
|
|
90649
90931
|
owner: inputs.owner,
|
|
@@ -90653,8 +90935,8 @@ function maybeApplyLabels(inputs, labels) {
|
|
|
90653
90935
|
token: inputs.githubToken
|
|
90654
90936
|
}).map(() => labels);
|
|
90655
90937
|
}
|
|
90656
|
-
function
|
|
90657
|
-
return
|
|
90938
|
+
function runPipeline4(inputs) {
|
|
90939
|
+
return import_neverthrow51.ResultAsync.combine([
|
|
90658
90940
|
loadXqaSuites(inputs.suitesDir),
|
|
90659
90941
|
fetchPullRequestDiff({
|
|
90660
90942
|
owner: inputs.owner,
|
|
@@ -90681,7 +90963,7 @@ async function runTriageCommand(options2, config3) {
|
|
|
90681
90963
|
printError(inputs.error);
|
|
90682
90964
|
return EXIT_FAILURE;
|
|
90683
90965
|
}
|
|
90684
|
-
const outcome = await
|
|
90966
|
+
const outcome = await runPipeline4(inputs.value);
|
|
90685
90967
|
return outcome.match(
|
|
90686
90968
|
(payload) => {
|
|
90687
90969
|
printSuccess(payload);
|
|
@@ -90701,10 +90983,10 @@ function runUpdateCommand() {
|
|
|
90701
90983
|
}
|
|
90702
90984
|
|
|
90703
90985
|
// src/config.ts
|
|
90704
|
-
var
|
|
90986
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
90705
90987
|
var import_node_url2 = require("node:url");
|
|
90706
90988
|
var import_dotenv = __toESM(require_main(), 1);
|
|
90707
|
-
var
|
|
90989
|
+
var import_neverthrow52 = __toESM(require_index_cjs(), 1);
|
|
90708
90990
|
|
|
90709
90991
|
// src/config-schema.ts
|
|
90710
90992
|
var configSchema = external_exports2.object({
|
|
@@ -90718,18 +91000,18 @@ var configSchema = external_exports2.object({
|
|
|
90718
91000
|
});
|
|
90719
91001
|
|
|
90720
91002
|
// src/config.ts
|
|
90721
|
-
var packageDirectory =
|
|
91003
|
+
var packageDirectory = import_node_path20.default.dirname((0, import_node_url2.fileURLToPath)(__importMetaUrl));
|
|
90722
91004
|
function loadConfig() {
|
|
90723
|
-
(0, import_dotenv.config)({ path:
|
|
91005
|
+
(0, import_dotenv.config)({ path: import_node_path20.default.resolve(packageDirectory, "..", ".env.local") });
|
|
90724
91006
|
const result = configSchema.safeParse(process.env);
|
|
90725
91007
|
if (!result.success) {
|
|
90726
91008
|
const messages = result.error.issues.map(
|
|
90727
91009
|
(issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`
|
|
90728
91010
|
);
|
|
90729
|
-
return (0,
|
|
91011
|
+
return (0, import_neverthrow52.err)({ type: "INVALID_CONFIG", message: `Configuration error:
|
|
90730
91012
|
${messages.join("\n")}` });
|
|
90731
91013
|
}
|
|
90732
|
-
return (0,
|
|
91014
|
+
return (0, import_neverthrow52.ok)(result.data);
|
|
90733
91015
|
}
|
|
90734
91016
|
|
|
90735
91017
|
// src/core/parse-timeout-seconds.ts
|
|
@@ -90762,7 +91044,7 @@ function parseVerboseOption(value) {
|
|
|
90762
91044
|
|
|
90763
91045
|
// src/pid-lock.ts
|
|
90764
91046
|
var import_node_fs9 = require("node:fs");
|
|
90765
|
-
var
|
|
91047
|
+
var import_neverthrow53 = __toESM(require_index_cjs(), 1);
|
|
90766
91048
|
var PID_FILE = "/tmp/xqa.pid";
|
|
90767
91049
|
var SIGINT_EXIT_CODE = 130;
|
|
90768
91050
|
var SIGTERM_EXIT_CODE = 143;
|
|
@@ -90771,7 +91053,7 @@ var HARD_TIMEOUT_MS = 1e4;
|
|
|
90771
91053
|
var cleanup = () => {
|
|
90772
91054
|
(0, import_node_fs9.rmSync)(PID_FILE, { force: true });
|
|
90773
91055
|
};
|
|
90774
|
-
var checkProcessRunning = (0,
|
|
91056
|
+
var checkProcessRunning = (0, import_neverthrow53.fromThrowable)(
|
|
90775
91057
|
(pid) => {
|
|
90776
91058
|
process.kill(pid, 0);
|
|
90777
91059
|
return true;
|
|
@@ -90836,32 +91118,32 @@ function acquireLock() {
|
|
|
90836
91118
|
|
|
90837
91119
|
// src/shell/xqa-directory.ts
|
|
90838
91120
|
var import_node_fs10 = require("node:fs");
|
|
90839
|
-
var
|
|
90840
|
-
var
|
|
91121
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
91122
|
+
var import_neverthrow54 = __toESM(require_index_cjs(), 1);
|
|
90841
91123
|
function findXqaDirectory(startDirectory) {
|
|
90842
91124
|
let current = startDirectory;
|
|
90843
91125
|
for (; ; ) {
|
|
90844
|
-
const candidate =
|
|
91126
|
+
const candidate = import_node_path21.default.join(current, ".xqa");
|
|
90845
91127
|
if ((0, import_node_fs10.existsSync)(candidate)) {
|
|
90846
|
-
return (0,
|
|
91128
|
+
return (0, import_neverthrow54.ok)(candidate);
|
|
90847
91129
|
}
|
|
90848
|
-
const parent =
|
|
91130
|
+
const parent = import_node_path21.default.dirname(current);
|
|
90849
91131
|
if (parent === current) {
|
|
90850
|
-
return (0,
|
|
91132
|
+
return (0, import_neverthrow54.err)({ type: "XQA_NOT_INITIALIZED" });
|
|
90851
91133
|
}
|
|
90852
91134
|
current = parent;
|
|
90853
91135
|
}
|
|
90854
91136
|
}
|
|
90855
91137
|
|
|
90856
91138
|
// src/suite/commands/run-command.ts
|
|
90857
|
-
var
|
|
90858
|
-
var
|
|
91139
|
+
var import_promises23 = __toESM(require("node:fs/promises"), 1);
|
|
91140
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
90859
91141
|
var import_fast_glob = __toESM(require_out4(), 1);
|
|
90860
|
-
var
|
|
91142
|
+
var import_neverthrow62 = __toESM(require_index_cjs(), 1);
|
|
90861
91143
|
|
|
90862
91144
|
// src/suite/core/suite-config-parser.ts
|
|
90863
|
-
var
|
|
90864
|
-
var
|
|
91145
|
+
var import_neverthrow55 = __toESM(require_index_cjs(), 1);
|
|
91146
|
+
var import_neverthrow56 = __toESM(require_index_cjs(), 1);
|
|
90865
91147
|
var RESERVED_HOOK_ENV_KEYS = [
|
|
90866
91148
|
"XQA_SIM_UDID",
|
|
90867
91149
|
"XQA_ITEM_ID",
|
|
@@ -90913,7 +91195,7 @@ var suiteConfigSchema = external_exports2.object({
|
|
|
90913
91195
|
}).refine((data) => data.specs.length > 0 || data.freestyle.length > 0, {
|
|
90914
91196
|
message: "Suite must declare at least one spec or freestyle entry"
|
|
90915
91197
|
});
|
|
90916
|
-
var safeJsonParse5 = (0,
|
|
91198
|
+
var safeJsonParse5 = (0, import_neverthrow55.fromThrowable)(
|
|
90917
91199
|
JSON.parse,
|
|
90918
91200
|
(cause) => ({
|
|
90919
91201
|
type: "INVALID_SUITE_CONFIG",
|
|
@@ -90947,16 +91229,16 @@ function parseSuiteConfig(raw) {
|
|
|
90947
91229
|
return safeJsonParse5(raw).andThen((data) => {
|
|
90948
91230
|
const parsed = suiteConfigSchema.safeParse(data);
|
|
90949
91231
|
if (!parsed.success) {
|
|
90950
|
-
return (0,
|
|
91232
|
+
return (0, import_neverthrow56.err)({ type: "INVALID_SUITE_CONFIG", cause: parsed.error });
|
|
90951
91233
|
}
|
|
90952
91234
|
const hooks = normalizeHooks(parsed.data.hooks);
|
|
90953
91235
|
if (hooks === void 0) {
|
|
90954
|
-
return (0,
|
|
91236
|
+
return (0, import_neverthrow56.ok)({
|
|
90955
91237
|
specs: parsed.data.specs,
|
|
90956
91238
|
freestyle: parsed.data.freestyle
|
|
90957
91239
|
});
|
|
90958
91240
|
}
|
|
90959
|
-
return (0,
|
|
91241
|
+
return (0, import_neverthrow56.ok)({
|
|
90960
91242
|
specs: parsed.data.specs,
|
|
90961
91243
|
freestyle: parsed.data.freestyle,
|
|
90962
91244
|
hooks
|
|
@@ -91013,25 +91295,25 @@ function buildFreestyleItems(entries) {
|
|
|
91013
91295
|
}
|
|
91014
91296
|
|
|
91015
91297
|
// src/suite/shell/suite-findings-writer.ts
|
|
91016
|
-
var
|
|
91017
|
-
var
|
|
91018
|
-
var
|
|
91298
|
+
var import_promises21 = __toESM(require("node:fs/promises"), 1);
|
|
91299
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
91300
|
+
var import_neverthrow57 = __toESM(require_index_cjs(), 1);
|
|
91019
91301
|
var INDENT_SPACES = 2;
|
|
91020
91302
|
function writeSuiteFindings(findings, options2) {
|
|
91021
|
-
const directory =
|
|
91303
|
+
const directory = import_node_path22.default.join(
|
|
91022
91304
|
options2.outputDirectory,
|
|
91023
91305
|
"suite",
|
|
91024
91306
|
findings.suiteId,
|
|
91025
91307
|
options2.date,
|
|
91026
91308
|
findings.runId
|
|
91027
91309
|
);
|
|
91028
|
-
const finalPath =
|
|
91310
|
+
const finalPath = import_node_path22.default.join(directory, "findings.json");
|
|
91029
91311
|
const temporaryPath = `${finalPath}.tmp`;
|
|
91030
|
-
const safeWriteAtomically =
|
|
91312
|
+
const safeWriteAtomically = import_neverthrow57.ResultAsync.fromThrowable(
|
|
91031
91313
|
async () => {
|
|
91032
|
-
await
|
|
91033
|
-
await
|
|
91034
|
-
await
|
|
91314
|
+
await import_promises21.default.mkdir(directory, { recursive: true });
|
|
91315
|
+
await import_promises21.default.writeFile(temporaryPath, JSON.stringify(findings, void 0, INDENT_SPACES));
|
|
91316
|
+
await import_promises21.default.rename(temporaryPath, finalPath);
|
|
91035
91317
|
return finalPath;
|
|
91036
91318
|
},
|
|
91037
91319
|
(cause) => ({ type: "FINDINGS_WRITE_FAILED", cause })
|
|
@@ -91040,7 +91322,7 @@ function writeSuiteFindings(findings, options2) {
|
|
|
91040
91322
|
}
|
|
91041
91323
|
|
|
91042
91324
|
// src/suite/shell/worker-pool.ts
|
|
91043
|
-
var
|
|
91325
|
+
var import_neverthrow60 = __toESM(require_index_cjs(), 1);
|
|
91044
91326
|
|
|
91045
91327
|
// src/suite/core/priority-queue.ts
|
|
91046
91328
|
var PriorityQueue = class {
|
|
@@ -91224,7 +91506,7 @@ function recordHookFailure(input) {
|
|
|
91224
91506
|
}
|
|
91225
91507
|
|
|
91226
91508
|
// src/suite/shell/hook-invoker.ts
|
|
91227
|
-
var
|
|
91509
|
+
var import_neverthrow59 = __toESM(require_index_cjs(), 1);
|
|
91228
91510
|
|
|
91229
91511
|
// src/suite/core/hook-env-builder.ts
|
|
91230
91512
|
function buildReservedKeys(input) {
|
|
@@ -91251,7 +91533,7 @@ function buildHookEnv(input) {
|
|
|
91251
91533
|
|
|
91252
91534
|
// src/suite/shell/hook-runner.ts
|
|
91253
91535
|
var import_node_child_process6 = require("node:child_process");
|
|
91254
|
-
var
|
|
91536
|
+
var import_neverthrow58 = __toESM(require_index_cjs(), 1);
|
|
91255
91537
|
function makeDeferred() {
|
|
91256
91538
|
const raw = Promise.withResolvers();
|
|
91257
91539
|
return { promise: raw.promise, resolve: raw.resolve };
|
|
@@ -91281,7 +91563,7 @@ var HookRuntime = class {
|
|
|
91281
91563
|
this.deferred = makeDeferred();
|
|
91282
91564
|
this.onAbort = () => {
|
|
91283
91565
|
this.child.kill("SIGTERM");
|
|
91284
|
-
this.settle((0,
|
|
91566
|
+
this.settle((0, import_neverthrow58.err)({ type: "HOOK_ABORTED" }));
|
|
91285
91567
|
};
|
|
91286
91568
|
}
|
|
91287
91569
|
async start() {
|
|
@@ -91306,20 +91588,20 @@ var HookRuntime = class {
|
|
|
91306
91588
|
attachTimeout() {
|
|
91307
91589
|
this.timeoutHandle = setTimeout(() => {
|
|
91308
91590
|
this.child.kill("SIGTERM");
|
|
91309
|
-
this.settle((0,
|
|
91591
|
+
this.settle((0, import_neverthrow58.err)({ type: "HOOK_TIMEOUT", timeoutMs: this.timeoutMs }));
|
|
91310
91592
|
}, this.timeoutMs);
|
|
91311
91593
|
}
|
|
91312
91594
|
attachChildListeners() {
|
|
91313
91595
|
this.child.on("error", (cause) => {
|
|
91314
|
-
this.settle((0,
|
|
91596
|
+
this.settle((0, import_neverthrow58.err)({ type: "HOOK_SPAWN_FAILED", cause }));
|
|
91315
91597
|
});
|
|
91316
91598
|
this.child.on("exit", (code) => {
|
|
91317
91599
|
if (code === 0) {
|
|
91318
|
-
this.settle((0,
|
|
91600
|
+
this.settle((0, import_neverthrow58.ok)());
|
|
91319
91601
|
return;
|
|
91320
91602
|
}
|
|
91321
91603
|
this.settle(
|
|
91322
|
-
(0,
|
|
91604
|
+
(0, import_neverthrow58.err)({
|
|
91323
91605
|
type: "HOOK_EXIT_NONZERO",
|
|
91324
91606
|
code: code ?? -1,
|
|
91325
91607
|
stderr: this.stderrBuffer
|
|
@@ -91342,7 +91624,7 @@ var HookRuntime = class {
|
|
|
91342
91624
|
this.signal.removeEventListener("abort", this.onAbort);
|
|
91343
91625
|
}
|
|
91344
91626
|
};
|
|
91345
|
-
var safeSpawn =
|
|
91627
|
+
var safeSpawn = import_neverthrow58.ResultAsync.fromThrowable(
|
|
91346
91628
|
spawnHook,
|
|
91347
91629
|
(cause) => ({ type: "HOOK_SPAWN_FAILED", cause })
|
|
91348
91630
|
);
|
|
@@ -91370,7 +91652,7 @@ async function invokeHook(input) {
|
|
|
91370
91652
|
async function maybeInvokeHook(input) {
|
|
91371
91653
|
const { hook: hook2 } = input;
|
|
91372
91654
|
if (hook2 === void 0) {
|
|
91373
|
-
return (0,
|
|
91655
|
+
return (0, import_neverthrow59.ok)();
|
|
91374
91656
|
}
|
|
91375
91657
|
return invokeHook({ ...input, hook: hook2 });
|
|
91376
91658
|
}
|
|
@@ -91509,7 +91791,7 @@ function runWorkerPool(config3) {
|
|
|
91509
91791
|
const queue = setupQueue(config3);
|
|
91510
91792
|
const results = [];
|
|
91511
91793
|
const suiteStartMs = Date.now();
|
|
91512
|
-
const safeRun =
|
|
91794
|
+
const safeRun = import_neverthrow60.ResultAsync.fromThrowable(
|
|
91513
91795
|
async () => runAllWorkers({ config: config3, queue, results, suiteStartMs }),
|
|
91514
91796
|
(cause) => ({ type: "WORKER_POOL_FAILED", cause })
|
|
91515
91797
|
);
|
|
@@ -91519,7 +91801,7 @@ function runWorkerPool(config3) {
|
|
|
91519
91801
|
// src/suite/commands/execute-item.ts
|
|
91520
91802
|
var import_node_fs11 = require("node:fs");
|
|
91521
91803
|
var import_node_os4 = __toESM(require("node:os"), 1);
|
|
91522
|
-
var
|
|
91804
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
91523
91805
|
var DEFAULT_FREESTYLE_TIMEOUT_SECONDS2 = 300;
|
|
91524
91806
|
function buildDeviceInstruction(simulatorUdid) {
|
|
91525
91807
|
return `You MUST use device "${simulatorUdid}" for ALL mobile tool calls. The simulator UDID is already configured \u2014 use it directly.`;
|
|
@@ -91528,7 +91810,7 @@ function composeAppContext(parts) {
|
|
|
91528
91810
|
return parts.filter((part) => part !== void 0 && part.length > 0).join("\n\n");
|
|
91529
91811
|
}
|
|
91530
91812
|
function ensureWorkerCwd(simulatorUdid) {
|
|
91531
|
-
const workerDirectory =
|
|
91813
|
+
const workerDirectory = import_node_path23.default.join(import_node_os4.default.tmpdir(), "xqa-workers", simulatorUdid);
|
|
91532
91814
|
(0, import_node_fs11.mkdirSync)(workerDirectory, { recursive: true });
|
|
91533
91815
|
return workerDirectory;
|
|
91534
91816
|
}
|
|
@@ -91542,7 +91824,7 @@ function buildFreestylePipelineConfig(input) {
|
|
|
91542
91824
|
const { item, context, signal, simulatorUdid, onEvent } = input;
|
|
91543
91825
|
const { config: config3, xqaDirectory, runId, date: date5, appContext } = context;
|
|
91544
91826
|
return {
|
|
91545
|
-
outputDir:
|
|
91827
|
+
outputDir: import_node_path23.default.join(xqaDirectory, "output", item.id),
|
|
91546
91828
|
runId,
|
|
91547
91829
|
simulatorUdid,
|
|
91548
91830
|
signal,
|
|
@@ -91564,13 +91846,13 @@ function buildFreestylePipelineConfig(input) {
|
|
|
91564
91846
|
};
|
|
91565
91847
|
}
|
|
91566
91848
|
function executeFreestyleItem(input) {
|
|
91567
|
-
return
|
|
91849
|
+
return runPipeline3(buildFreestylePipelineConfig(input)).map((output) => ({ findings: output.findings, findingsPath: output.findingsPath })).mapErr((cause) => ({ type: "PIPELINE_FAILED", cause }));
|
|
91568
91850
|
}
|
|
91569
91851
|
function buildSpecPipelineConfig(input) {
|
|
91570
91852
|
const { item, context, signal, simulatorUdid, onEvent } = input;
|
|
91571
91853
|
const { config: config3, xqaDirectory, runId, appContext } = context;
|
|
91572
91854
|
return {
|
|
91573
|
-
outputDir:
|
|
91855
|
+
outputDir: import_node_path23.default.join(xqaDirectory, "output", item.id),
|
|
91574
91856
|
runId,
|
|
91575
91857
|
simulatorUdid,
|
|
91576
91858
|
signal,
|
|
@@ -91587,7 +91869,7 @@ function buildSpecPipelineConfig(input) {
|
|
|
91587
91869
|
};
|
|
91588
91870
|
}
|
|
91589
91871
|
function executeSpecItem(input) {
|
|
91590
|
-
return
|
|
91872
|
+
return runPipeline3(buildSpecPipelineConfig(input)).map((output) => ({ findings: output.findings, findingsPath: output.findingsPath })).mapErr((cause) => ({ type: "PIPELINE_FAILED", cause }));
|
|
91591
91873
|
}
|
|
91592
91874
|
function makeExecuteItem(context) {
|
|
91593
91875
|
return (options2) => {
|
|
@@ -91600,9 +91882,9 @@ function makeExecuteItem(context) {
|
|
|
91600
91882
|
}
|
|
91601
91883
|
|
|
91602
91884
|
// src/suite/commands/suite-run-context.ts
|
|
91603
|
-
var
|
|
91604
|
-
var
|
|
91605
|
-
var
|
|
91885
|
+
var import_promises22 = __toESM(require("node:fs/promises"), 1);
|
|
91886
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
91887
|
+
var import_neverthrow61 = __toESM(require_index_cjs(), 1);
|
|
91606
91888
|
|
|
91607
91889
|
// src/suite/core/run-id.ts
|
|
91608
91890
|
var RUN_ID_PAD_LENGTH2 = 4;
|
|
@@ -91637,16 +91919,16 @@ function deriveSuiteId(input) {
|
|
|
91637
91919
|
|
|
91638
91920
|
// src/suite/commands/suite-run-context.ts
|
|
91639
91921
|
var ISO_DATE_LENGTH3 = 10;
|
|
91640
|
-
var safeReaddir2 =
|
|
91922
|
+
var safeReaddir2 = import_neverthrow61.ResultAsync.fromThrowable(
|
|
91641
91923
|
async (directoryPath) => {
|
|
91642
|
-
const entries = await
|
|
91924
|
+
const entries = await import_promises22.default.readdir(directoryPath, { withFileTypes: true });
|
|
91643
91925
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
91644
91926
|
},
|
|
91645
91927
|
() => "READDIR_FAILED"
|
|
91646
91928
|
);
|
|
91647
91929
|
async function listRunDirectories(input) {
|
|
91648
91930
|
const { outputDirectory, suiteId, date: date5 } = input;
|
|
91649
|
-
const directoryPath =
|
|
91931
|
+
const directoryPath = import_node_path24.default.join(outputDirectory, "suite", suiteId, date5);
|
|
91650
91932
|
const result = await safeReaddir2(directoryPath);
|
|
91651
91933
|
return result.unwrapOr([]);
|
|
91652
91934
|
}
|
|
@@ -91670,7 +91952,7 @@ ${cause}
|
|
|
91670
91952
|
async function buildSuiteRunContext(input) {
|
|
91671
91953
|
const suiteId = deriveSuiteIdFromMode(input.mode);
|
|
91672
91954
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, ISO_DATE_LENGTH3);
|
|
91673
|
-
const outputDirectory =
|
|
91955
|
+
const outputDirectory = import_node_path24.default.join(input.xqaDirectory, "output");
|
|
91674
91956
|
const existingDirectories = await listRunDirectories({ outputDirectory, suiteId, date: date5 });
|
|
91675
91957
|
const runId = computeNextRunId(existingDirectories);
|
|
91676
91958
|
const appContext = await loadAppContext(input.xqaDirectory);
|
|
@@ -91685,15 +91967,15 @@ async function buildSuiteRunContext(input) {
|
|
|
91685
91967
|
}
|
|
91686
91968
|
|
|
91687
91969
|
// src/suite/commands/run-command.ts
|
|
91688
|
-
var safeReadFile5 =
|
|
91689
|
-
async (filePath) =>
|
|
91970
|
+
var safeReadFile5 = import_neverthrow62.ResultAsync.fromThrowable(
|
|
91971
|
+
async (filePath) => import_promises23.default.readFile(filePath, "utf8"),
|
|
91690
91972
|
() => "READ_FAILED"
|
|
91691
91973
|
);
|
|
91692
91974
|
async function resolveGlobs(input) {
|
|
91693
91975
|
return (0, import_fast_glob.default)(input.globs, { cwd: input.cwd, absolute: true });
|
|
91694
91976
|
}
|
|
91695
91977
|
async function loadSuiteConfig(xqaDirectory, name) {
|
|
91696
|
-
const suitePath =
|
|
91978
|
+
const suitePath = import_node_path25.default.join(xqaDirectory, "suites", `${name}.suite.json`);
|
|
91697
91979
|
const contentResult = await safeReadFile5(suitePath);
|
|
91698
91980
|
if (contentResult.isErr()) {
|
|
91699
91981
|
return;
|
|
@@ -91889,7 +92171,7 @@ function resolveXqaDirectory() {
|
|
|
91889
92171
|
return result.value;
|
|
91890
92172
|
}
|
|
91891
92173
|
var program2 = new Command();
|
|
91892
|
-
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"
|
|
92174
|
+
program2.name("xqa").description("AI-powered QA agent CLI").version(`${"2.0.0"}${false ? ` (dev build +${"e8d216b"})` : ""}`);
|
|
91893
92175
|
program2.command("init").description("Initialize a new xqa project in the current directory").action(() => {
|
|
91894
92176
|
runInitCommand();
|
|
91895
92177
|
});
|