@qawolf/cli 1.29.0 → 1.31.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/cli.js +2393 -577
- package/dist/runner-sdk.js +274 -142
- package/dist/types/runnerSdk/types.d.ts +8 -0
- package/package.json +2 -2
- package/skills/qawolf-cli/SKILL.md +56 -2
- package/skills/qawolf-cli/references/run-results.md +8 -0
- package/skills/qawolf-cli/references/runner.md +21 -9
package/dist/cli.js
CHANGED
|
@@ -8382,17 +8382,13 @@ function isTimeoutError(err) {
|
|
|
8382
8382
|
}
|
|
8383
8383
|
var missingPackagePattern = /Cannot find (?:package|module) '([^']+)'/;
|
|
8384
8384
|
var pathLikeSpecifierPattern = /^(?:\.|\/|[A-Za-z]:[\\/])/;
|
|
8385
|
-
|
|
8385
|
+
var sourceFileSpecifierPattern = /\.(?:[cm]?[jt]sx?)$/;
|
|
8386
|
+
function extractMissingSpecifier(text) {
|
|
8386
8387
|
const specifier = missingPackagePattern.exec(text)?.[1];
|
|
8387
8388
|
if (specifier === undefined || pathLikeSpecifierPattern.test(specifier)) {
|
|
8388
8389
|
return;
|
|
8389
8390
|
}
|
|
8390
|
-
return specifier;
|
|
8391
|
-
}
|
|
8392
|
-
|
|
8393
|
-
// src/core/pluralize.ts
|
|
8394
|
-
function pluralize(count, singular, plural = `${singular}s`) {
|
|
8395
|
-
return `${String(count)} ${count === 1 ? singular : plural}`;
|
|
8391
|
+
return sourceFileSpecifierPattern.test(specifier) ? { kind: "path-alias", specifier } : { kind: "package", specifier };
|
|
8396
8392
|
}
|
|
8397
8393
|
|
|
8398
8394
|
// src/core/formatSeconds.ts
|
|
@@ -8400,6 +8396,33 @@ function formatSeconds(ms) {
|
|
|
8400
8396
|
return `${Math.round(ms / 1000)}s`;
|
|
8401
8397
|
}
|
|
8402
8398
|
|
|
8399
|
+
// src/core/messages/agent.ts
|
|
8400
|
+
var followAgain = (sessionId) => `qawolf agent get --follow --session ${sessionId}`;
|
|
8401
|
+
var sessionGivenTwice = (argument, flag) => `Two different sessions were named: "${argument}" as an argument and "${flag}" as --session. Pass one of them.`;
|
|
8402
|
+
var agentMessages = {
|
|
8403
|
+
answerCancelled: "No answer sent, so QA Wolf is still waiting on one. The session keeps its place: answer it whenever you like.",
|
|
8404
|
+
answerPrompt: "Your answer",
|
|
8405
|
+
answerSendFailed: (reason) => `The answer could not be sent: ${reason}. The session is still waiting, so try again.`,
|
|
8406
|
+
blocked: (sessionId) => `QA Wolf asked a question and cannot continue until it is answered. Answer it with qawolf agent send "<your answer>" --session ${sessionId}.`,
|
|
8407
|
+
detachHint: "Press Ctrl-C to stop following. The session keeps running in the background.",
|
|
8408
|
+
detached: (sessionId) => `Stopped following. The session is still running — pick it back up with ${followAgain(sessionId)}.`,
|
|
8409
|
+
followTimedOut: (sessionId, seconds) => `Stopped following after ${formatSeconds(seconds * 1000)}. The session may still be going: pick it back up with ${followAgain(sessionId)}, or pass --timeout to wait longer.`,
|
|
8410
|
+
noSession: "No session named. Pass --session, set QAWOLF_SESSION_ID, or start one with qawolf agent send.",
|
|
8411
|
+
sessionNotRemembered: (sessionId) => `The session id could not be saved to .qawolf/agent.json, so pass --session ${sessionId} to pick it up later.`,
|
|
8412
|
+
sessionCancelled: (url) => `The session was cancelled before it finished. Read how far it got at ${url}.`,
|
|
8413
|
+
sessionCompleted: "QA Wolf finished the work.",
|
|
8414
|
+
sessionFailed: (url) => `The session failed. Read what happened at ${url}.`,
|
|
8415
|
+
sessionAt: (url) => `Following ${url}`,
|
|
8416
|
+
standing: (status, url) => `${status} — ${url}`,
|
|
8417
|
+
started: (sessionId, url) => `Started session ${sessionId} — ${url}`,
|
|
8418
|
+
waiting: "Waiting for QA Wolf",
|
|
8419
|
+
working: "QA Wolf is working. It reports back here as it goes, which can take a few minutes."
|
|
8420
|
+
};
|
|
8421
|
+
// src/core/pluralize.ts
|
|
8422
|
+
function pluralize(count, singular, plural = `${singular}s`) {
|
|
8423
|
+
return `${String(count)} ${count === 1 ? singular : plural}`;
|
|
8424
|
+
}
|
|
8425
|
+
|
|
8403
8426
|
// src/core/messages/authErrors.ts
|
|
8404
8427
|
var authErrorMessages = {
|
|
8405
8428
|
identity: {
|
|
@@ -8413,7 +8436,14 @@ var authErrorMessages = {
|
|
|
8413
8436
|
rejected401: (noun) => `QA Wolf API rejected the${noun ? ` ${noun}` : ""} request (HTTP 401). Check your API key.`,
|
|
8414
8437
|
rejected402: (noun) => `QA Wolf API refused the${noun ? ` ${noun}` : ""} request (HTTP 402): billing prevented it.`,
|
|
8415
8438
|
rejected403: (noun) => `QA Wolf API rejected the${noun ? ` ${noun}` : ""} request (HTTP 403). Check that your API key has access to this environment.`,
|
|
8416
|
-
|
|
8439
|
+
notFound404Environment: (noun) => `QA Wolf API could not find ${noun ? `${noun} for that environment` : "that environment"} (HTTP 404). Check the --env value.`,
|
|
8440
|
+
notFound404Runner: (runnerId) => runnerId === undefined ? "That runner is not running (HTTP 404)." : `Runner ${runnerId} is not running (HTTP 404).`,
|
|
8441
|
+
runnerIsGone: "It was never launched, or it has since been terminated or idled out.",
|
|
8442
|
+
launchTheRunner: (runnerId) => runnerId === undefined ? "Launch one with qawolf runner launch --id <id>, or name a running one with --runner." : `Launch it with qawolf runner launch --id ${runnerId}, or send this to a different runner with --runner.`,
|
|
8443
|
+
notFound404Run: (runId) => `QA Wolf has no run ${runId ?? "by that id"} on this team (HTTP 404).`,
|
|
8444
|
+
runIdMayBeRunnerLocal: (runId) => `A run id printed by qawolf runner run belongs to that runner rather than to the platform, so this command cannot resolve it. Read that run with qawolf runner events run-status --run ${runId ?? "<id>"}.`,
|
|
8445
|
+
notFound404Record: (noun, id) => `QA Wolf has no ${noun} ${id} (HTTP 404).`,
|
|
8446
|
+
notFound404: (noun) => noun === undefined ? "QA Wolf found nothing matching the request (HTTP 404)." : `QA Wolf found nothing matching the ${noun} request (HTTP 404).`,
|
|
8417
8447
|
failedWithStatus: (status, noun) => `QA Wolf API${noun ? ` ${noun}` : ""} request failed (HTTP ${status}).`,
|
|
8418
8448
|
networkUnreachable: (baseUrl, noun) => `Could not reach the QA Wolf API at ${baseUrl}${noun ? ` to fetch ${noun}` : ""}. Check your network connection and QAWOLF_HOST_URL.`,
|
|
8419
8449
|
timedOut: (timeoutMs, noun) => `The QA Wolf API${noun ? ` ${noun}` : ""} request timed out after ${formatSeconds(timeoutMs)}. The work may still be finishing on the platform.`,
|
|
@@ -8669,7 +8699,7 @@ var flowsMessages = {
|
|
|
8669
8699
|
extractingBundle: "Extracting bundle",
|
|
8670
8700
|
downloadingTeamStorageAssets: "Downloading team-storage assets",
|
|
8671
8701
|
downloadingTeamStorageAssetsProgress: (current, total) => `Downloading team-storage assets (${String(current)}/${String(total)})`,
|
|
8672
|
-
|
|
8702
|
+
teamStorageRequiresTeam: "Team storage needs a team. Pull an environment to name its team, choose a workspace with 'qawolf auth switch', or use a team API key.",
|
|
8673
8703
|
summary: (result, assetsAbs) => {
|
|
8674
8704
|
const flows = pluralize(result.flowCount, "flow");
|
|
8675
8705
|
const envVars = result.envVarCount === 0 ? "" : ` and ${pluralize(result.envVarCount, "environment variable")}`;
|
|
@@ -8844,17 +8874,18 @@ var interactMessages = {
|
|
|
8844
8874
|
};
|
|
8845
8875
|
|
|
8846
8876
|
// src/core/messages/interactiveRunner/lifecycle.ts
|
|
8877
|
+
var pageAt = (url) => `Its runner page is at ${url}`;
|
|
8847
8878
|
var noRunnerId = "No runner id. Pass --runner, set QAWOLF_RUNNER_ID, or run qawolf runner launch first.";
|
|
8848
8879
|
var lifecycleMessages = {
|
|
8849
|
-
alreadyRunning: (id) => `Runner ${id} was already running
|
|
8880
|
+
alreadyRunning: (id, url) => `Runner ${id} was already running. ${pageAt(url)}`,
|
|
8850
8881
|
defaultNotRemembered: (id) => `Runner ${id} could not be written to .qawolf as this directory's default, so later commands will not find it on their own. Pass --runner ${id}, or set QAWOLF_RUNNER_ID=${id}.`,
|
|
8851
8882
|
defaultNotForgotten: (id) => `Runner ${id} was terminated, but it could not be removed from .qawolf as this directory's default, so later commands will still be sent to it. Pass --runner, or launch a new runner.`,
|
|
8852
8883
|
envRunnerIdShadowsLaunch: (launchedId, envId) => `QAWOLF_RUNNER_ID=${envId} is still set, so commands that omit --runner will keep targeting it instead of the runner just launched. Pass --runner ${launchedId} to address this one.`,
|
|
8853
8884
|
keptAlive: (id) => `Runner ${id} is alive, and its inactivity clock has been reset.`,
|
|
8854
8885
|
launchFailed: (id, error) => `Launching runner ${id} failed. ${error}`,
|
|
8855
8886
|
launchLost: (id, error) => `Launching runner ${id} failed. ${error}. The request may still have reached QA Wolf and started a runner, so relaunch the same id with qawolf runner launch --id ${id} to attach to it rather than start a second one, or terminate it with qawolf runner terminate --runner ${id}.`,
|
|
8856
|
-
launched: (id) => `Launched runner ${id}
|
|
8857
|
-
launchedForCommand: (id) => `No runner was given, so launched ${id} for this command. Its browser is fresh: nothing has been run on it and nothing is signed in. It bills until it is terminated or idles out, so terminate it with qawolf runner terminate --runner ${id} when you are done
|
|
8887
|
+
launched: (id, url) => `Launched runner ${id}. ${pageAt(url)}`,
|
|
8888
|
+
launchedForCommand: (id, url) => `No runner was given, so launched ${id} for this command. Its browser is fresh: nothing has been run on it and nothing is signed in. It bills until it is terminated or idles out, so terminate it with qawolf runner terminate --runner ${id} when you are done. ${pageAt(url)}`,
|
|
8858
8889
|
noRunnerIdForImport: `${noRunnerId} An install also needs a live run to go into, which a runner gets from qawolf runner run.`,
|
|
8859
8890
|
noRunnerIdForHighlight: `${noRunnerId} Highlighting also needs a live page to draw on, which a runner gets from its first run: run a flow on it with qawolf runner run.`,
|
|
8860
8891
|
noRunnerIdForInspect: `${noRunnerId} Inspecting also needs a page, which a runner gets from its first run: run a flow on it with qawolf runner run.`,
|
|
@@ -8865,7 +8896,14 @@ var lifecycleMessages = {
|
|
|
8865
8896
|
terminated: (id) => `Terminated runner ${id}.`,
|
|
8866
8897
|
runStopped: (id) => `Stopped the run on runner ${id}. The runner is still up, on whatever page the run reached.`,
|
|
8867
8898
|
nothingToStop: (id) => `Runner ${id} had nothing to stop. The run had already finished, or none had been submitted.`,
|
|
8868
|
-
runnerUnreachable: "The runner could not be reached. It may still be starting, or it may have terminated after inactivity. Retry, or launch it again."
|
|
8899
|
+
runnerUnreachable: "The runner could not be reached. It may still be starting, or it may have terminated after inactivity. Retry, or launch it again.",
|
|
8900
|
+
runnerIdCameFrom: (id, source) => ({
|
|
8901
|
+
environment: `The id ${id} came from QAWOLF_RUNNER_ID.`,
|
|
8902
|
+
flag: `The id ${id} came from --runner.`,
|
|
8903
|
+
given: `The id ${id} is the one this call named.`,
|
|
8904
|
+
launched: `Runner ${id} was launched for this command.`,
|
|
8905
|
+
stored: `The id ${id} came from the runner this directory last launched, recorded in .qawolf.`
|
|
8906
|
+
})[source]
|
|
8869
8907
|
};
|
|
8870
8908
|
|
|
8871
8909
|
// src/core/messages/interactiveRunner/list.ts
|
|
@@ -8964,7 +9002,9 @@ ${dir}`,
|
|
|
8964
9002
|
].join(`
|
|
8965
9003
|
`),
|
|
8966
9004
|
outerHopCarriedOver: (names) => `Carried over ${pluralize(names.length, "undeclared package")} from the project node_modules: ${listNames(names)}. Declare them in package.json "dependencies".`,
|
|
8967
|
-
moduleNotFoundHint: (pkg, projectDir) => projectDir === undefined ? `Hint: '${pkg}' could not be resolved. Run from within your flows project so its dependencies can be found.` : `Hint: '${pkg}' could not be resolved. Ensure it is declared in ${projectDir}/package.json "dependencies" and run npm install in that project
|
|
9005
|
+
moduleNotFoundHint: (pkg, projectDir) => projectDir === undefined ? `Hint: '${pkg}' could not be resolved. Run from within your flows project so its dependencies can be found.` : `Hint: '${pkg}' could not be resolved. Ensure it is declared in ${projectDir}/package.json "dependencies" and run npm install in that project.`,
|
|
9006
|
+
tsconfigUnparsedNotice: (projectDir) => `Not resolving path aliases: ${projectDir}/tsconfig.json is not valid JSON. Comments and trailing commas are not supported, here or on the platform. Remove them so "compilerOptions.paths" can be read.`,
|
|
9007
|
+
pathAliasNotFoundHint: (specifier, projectDir) => projectDir === undefined ? `Hint: '${specifier}' looks like a tsconfig path alias. Run from within your flows project so its tsconfig.json can be found.` : `Hint: '${specifier}' looks like a tsconfig path alias. Ensure "compilerOptions.paths" in ${projectDir}/tsconfig.json maps it to a file that exists.`
|
|
8968
9008
|
};
|
|
8969
9009
|
// src/core/messages/updateCheck.ts
|
|
8970
9010
|
var updateCheckMessages = {
|
|
@@ -9088,7 +9128,8 @@ var exitCodes = {
|
|
|
9088
9128
|
network: 4,
|
|
9089
9129
|
config: 5,
|
|
9090
9130
|
timeout: 6,
|
|
9091
|
-
payment: 7
|
|
9131
|
+
payment: 7,
|
|
9132
|
+
notFound: 8
|
|
9092
9133
|
};
|
|
9093
9134
|
function exit(code, message, proc = process) {
|
|
9094
9135
|
if (message !== undefined && message.length > 0) {
|
|
@@ -9237,8 +9278,10 @@ function resolveHostUrl(env) {
|
|
|
9237
9278
|
return configuredHostUrl.replace(/\/+$/, "");
|
|
9238
9279
|
}
|
|
9239
9280
|
|
|
9240
|
-
// src/
|
|
9241
|
-
|
|
9281
|
+
// src/shell/keyring.ts
|
|
9282
|
+
function loadEntryClass() {
|
|
9283
|
+
return import("@napi-rs/keyring").then((keyring) => keyring.Entry);
|
|
9284
|
+
}
|
|
9242
9285
|
|
|
9243
9286
|
// src/core/deviceAuth/tokenExpiry.ts
|
|
9244
9287
|
function readAccessTokenExpiry(accessToken) {
|
|
@@ -11881,6 +11924,56 @@ function handlePipeResult(left, next, ctx) {
|
|
|
11881
11924
|
}
|
|
11882
11925
|
return next._zod.run({ value: left.value, issues: left.issues, fallback: left.fallback }, ctx);
|
|
11883
11926
|
}
|
|
11927
|
+
var $ZodCodec = /* @__PURE__ */ $constructor("$ZodCodec", (inst, def) => {
|
|
11928
|
+
$ZodType.init(inst, def);
|
|
11929
|
+
defineLazy(inst._zod, "values", () => def.in._zod.values);
|
|
11930
|
+
defineLazy(inst._zod, "optin", () => def.in._zod.optin);
|
|
11931
|
+
defineLazy(inst._zod, "optout", () => def.out._zod.optout);
|
|
11932
|
+
defineLazy(inst._zod, "propValues", () => def.in._zod.propValues);
|
|
11933
|
+
inst._zod.parse = (payload, ctx) => {
|
|
11934
|
+
const direction = ctx.direction || "forward";
|
|
11935
|
+
if (direction === "forward") {
|
|
11936
|
+
const left = def.in._zod.run(payload, ctx);
|
|
11937
|
+
if (left instanceof Promise) {
|
|
11938
|
+
return left.then((left) => handleCodecAResult(left, def, ctx));
|
|
11939
|
+
}
|
|
11940
|
+
return handleCodecAResult(left, def, ctx);
|
|
11941
|
+
} else {
|
|
11942
|
+
const right = def.out._zod.run(payload, ctx);
|
|
11943
|
+
if (right instanceof Promise) {
|
|
11944
|
+
return right.then((right) => handleCodecAResult(right, def, ctx));
|
|
11945
|
+
}
|
|
11946
|
+
return handleCodecAResult(right, def, ctx);
|
|
11947
|
+
}
|
|
11948
|
+
};
|
|
11949
|
+
});
|
|
11950
|
+
function handleCodecAResult(result, def, ctx) {
|
|
11951
|
+
if (result.issues.length) {
|
|
11952
|
+
result.aborted = true;
|
|
11953
|
+
return result;
|
|
11954
|
+
}
|
|
11955
|
+
const direction = ctx.direction || "forward";
|
|
11956
|
+
if (direction === "forward") {
|
|
11957
|
+
const transformed = def.transform(result.value, result);
|
|
11958
|
+
if (transformed instanceof Promise) {
|
|
11959
|
+
return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx));
|
|
11960
|
+
}
|
|
11961
|
+
return handleCodecTxResult(result, transformed, def.out, ctx);
|
|
11962
|
+
} else {
|
|
11963
|
+
const transformed = def.reverseTransform(result.value, result);
|
|
11964
|
+
if (transformed instanceof Promise) {
|
|
11965
|
+
return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx));
|
|
11966
|
+
}
|
|
11967
|
+
return handleCodecTxResult(result, transformed, def.in, ctx);
|
|
11968
|
+
}
|
|
11969
|
+
}
|
|
11970
|
+
function handleCodecTxResult(left, value, nextSchema, ctx) {
|
|
11971
|
+
if (left.issues.length) {
|
|
11972
|
+
left.aborted = true;
|
|
11973
|
+
return left;
|
|
11974
|
+
}
|
|
11975
|
+
return nextSchema._zod.run({ value, issues: left.issues }, ctx);
|
|
11976
|
+
}
|
|
11884
11977
|
var $ZodReadonly = /* @__PURE__ */ $constructor("$ZodReadonly", (inst, def) => {
|
|
11885
11978
|
$ZodType.init(inst, def);
|
|
11886
11979
|
defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
|
|
@@ -14426,6 +14519,19 @@ function pipe(in_, out) {
|
|
|
14426
14519
|
out
|
|
14427
14520
|
});
|
|
14428
14521
|
}
|
|
14522
|
+
var ZodCodec = /* @__PURE__ */ $constructor("ZodCodec", (inst, def) => {
|
|
14523
|
+
ZodPipe.init(inst, def);
|
|
14524
|
+
$ZodCodec.init(inst, def);
|
|
14525
|
+
});
|
|
14526
|
+
function codec(in_, out, params) {
|
|
14527
|
+
return new ZodCodec({
|
|
14528
|
+
type: "pipe",
|
|
14529
|
+
in: in_,
|
|
14530
|
+
out,
|
|
14531
|
+
transform: params.decode,
|
|
14532
|
+
reverseTransform: params.encode
|
|
14533
|
+
});
|
|
14534
|
+
}
|
|
14429
14535
|
var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
|
|
14430
14536
|
$ZodReadonly.init(inst, def);
|
|
14431
14537
|
ZodType.init(inst, def);
|
|
@@ -14635,7 +14741,6 @@ function resolveWorkosConfig(publishedClientId) {
|
|
|
14635
14741
|
|
|
14636
14742
|
// src/domains/auth/store/delete.ts
|
|
14637
14743
|
import { join as join2 } from "node:path";
|
|
14638
|
-
import { Entry } from "@napi-rs/keyring";
|
|
14639
14744
|
|
|
14640
14745
|
// src/domains/auth/store/constants.ts
|
|
14641
14746
|
var service = "qawolf-cli";
|
|
@@ -14645,8 +14750,9 @@ var tokensAccount = "oauth-tokens";
|
|
|
14645
14750
|
var tokensFile = "tokens.json";
|
|
14646
14751
|
|
|
14647
14752
|
// src/domains/auth/store/delete.ts
|
|
14648
|
-
function deleteFromKeychain() {
|
|
14753
|
+
async function deleteFromKeychain() {
|
|
14649
14754
|
try {
|
|
14755
|
+
const Entry = await loadEntryClass();
|
|
14650
14756
|
new Entry(service, account).deletePassword();
|
|
14651
14757
|
return "deleted";
|
|
14652
14758
|
} catch {
|
|
@@ -14665,14 +14771,13 @@ async function deleteFromFile(configDir, fs) {
|
|
|
14665
14771
|
}
|
|
14666
14772
|
async function deleteApiKey(configDir, fs) {
|
|
14667
14773
|
const [keychain, file] = await Promise.all([
|
|
14668
|
-
|
|
14774
|
+
deleteFromKeychain(),
|
|
14669
14775
|
deleteFromFile(configDir, fs)
|
|
14670
14776
|
]);
|
|
14671
14777
|
return { keychain, file };
|
|
14672
14778
|
}
|
|
14673
14779
|
// src/domains/auth/store/hasStoredCredentials.ts
|
|
14674
14780
|
import { join as join3 } from "node:path";
|
|
14675
|
-
import { Entry as Entry2 } from "@napi-rs/keyring";
|
|
14676
14781
|
async function fileExists(path, fs) {
|
|
14677
14782
|
try {
|
|
14678
14783
|
await fs.readFile(path);
|
|
@@ -14681,9 +14786,10 @@ async function fileExists(path, fs) {
|
|
|
14681
14786
|
return !isNoEntError(err);
|
|
14682
14787
|
}
|
|
14683
14788
|
}
|
|
14684
|
-
function keychainHolds(entryAccount) {
|
|
14789
|
+
async function keychainHolds(entryAccount) {
|
|
14685
14790
|
try {
|
|
14686
|
-
|
|
14791
|
+
const Entry = await loadEntryClass();
|
|
14792
|
+
return Boolean(new Entry(service, entryAccount).getPassword());
|
|
14687
14793
|
} catch {
|
|
14688
14794
|
return false;
|
|
14689
14795
|
}
|
|
@@ -14693,7 +14799,9 @@ async function hasStoredCredentials(configDir, fs) {
|
|
|
14693
14799
|
fileExists(join3(configDir, credentialsFile), fs),
|
|
14694
14800
|
fileExists(join3(configDir, tokensFile), fs)
|
|
14695
14801
|
]);
|
|
14696
|
-
|
|
14802
|
+
if (apiKeyFile || tokenFile)
|
|
14803
|
+
return true;
|
|
14804
|
+
return await keychainHolds(account) || await keychainHolds(tokensAccount);
|
|
14697
14805
|
}
|
|
14698
14806
|
// src/domains/auth/store/load.ts
|
|
14699
14807
|
import { join as join4 } from "node:path";
|
|
@@ -14716,7 +14824,8 @@ var oauthTokensSchema = object({
|
|
|
14716
14824
|
async function loadApiKey(configDir, deps) {
|
|
14717
14825
|
const errors = {};
|
|
14718
14826
|
try {
|
|
14719
|
-
const
|
|
14827
|
+
const Entry = await deps.loadEntryClass();
|
|
14828
|
+
const entry = new Entry(service, account);
|
|
14720
14829
|
const key = entry.getPassword();
|
|
14721
14830
|
if (key)
|
|
14722
14831
|
return { found: true, key, source: "keychain" };
|
|
@@ -14737,7 +14846,6 @@ async function loadApiKey(configDir, deps) {
|
|
|
14737
14846
|
}
|
|
14738
14847
|
// src/domains/auth/store/save.ts
|
|
14739
14848
|
import { join as join5 } from "node:path";
|
|
14740
|
-
import { Entry as Entry3 } from "@napi-rs/keyring";
|
|
14741
14849
|
async function saveToFile(configDir, key, fs) {
|
|
14742
14850
|
const payload = { apiKey: key };
|
|
14743
14851
|
await fs.mkdir(configDir, { recursive: true, mode: 448 });
|
|
@@ -14745,7 +14853,8 @@ async function saveToFile(configDir, key, fs) {
|
|
|
14745
14853
|
}
|
|
14746
14854
|
async function saveApiKey(configDir, key, fs) {
|
|
14747
14855
|
try {
|
|
14748
|
-
const
|
|
14856
|
+
const Entry = await loadEntryClass();
|
|
14857
|
+
const entry = new Entry(service, account);
|
|
14749
14858
|
entry.setPassword(key);
|
|
14750
14859
|
return { stored: "keychain" };
|
|
14751
14860
|
} catch (err) {
|
|
@@ -14773,7 +14882,8 @@ function parseTokens(raw) {
|
|
|
14773
14882
|
async function loadTokens(configDir, deps) {
|
|
14774
14883
|
const errors = {};
|
|
14775
14884
|
try {
|
|
14776
|
-
const
|
|
14885
|
+
const Entry = await deps.loadEntryClass();
|
|
14886
|
+
const raw = new Entry(service, tokensAccount).getPassword();
|
|
14777
14887
|
if (raw) {
|
|
14778
14888
|
const tokens = parseTokens(raw);
|
|
14779
14889
|
if (tokens)
|
|
@@ -14798,7 +14908,6 @@ async function loadTokens(configDir, deps) {
|
|
|
14798
14908
|
// src/domains/auth/store/saveTokens.ts
|
|
14799
14909
|
import { randomUUID } from "node:crypto";
|
|
14800
14910
|
import { join as join7 } from "node:path";
|
|
14801
|
-
import { Entry as Entry4 } from "@napi-rs/keyring";
|
|
14802
14911
|
async function saveToFile2(configDir, tokens, fs) {
|
|
14803
14912
|
await fs.mkdir(configDir, { recursive: true, mode: 448 });
|
|
14804
14913
|
const target = join7(configDir, tokensFile);
|
|
@@ -14815,11 +14924,13 @@ async function saveToFile2(configDir, tokens, fs) {
|
|
|
14815
14924
|
}
|
|
14816
14925
|
async function saveTokens(configDir, tokens, fs) {
|
|
14817
14926
|
try {
|
|
14818
|
-
|
|
14927
|
+
const Entry = await loadEntryClass();
|
|
14928
|
+
new Entry(service, tokensAccount).setPassword(JSON.stringify(tokens));
|
|
14819
14929
|
return { stored: "keychain" };
|
|
14820
14930
|
} catch (err) {
|
|
14821
14931
|
try {
|
|
14822
|
-
|
|
14932
|
+
const Entry = await loadEntryClass();
|
|
14933
|
+
new Entry(service, tokensAccount).deletePassword();
|
|
14823
14934
|
} catch {}
|
|
14824
14935
|
await saveToFile2(configDir, tokens, fs);
|
|
14825
14936
|
return { stored: "file", keychainError: errorMessage(err) };
|
|
@@ -14882,7 +14993,7 @@ async function resolveOauthToken(configDir, deps) {
|
|
|
14882
14993
|
// src/domains/auth/resolve.ts
|
|
14883
14994
|
function makeOauthDeps(fs) {
|
|
14884
14995
|
return {
|
|
14885
|
-
loadTokens: (configDir) => loadTokens(configDir, {
|
|
14996
|
+
loadTokens: (configDir) => loadTokens(configDir, { loadEntryClass, fs }),
|
|
14886
14997
|
refreshTokens: async ({ refreshToken, organizationId, clientId }) => {
|
|
14887
14998
|
const config = resolveWorkosConfig(clientId);
|
|
14888
14999
|
if (!config.configured) {
|
|
@@ -14904,7 +15015,7 @@ function makeOauthDeps(fs) {
|
|
|
14904
15015
|
}
|
|
14905
15016
|
function makeDefaultDeps(fs) {
|
|
14906
15017
|
return {
|
|
14907
|
-
loadApiKey: (configDir) => loadApiKey(configDir, {
|
|
15018
|
+
loadApiKey: (configDir) => loadApiKey(configDir, { loadEntryClass, fs }),
|
|
14908
15019
|
resolveOauth: (configDir) => resolveOauthToken(configDir, makeOauthDeps(fs)),
|
|
14909
15020
|
env: process.env
|
|
14910
15021
|
};
|
|
@@ -15017,6 +15128,47 @@ function createLoggingSystem(opts) {
|
|
|
15017
15128
|
};
|
|
15018
15129
|
}
|
|
15019
15130
|
|
|
15131
|
+
// src/core/publicApi/notFoundSubject.ts
|
|
15132
|
+
var runnerRoutesThatNameNoRunner = new Set([
|
|
15133
|
+
"runner.launch",
|
|
15134
|
+
"runner.list"
|
|
15135
|
+
]);
|
|
15136
|
+
var runRoutesThatResolveOneRun = new Set([
|
|
15137
|
+
"run.diagnose",
|
|
15138
|
+
"run.get",
|
|
15139
|
+
"run.reattempt",
|
|
15140
|
+
"run.stop"
|
|
15141
|
+
]);
|
|
15142
|
+
var recordFieldNouns = [
|
|
15143
|
+
["sessionId", "session"],
|
|
15144
|
+
["triggerId", "trigger"],
|
|
15145
|
+
["issueId", "issue"],
|
|
15146
|
+
["flowId", "flow"],
|
|
15147
|
+
["filePath", "file"]
|
|
15148
|
+
];
|
|
15149
|
+
function field(input, name) {
|
|
15150
|
+
if (typeof input !== "object" || input === null)
|
|
15151
|
+
return;
|
|
15152
|
+
const value = input[name];
|
|
15153
|
+
return typeof value === "string" ? value : undefined;
|
|
15154
|
+
}
|
|
15155
|
+
function notFoundSubject(contractName, input) {
|
|
15156
|
+
if (contractName.startsWith("runner.") && !runnerRoutesThatNameNoRunner.has(contractName)) {
|
|
15157
|
+
return { kind: "runner", runnerId: field(input, "id") };
|
|
15158
|
+
}
|
|
15159
|
+
if (runRoutesThatResolveOneRun.has(contractName)) {
|
|
15160
|
+
return { kind: "run", runId: field(input, "runId") };
|
|
15161
|
+
}
|
|
15162
|
+
for (const [name, noun] of recordFieldNouns) {
|
|
15163
|
+
const id = field(input, name);
|
|
15164
|
+
if (id !== undefined)
|
|
15165
|
+
return { id, kind: "record", noun };
|
|
15166
|
+
}
|
|
15167
|
+
if (field(input, "environmentId") !== undefined)
|
|
15168
|
+
return { kind: "environment" };
|
|
15169
|
+
return { kind: "other" };
|
|
15170
|
+
}
|
|
15171
|
+
|
|
15020
15172
|
// src/core/publicApi/flagKind.ts
|
|
15021
15173
|
function flagKind(schema) {
|
|
15022
15174
|
if (schema.type === "string")
|
|
@@ -15187,6 +15339,42 @@ function applyWorkspaceId(inputSchema, input, workspaceId) {
|
|
|
15187
15339
|
return { ...input, workspaceId };
|
|
15188
15340
|
}
|
|
15189
15341
|
|
|
15342
|
+
// src/shell/platform/describeNotFound.ts
|
|
15343
|
+
var m = authMessages.errors.request;
|
|
15344
|
+
var saysNothingMore = (reason) => /^(\w+ )*not ?found\.?$/i.test(reason.trim());
|
|
15345
|
+
function describeNotFound(subject, noun, reason) {
|
|
15346
|
+
const explained = reason && !saysNothingMore(reason) ? reason : undefined;
|
|
15347
|
+
const say = (own) => {
|
|
15348
|
+
const body = [explained ? undefined : own.guess, own.guidance].filter((line) => line);
|
|
15349
|
+
return {
|
|
15350
|
+
error: explained ? `${explained} (HTTP 404)` : own.statement,
|
|
15351
|
+
exitCode: exitCodes.notFound,
|
|
15352
|
+
...body.length > 0 ? { errorBody: body.join(`
|
|
15353
|
+
`) } : {}
|
|
15354
|
+
};
|
|
15355
|
+
};
|
|
15356
|
+
switch (subject?.kind) {
|
|
15357
|
+
case "runner":
|
|
15358
|
+
return say({
|
|
15359
|
+
guess: m.runnerIsGone,
|
|
15360
|
+
guidance: m.launchTheRunner(subject.runnerId),
|
|
15361
|
+
statement: m.notFound404Runner(subject.runnerId)
|
|
15362
|
+
});
|
|
15363
|
+
case "run":
|
|
15364
|
+
return say({
|
|
15365
|
+
guess: m.runIdMayBeRunnerLocal(subject.runId),
|
|
15366
|
+
statement: m.notFound404Run(subject.runId)
|
|
15367
|
+
});
|
|
15368
|
+
case "record":
|
|
15369
|
+
return say({ statement: m.notFound404Record(subject.noun, subject.id) });
|
|
15370
|
+
case "other":
|
|
15371
|
+
return say({ statement: m.notFound404(noun) });
|
|
15372
|
+
case "environment":
|
|
15373
|
+
case undefined:
|
|
15374
|
+
return say({ statement: m.notFound404Environment(noun) });
|
|
15375
|
+
}
|
|
15376
|
+
}
|
|
15377
|
+
|
|
15190
15378
|
// src/shell/platform/parseErrorBody.ts
|
|
15191
15379
|
var defaultMaxLength = 1024;
|
|
15192
15380
|
function asRecord(value) {
|
|
@@ -15229,69 +15417,69 @@ function clip(message, maxLength) {
|
|
|
15229
15417
|
}
|
|
15230
15418
|
|
|
15231
15419
|
// src/shell/platform/describeErrors.ts
|
|
15232
|
-
var
|
|
15420
|
+
var m2 = authMessages.errors;
|
|
15233
15421
|
var inlineReasonMaxLength = 200;
|
|
15234
15422
|
function describeIdentityError(err) {
|
|
15235
15423
|
if (err.kind === "http") {
|
|
15236
15424
|
if (err.status === 401 || err.status === 403) {
|
|
15237
15425
|
return {
|
|
15238
|
-
error:
|
|
15426
|
+
error: m2.identity.invalidOrUnauthorized,
|
|
15239
15427
|
...err.status === 401 ? { exitCode: exitCodes.auth } : {}
|
|
15240
15428
|
};
|
|
15241
15429
|
}
|
|
15242
15430
|
return {
|
|
15243
|
-
error:
|
|
15431
|
+
error: m2.identity.couldNotVerify(parseErrorBody(err.body, inlineReasonMaxLength), err.status)
|
|
15244
15432
|
};
|
|
15245
15433
|
}
|
|
15246
15434
|
if (err.kind === "network") {
|
|
15247
|
-
return { error:
|
|
15435
|
+
return { error: m2.identity.couldNotVerifyNetwork(err.cause.message) };
|
|
15248
15436
|
}
|
|
15249
15437
|
if (err.kind === "timeout") {
|
|
15250
|
-
return { error:
|
|
15438
|
+
return { error: m2.identity.timedOut(err.timeoutMs) };
|
|
15251
15439
|
}
|
|
15252
|
-
return { error:
|
|
15440
|
+
return { error: m2.identity.unexpectedFormat };
|
|
15253
15441
|
}
|
|
15254
|
-
function describeRequestError(err, baseUrl, noun) {
|
|
15442
|
+
function describeRequestError(err, baseUrl, noun, notFound) {
|
|
15255
15443
|
if (err.kind === "http") {
|
|
15256
15444
|
const reason = parseErrorBody(err.body);
|
|
15257
15445
|
const body = reason ? { errorBody: reason } : {};
|
|
15258
15446
|
if (err.status === 401)
|
|
15259
15447
|
return {
|
|
15260
|
-
error:
|
|
15448
|
+
error: m2.request.rejected401(noun),
|
|
15261
15449
|
exitCode: exitCodes.auth,
|
|
15262
15450
|
...body
|
|
15263
15451
|
};
|
|
15264
15452
|
if (err.status === 402)
|
|
15265
15453
|
return {
|
|
15266
|
-
error:
|
|
15454
|
+
error: m2.request.rejected402(noun),
|
|
15267
15455
|
exitCode: exitCodes.payment,
|
|
15268
15456
|
...body
|
|
15269
15457
|
};
|
|
15270
15458
|
if (err.status === 403)
|
|
15271
|
-
return { error:
|
|
15459
|
+
return { error: m2.request.rejected403(noun), ...body };
|
|
15272
15460
|
if (err.status === 404)
|
|
15273
|
-
return
|
|
15274
|
-
return { error:
|
|
15461
|
+
return describeNotFound(notFound, noun, reason);
|
|
15462
|
+
return { error: m2.request.failedWithStatus(err.status, noun), ...body };
|
|
15275
15463
|
}
|
|
15276
15464
|
if (err.kind === "network") {
|
|
15277
|
-
return { error:
|
|
15465
|
+
return { error: m2.request.networkUnreachable(baseUrl, noun) };
|
|
15278
15466
|
}
|
|
15279
15467
|
if (err.kind === "timeout") {
|
|
15280
|
-
return { error:
|
|
15468
|
+
return { error: m2.request.timedOut(err.timeoutMs, noun) };
|
|
15281
15469
|
}
|
|
15282
|
-
return { error:
|
|
15470
|
+
return { error: m2.request.unexpectedResponse(noun) };
|
|
15283
15471
|
}
|
|
15284
15472
|
function describeBundleDownloadError(err) {
|
|
15285
15473
|
if (err.kind === "http") {
|
|
15286
15474
|
if (err.status === 401 || err.status === 403)
|
|
15287
|
-
return
|
|
15288
|
-
return
|
|
15475
|
+
return m2.bundle.linkExpired;
|
|
15476
|
+
return m2.bundle.failedWithStatus(err.status);
|
|
15289
15477
|
}
|
|
15290
15478
|
if (err.kind === "network")
|
|
15291
|
-
return
|
|
15479
|
+
return m2.bundle.networkUnreachable;
|
|
15292
15480
|
if (err.kind === "timeout")
|
|
15293
|
-
return
|
|
15294
|
-
return
|
|
15481
|
+
return m2.bundle.timedOut(err.timeoutMs);
|
|
15482
|
+
return m2.bundle.malformed;
|
|
15295
15483
|
}
|
|
15296
15484
|
function describeTeamStorageDownloadError(path, err) {
|
|
15297
15485
|
if (err.kind === "http") {
|
|
@@ -15352,12 +15540,16 @@ function callPublicApi(trpc, contract, input, options) {
|
|
|
15352
15540
|
return trpc.mutation(path, input, contract.output, options);
|
|
15353
15541
|
}
|
|
15354
15542
|
function makeCallPublicApiMethod(trpc, deps, readBackoffMs) {
|
|
15355
|
-
return async (contract, input, options) =>
|
|
15356
|
-
|
|
15357
|
-
|
|
15358
|
-
|
|
15359
|
-
|
|
15360
|
-
|
|
15543
|
+
return async (contract, input, options) => {
|
|
15544
|
+
const sent = applyWorkspaceId(contract.input, input, deps.workspaceId);
|
|
15545
|
+
const subject = notFoundSubject(contract.name, sent);
|
|
15546
|
+
return requestWithRetry({
|
|
15547
|
+
call: () => callPublicApi(trpc, contract, sent, options),
|
|
15548
|
+
backoffMs: contract.kind === "read" ? readBackoffMs : [],
|
|
15549
|
+
describe: (err) => describeRequestError(err, deps.baseUrl, contract.name, subject),
|
|
15550
|
+
sleep: deps.sleep
|
|
15551
|
+
});
|
|
15552
|
+
};
|
|
15361
15553
|
}
|
|
15362
15554
|
|
|
15363
15555
|
// node_modules/superjson/dist/double-indexed-kv.js
|
|
@@ -18988,7 +19180,8 @@ var environmentListItemSchema = object({
|
|
|
18988
19180
|
slug: string2()
|
|
18989
19181
|
});
|
|
18990
19182
|
var environmentWithVariablesResponseSchema = object({
|
|
18991
|
-
environmentVariables: record(string2(), string2())
|
|
19183
|
+
environmentVariables: record(string2(), string2()),
|
|
19184
|
+
teamId: string2()
|
|
18992
19185
|
});
|
|
18993
19186
|
var flowListItemSchema = object({
|
|
18994
19187
|
flowId: string2(),
|
|
@@ -19265,7 +19458,10 @@ async function writeTeamStorageAssets(args, deps) {
|
|
|
19265
19458
|
|
|
19266
19459
|
// src/shell/platform/teamStorageMethods.ts
|
|
19267
19460
|
function createTeamStorageMethods(trpc, deps, fs, getIdentity) {
|
|
19268
|
-
async function list() {
|
|
19461
|
+
async function list(opts) {
|
|
19462
|
+
if (opts?.teamId !== undefined) {
|
|
19463
|
+
return listTeamStorageFiles(trpc, { teamId: opts.teamId }, deps);
|
|
19464
|
+
}
|
|
19269
19465
|
if (deps.workspaceId !== undefined) {
|
|
19270
19466
|
return listTeamStorageFiles(trpc, { teamId: deps.workspaceId }, deps);
|
|
19271
19467
|
}
|
|
@@ -19275,7 +19471,7 @@ function createTeamStorageMethods(trpc, deps, fs, getIdentity) {
|
|
|
19275
19471
|
if (!("team" in identity.value)) {
|
|
19276
19472
|
return {
|
|
19277
19473
|
ok: false,
|
|
19278
|
-
error: flowsMessages.pull.
|
|
19474
|
+
error: flowsMessages.pull.teamStorageRequiresTeam
|
|
19279
19475
|
};
|
|
19280
19476
|
}
|
|
19281
19477
|
return listTeamStorageFiles(trpc, { teamId: identity.value.team.id }, deps);
|
|
@@ -19283,7 +19479,7 @@ function createTeamStorageMethods(trpc, deps, fs, getIdentity) {
|
|
|
19283
19479
|
return {
|
|
19284
19480
|
listTeamStorageFiles: list,
|
|
19285
19481
|
async syncTeamStorageAssets(assetsAbs, opts) {
|
|
19286
|
-
const files = await list();
|
|
19482
|
+
const files = await list({ teamId: opts?.teamId });
|
|
19287
19483
|
if (!files.ok)
|
|
19288
19484
|
return files;
|
|
19289
19485
|
return downloadTeamStorageAssets({ assetsAbs, files: files.value }, { fetch: deps.fetch, fs, onProgress: opts?.onProgress });
|
|
@@ -19313,16 +19509,14 @@ function createPlatformClient(apiKey, deps) {
|
|
|
19313
19509
|
...createTeamStorageMethods(trpc, deps, fs, identityMethods.getIdentity),
|
|
19314
19510
|
getFlowsBundleUrl: getFlowsBundleUrlImpl,
|
|
19315
19511
|
callPublicApi: makeCallPublicApiMethod(trpc, deps, requestBackoffMs2),
|
|
19316
|
-
async
|
|
19512
|
+
async getEnvironmentWithVariables(envId) {
|
|
19317
19513
|
const result = await requestWithRetry({
|
|
19318
19514
|
call: () => trpc.query("environment.getEnvironmentWithVariables", { id: envId }, environmentWithVariablesResponseSchema),
|
|
19319
19515
|
backoffMs: requestBackoffMs2,
|
|
19320
19516
|
describe: (err) => describeRequestError(err, deps.baseUrl, "env-vars"),
|
|
19321
19517
|
sleep: deps.sleep
|
|
19322
19518
|
});
|
|
19323
|
-
|
|
19324
|
-
return result;
|
|
19325
|
-
return { ok: true, value: result.value.environmentVariables };
|
|
19519
|
+
return result;
|
|
19326
19520
|
},
|
|
19327
19521
|
async downloadBundle(envId) {
|
|
19328
19522
|
const urlResult = await getFlowsBundleUrlImpl(envId);
|
|
@@ -20000,7 +20194,7 @@ function p$1(l, e) {
|
|
|
20000
20194
|
function g(l, e) {
|
|
20001
20195
|
return (e.label ?? String(e.value)).toLowerCase().includes(l.toLowerCase());
|
|
20002
20196
|
}
|
|
20003
|
-
function
|
|
20197
|
+
function m3(l, e) {
|
|
20004
20198
|
if (e)
|
|
20005
20199
|
return l ? e : e[0];
|
|
20006
20200
|
}
|
|
@@ -20050,7 +20244,7 @@ var T$1 = class T extends V {
|
|
|
20050
20244
|
this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
|
|
20051
20245
|
return;
|
|
20052
20246
|
}
|
|
20053
|
-
i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value =
|
|
20247
|
+
i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m3(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t.name === "tab" || this.isNavigating && t.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
|
|
20054
20248
|
}
|
|
20055
20249
|
deselectAll() {
|
|
20056
20250
|
this.selectedValues = [];
|
|
@@ -20142,6 +20336,30 @@ class a extends V {
|
|
|
20142
20336
|
});
|
|
20143
20337
|
}
|
|
20144
20338
|
}
|
|
20339
|
+
class n extends V {
|
|
20340
|
+
get userInputWithCursor() {
|
|
20341
|
+
if (this.state === "submit")
|
|
20342
|
+
return this.userInput;
|
|
20343
|
+
const t = this.userInput;
|
|
20344
|
+
if (this.cursor >= t.length)
|
|
20345
|
+
return `${this.userInput}█`;
|
|
20346
|
+
const e = t.slice(0, this.cursor), [s, ...r] = t.slice(this.cursor);
|
|
20347
|
+
return `${e}${styleText("inverse", s)}${r.join("")}`;
|
|
20348
|
+
}
|
|
20349
|
+
get cursor() {
|
|
20350
|
+
return this._cursor;
|
|
20351
|
+
}
|
|
20352
|
+
constructor(t) {
|
|
20353
|
+
super({
|
|
20354
|
+
...t,
|
|
20355
|
+
initialUserInput: t.initialUserInput ?? t.initialValue
|
|
20356
|
+
}), this.on("userInput", (e) => {
|
|
20357
|
+
this._setValue(e);
|
|
20358
|
+
}), this.on("finalize", () => {
|
|
20359
|
+
this.value || (this.value = t.defaultValue), this.value === undefined && (this.value = "");
|
|
20360
|
+
});
|
|
20361
|
+
}
|
|
20362
|
+
}
|
|
20145
20363
|
|
|
20146
20364
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
20147
20365
|
import { styleText as styleText2, stripVTControlCharacters } from "node:util";
|
|
@@ -20752,14 +20970,56 @@ ${e.value}` : e.value;
|
|
|
20752
20970
|
}
|
|
20753
20971
|
};
|
|
20754
20972
|
};
|
|
20973
|
+
var text = (t) => new n({
|
|
20974
|
+
validate: t.validate,
|
|
20975
|
+
placeholder: t.placeholder,
|
|
20976
|
+
defaultValue: t.defaultValue,
|
|
20977
|
+
initialValue: t.initialValue,
|
|
20978
|
+
output: t.output,
|
|
20979
|
+
signal: t.signal,
|
|
20980
|
+
input: t.input,
|
|
20981
|
+
render() {
|
|
20982
|
+
const i = t?.withGuide ?? settings.withGuide, s = `${`${i ? `${styleText2("gray", S_BAR)}
|
|
20983
|
+
` : ""}${symbol(this.state)} `}${t.message}
|
|
20984
|
+
`, c = t.placeholder ? styleText2("inverse", t.placeholder[0]) + styleText2("dim", t.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o = this.userInput ? this.userInputWithCursor : c, a = this.value ?? "";
|
|
20985
|
+
switch (this.state) {
|
|
20986
|
+
case "error": {
|
|
20987
|
+
const n = this.error ? ` ${styleText2("yellow", this.error)}` : "", r = i ? `${styleText2("yellow", S_BAR)} ` : "", d = i ? styleText2("yellow", S_BAR_END) : "";
|
|
20988
|
+
return `${s.trim()}
|
|
20989
|
+
${r}${o}
|
|
20990
|
+
${d}${n}
|
|
20991
|
+
`;
|
|
20992
|
+
}
|
|
20993
|
+
case "submit": {
|
|
20994
|
+
const n = a ? ` ${styleText2("dim", a)}` : "", r = i ? styleText2("gray", S_BAR) : "";
|
|
20995
|
+
return `${s}${r}${n}`;
|
|
20996
|
+
}
|
|
20997
|
+
case "cancel": {
|
|
20998
|
+
const n = a ? ` ${styleText2(["strikethrough", "dim"], a)}` : "", r = i ? styleText2("gray", S_BAR) : "";
|
|
20999
|
+
return `${s}${r}${n}${a.trim() ? `
|
|
21000
|
+
${r}` : ""}`;
|
|
21001
|
+
}
|
|
21002
|
+
default: {
|
|
21003
|
+
const n = i ? `${styleText2("cyan", S_BAR)} ` : "", r = i ? styleText2("cyan", S_BAR_END) : "";
|
|
21004
|
+
return `${s}${n}${o}
|
|
21005
|
+
${r}
|
|
21006
|
+
`;
|
|
21007
|
+
}
|
|
21008
|
+
}
|
|
21009
|
+
}
|
|
21010
|
+
}).prompt();
|
|
20755
21011
|
|
|
20756
21012
|
// src/shell/ui/clack/theme.ts
|
|
21013
|
+
import { styleText as styleText3 } from "node:util";
|
|
20757
21014
|
var qaWolfBlueBg = "\x1B[48;2;59;59;239m";
|
|
20758
21015
|
var whiteBold = "\x1B[97;1m";
|
|
20759
21016
|
var reset = "\x1B[0m";
|
|
20760
21017
|
function styledTitle(title) {
|
|
20761
21018
|
return `${qaWolfBlueBg}${whiteBold} ${title} ${reset}`;
|
|
20762
21019
|
}
|
|
21020
|
+
function replySymbol() {
|
|
21021
|
+
return styleText3("cyan", "◇");
|
|
21022
|
+
}
|
|
20763
21023
|
|
|
20764
21024
|
// src/shell/ui/clack/styledClack.ts
|
|
20765
21025
|
function createStyledClack() {
|
|
@@ -20770,6 +21030,7 @@ function createStyledClack() {
|
|
|
20770
21030
|
cancel,
|
|
20771
21031
|
confirm,
|
|
20772
21032
|
password,
|
|
21033
|
+
text,
|
|
20773
21034
|
autocomplete,
|
|
20774
21035
|
select,
|
|
20775
21036
|
isCancel,
|
|
@@ -20873,6 +21134,12 @@ function createAgentRenderers() {
|
|
|
20873
21134
|
gap: () => writeStderrLine(""),
|
|
20874
21135
|
stream: (_data, line) => writeStdoutRaw(`${line}
|
|
20875
21136
|
`),
|
|
21137
|
+
transcript: ({ body, headline }) => writeStdoutRaw(`**${headline}**
|
|
21138
|
+
|
|
21139
|
+
${body}
|
|
21140
|
+
|
|
21141
|
+
`),
|
|
21142
|
+
wait: () => ({ stop: () => {} }),
|
|
20876
21143
|
write: (text) => writeStderrRaw(text),
|
|
20877
21144
|
withProgress: async (steps, done) => {
|
|
20878
21145
|
const results = [];
|
|
@@ -20889,7 +21156,69 @@ function createAgentRenderers() {
|
|
|
20889
21156
|
};
|
|
20890
21157
|
}
|
|
20891
21158
|
|
|
21159
|
+
// src/core/wrapText.ts
|
|
21160
|
+
function wrapLine(rawLine, width) {
|
|
21161
|
+
const line = rawLine.trimEnd();
|
|
21162
|
+
if (line.length <= width)
|
|
21163
|
+
return [line];
|
|
21164
|
+
const indent = /^\s*/.exec(line)?.[0] ?? "";
|
|
21165
|
+
const lines = [];
|
|
21166
|
+
let current = "";
|
|
21167
|
+
for (const word of line.trimStart().split(" ")) {
|
|
21168
|
+
if (current === "") {
|
|
21169
|
+
current = word;
|
|
21170
|
+
} else if (indent.length + current.length + 1 + word.length <= width) {
|
|
21171
|
+
current = `${current} ${word}`;
|
|
21172
|
+
} else {
|
|
21173
|
+
lines.push(indent + current);
|
|
21174
|
+
current = word;
|
|
21175
|
+
}
|
|
21176
|
+
}
|
|
21177
|
+
lines.push(indent + current);
|
|
21178
|
+
return lines;
|
|
21179
|
+
}
|
|
21180
|
+
function wrapText(text, width) {
|
|
21181
|
+
return text.split(`
|
|
21182
|
+
`).flatMap((line) => wrapLine(line, width)).join(`
|
|
21183
|
+
`);
|
|
21184
|
+
}
|
|
21185
|
+
|
|
21186
|
+
// src/shell/ui/renderers/waitLine.ts
|
|
21187
|
+
import { styleText as styleText4 } from "node:util";
|
|
21188
|
+
var frames = ["◒", "◐", "◓", "◑"];
|
|
21189
|
+
var frameMs = 120;
|
|
21190
|
+
function elapsed(sinceMs) {
|
|
21191
|
+
const seconds = Math.floor((Date.now() - sinceMs) / 1000);
|
|
21192
|
+
const minutes = Math.floor(seconds / 60);
|
|
21193
|
+
return minutes > 0 ? `[${minutes}m ${seconds % 60}s]` : `[${seconds}s]`;
|
|
21194
|
+
}
|
|
21195
|
+
function startWaitLine(message, output = process.stdout) {
|
|
21196
|
+
const startedAt = Date.now();
|
|
21197
|
+
let frame = 0;
|
|
21198
|
+
const draw = () => {
|
|
21199
|
+
const mark = styleText4("magenta", frames[frame] ?? "◒");
|
|
21200
|
+
output.write(`\r\x1B[2K${mark} ${message} ${elapsed(startedAt)}`);
|
|
21201
|
+
frame = (frame + 1) % frames.length;
|
|
21202
|
+
};
|
|
21203
|
+
draw();
|
|
21204
|
+
const timer = setInterval(draw, frameMs);
|
|
21205
|
+
let stopped = false;
|
|
21206
|
+
return {
|
|
21207
|
+
stop: () => {
|
|
21208
|
+
if (stopped)
|
|
21209
|
+
return;
|
|
21210
|
+
stopped = true;
|
|
21211
|
+
clearInterval(timer);
|
|
21212
|
+
output.write("\r\x1B[2K");
|
|
21213
|
+
}
|
|
21214
|
+
};
|
|
21215
|
+
}
|
|
21216
|
+
|
|
20892
21217
|
// src/shell/ui/renderers/modes/human.ts
|
|
21218
|
+
function transcriptWidth() {
|
|
21219
|
+
const columns = process.stdout.columns || 80;
|
|
21220
|
+
return Math.min(Math.max(columns - 4, 20), 100);
|
|
21221
|
+
}
|
|
20893
21222
|
function createHumanRenderers(clack, verboseTarget) {
|
|
20894
21223
|
return {
|
|
20895
21224
|
intro: (title) => clack.intro(title),
|
|
@@ -20911,6 +21240,12 @@ ${body}` : ""));
|
|
|
20911
21240
|
`),
|
|
20912
21241
|
stream: (_data, line) => writeStdoutRaw(`${line}
|
|
20913
21242
|
`),
|
|
21243
|
+
transcript: ({ body, headline }) => {
|
|
21244
|
+
const lines = wrapText(body, transcriptWidth()).split(`
|
|
21245
|
+
`);
|
|
21246
|
+
clack.log.message([headline, ...lines], { symbol: replySymbol() });
|
|
21247
|
+
},
|
|
21248
|
+
wait: (message) => startWaitLine(message),
|
|
20914
21249
|
write: (text) => writeStdoutRaw(text),
|
|
20915
21250
|
withProgress: async (steps, done) => {
|
|
20916
21251
|
const results = [];
|
|
@@ -20984,6 +21319,8 @@ function createJsonRenderers() {
|
|
|
20984
21319
|
output: (data, _humanMessage) => writeJsonLine(data),
|
|
20985
21320
|
gap: () => {},
|
|
20986
21321
|
stream: (data, _line) => writeJsonLine(data),
|
|
21322
|
+
transcript: ({ data }) => writeJsonLine(data),
|
|
21323
|
+
wait: () => ({ stop: () => {} }),
|
|
20987
21324
|
write: () => {},
|
|
20988
21325
|
withProgress: async (steps, done) => {
|
|
20989
21326
|
const results = [];
|
|
@@ -21080,6 +21417,20 @@ function createSelect({ mode, clack }) {
|
|
|
21080
21417
|
};
|
|
21081
21418
|
}
|
|
21082
21419
|
|
|
21420
|
+
// src/shell/ui/renderers/text.ts
|
|
21421
|
+
function createText({ mode, clack }) {
|
|
21422
|
+
return async (message) => {
|
|
21423
|
+
assertHumanMode(mode, "text");
|
|
21424
|
+
const value = await clack.text({ message });
|
|
21425
|
+
if (clack.isCancel(value))
|
|
21426
|
+
return { ok: false };
|
|
21427
|
+
const answer = value.trim();
|
|
21428
|
+
if (answer.length === 0)
|
|
21429
|
+
return { ok: false };
|
|
21430
|
+
return { ok: true, value: answer };
|
|
21431
|
+
};
|
|
21432
|
+
}
|
|
21433
|
+
|
|
21083
21434
|
// src/shell/ui/createUi.ts
|
|
21084
21435
|
function createUI(mode, opts = {}) {
|
|
21085
21436
|
const clack = opts.clack ?? createStyledClack();
|
|
@@ -21089,6 +21440,7 @@ function createUI(mode, opts = {}) {
|
|
|
21089
21440
|
confirm: createConfirm({ mode, clack }),
|
|
21090
21441
|
password: createPassword({ mode, clack }),
|
|
21091
21442
|
select: createSelect({ mode, clack }),
|
|
21443
|
+
text: createText({ mode, clack }),
|
|
21092
21444
|
json: createJson()
|
|
21093
21445
|
};
|
|
21094
21446
|
}
|
|
@@ -21213,7 +21565,7 @@ function startUpdateCheck(deps) {
|
|
|
21213
21565
|
// package.json
|
|
21214
21566
|
var package_default = {
|
|
21215
21567
|
name: "@qawolf/cli",
|
|
21216
|
-
version: "1.
|
|
21568
|
+
version: "1.31.0",
|
|
21217
21569
|
description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
21218
21570
|
keywords: [
|
|
21219
21571
|
"automation",
|
|
@@ -21288,7 +21640,7 @@ var package_default = {
|
|
|
21288
21640
|
"@qawolf/emails": "1.1.1",
|
|
21289
21641
|
"@qawolf/flow-targets": "1.0.0",
|
|
21290
21642
|
"@qawolf/flows": "0.1.4",
|
|
21291
|
-
"@qawolf/testkit": "1.
|
|
21643
|
+
"@qawolf/testkit": "1.2.1",
|
|
21292
21644
|
commander: "14.0.3",
|
|
21293
21645
|
"env-paths": "4.0.0",
|
|
21294
21646
|
picomatch: "4.0.4",
|
|
@@ -21429,97 +21781,565 @@ function withAuthContext(signals, fn, deps = {}) {
|
|
|
21429
21781
|
};
|
|
21430
21782
|
}
|
|
21431
21783
|
|
|
21432
|
-
// src/
|
|
21433
|
-
|
|
21434
|
-
|
|
21435
|
-
|
|
21436
|
-
|
|
21784
|
+
// src/core/agent/session.ts
|
|
21785
|
+
var defaultAgentFollowTimeoutSeconds = 1800;
|
|
21786
|
+
var settledStatuses = [
|
|
21787
|
+
"cancelled",
|
|
21788
|
+
"completed",
|
|
21789
|
+
"failed"
|
|
21790
|
+
];
|
|
21791
|
+
function isSettled(status) {
|
|
21792
|
+
return settledStatuses.includes(status);
|
|
21793
|
+
}
|
|
21794
|
+
function pendingQuestion(status, replies) {
|
|
21795
|
+
if (status !== "waiting-for-you")
|
|
21437
21796
|
return;
|
|
21438
|
-
|
|
21439
|
-
|
|
21440
|
-
|
|
21441
|
-
|
|
21797
|
+
return replies[replies.length - 1];
|
|
21798
|
+
}
|
|
21799
|
+
|
|
21800
|
+
// src/core/agent/formatReply.ts
|
|
21801
|
+
var speaker = "QA Wolf";
|
|
21802
|
+
function replyTime(askedAt) {
|
|
21803
|
+
const at = new Date(askedAt);
|
|
21804
|
+
if (Number.isNaN(at.getTime()))
|
|
21805
|
+
return;
|
|
21806
|
+
return at.toTimeString().slice(0, 8);
|
|
21807
|
+
}
|
|
21808
|
+
function replyParts(reply, options) {
|
|
21809
|
+
const time = replyTime(reply.askedAt);
|
|
21810
|
+
const choices = options.listChoices && reply.choices !== undefined ? ["", ...reply.choices.map((choice) => `- ${choice}`)] : [];
|
|
21811
|
+
return {
|
|
21812
|
+
body: [reply.text.trim(), ...choices].join(`
|
|
21813
|
+
`),
|
|
21814
|
+
headline: time === undefined ? speaker : `${speaker} ${time}`
|
|
21815
|
+
};
|
|
21816
|
+
}
|
|
21817
|
+
|
|
21818
|
+
// src/core/followTimeout.ts
|
|
21819
|
+
var followTimeoutSchema = exports_coerce.number().int().positive();
|
|
21820
|
+
function parseFollowTimeout(seconds, defaultSeconds) {
|
|
21821
|
+
if (seconds === undefined)
|
|
21822
|
+
return { ok: true, seconds: defaultSeconds };
|
|
21823
|
+
const parsed = followTimeoutSchema.safeParse(seconds);
|
|
21824
|
+
if (!parsed.success)
|
|
21825
|
+
return { error: prettifyError(parsed.error), ok: false };
|
|
21826
|
+
return { ok: true, seconds: parsed.data };
|
|
21827
|
+
}
|
|
21828
|
+
|
|
21829
|
+
// src/domains/agent/settlement.ts
|
|
21830
|
+
function endWithSession(ctx, session) {
|
|
21831
|
+
if (ctx.ui.mode !== "human")
|
|
21832
|
+
ctx.ui.json(session);
|
|
21833
|
+
}
|
|
21834
|
+
function reportSettlement(ctx, session) {
|
|
21835
|
+
endWithSession(ctx, session);
|
|
21836
|
+
if (session.status === "completed") {
|
|
21837
|
+
ctx.ui.success(agentMessages.sessionCompleted);
|
|
21442
21838
|
return;
|
|
21443
21839
|
}
|
|
21444
|
-
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
|
|
21448
|
-
const v = await validateApiKey({
|
|
21449
|
-
platformClient: createPlatformClient(apiKey, {
|
|
21450
|
-
baseUrl: ctx.apiBaseUrl,
|
|
21451
|
-
fetch: globalThis.fetch
|
|
21452
|
-
})
|
|
21453
|
-
});
|
|
21454
|
-
if (!v.valid)
|
|
21455
|
-
throw Error(v.error);
|
|
21456
|
-
}
|
|
21457
|
-
},
|
|
21458
|
-
{
|
|
21459
|
-
message: authMessages.storing,
|
|
21460
|
-
task: async () => saveApiKey(ctx.configDir, apiKey, ctx.fs)
|
|
21461
|
-
}
|
|
21462
|
-
], ([, saveResult]) => {
|
|
21463
|
-
return saveResult.stored === "file" ? authMessages.storedFile : authMessages.storedKeychain;
|
|
21464
|
-
});
|
|
21465
|
-
ctx.ui.outro(authMessages.outroSuccess);
|
|
21840
|
+
return {
|
|
21841
|
+
error: session.status === "cancelled" ? agentMessages.sessionCancelled(session.url) : agentMessages.sessionFailed(session.url),
|
|
21842
|
+
exitCode: exitCodes.testFailure
|
|
21843
|
+
};
|
|
21466
21844
|
}
|
|
21467
21845
|
|
|
21468
|
-
// src/
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
return
|
|
21846
|
+
// src/domains/agent/answerQuestion.ts
|
|
21847
|
+
async function ask(ctx, question) {
|
|
21848
|
+
const choices = question.choices ?? [];
|
|
21849
|
+
const answer = choices.length > 0 ? await ctx.ui.select(agentMessages.answerPrompt, choices.map((choice) => ({ label: choice, value: choice }))) : await ctx.ui.text(agentMessages.answerPrompt);
|
|
21850
|
+
return answer.ok ? answer.value : undefined;
|
|
21473
21851
|
}
|
|
21474
|
-
function
|
|
21475
|
-
|
|
21476
|
-
|
|
21852
|
+
async function answerQuestion(ctx, options) {
|
|
21853
|
+
const answer = await ask(ctx, options.question);
|
|
21854
|
+
if (answer === undefined) {
|
|
21855
|
+
ctx.ui.warn(agentMessages.answerCancelled);
|
|
21856
|
+
return { type: "declined" };
|
|
21477
21857
|
}
|
|
21478
|
-
|
|
21479
|
-
|
|
21858
|
+
const sent = await ctx.platformClient.callPublicApi(publicContractsV1.agent.send, {
|
|
21859
|
+
message: answer,
|
|
21860
|
+
sessionId: options.sessionId,
|
|
21861
|
+
...options.workspaceId === undefined ? {} : { workspaceId: options.workspaceId }
|
|
21862
|
+
});
|
|
21863
|
+
if (!sent.ok) {
|
|
21864
|
+
const failure = failureFields(sent);
|
|
21865
|
+
return {
|
|
21866
|
+
result: {
|
|
21867
|
+
exitCode: exitCodes.network,
|
|
21868
|
+
...failure,
|
|
21869
|
+
error: agentMessages.answerSendFailed(failure.error)
|
|
21870
|
+
},
|
|
21871
|
+
type: "failed"
|
|
21872
|
+
};
|
|
21480
21873
|
}
|
|
21481
|
-
|
|
21482
|
-
|
|
21483
|
-
|
|
21484
|
-
|
|
21485
|
-
|
|
21486
|
-
|
|
21487
|
-
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
|
|
21494
|
-
|
|
21495
|
-
|
|
21496
|
-
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
|
|
21500
|
-
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
|
|
21504
|
-
|
|
21505
|
-
|
|
21506
|
-
|
|
21507
|
-
|
|
21508
|
-
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
|
|
21512
|
-
|
|
21874
|
+
return { repliesAtAnswer: options.repliesSoFar, type: "answered" };
|
|
21875
|
+
}
|
|
21876
|
+
async function handleQuestion(ctx, options) {
|
|
21877
|
+
const { session, sessionId } = options;
|
|
21878
|
+
if (!options.canPrompt) {
|
|
21879
|
+
ctx.ui.info(agentMessages.blocked(sessionId));
|
|
21880
|
+
endWithSession(ctx, session);
|
|
21881
|
+
return { result: undefined, type: "ended" };
|
|
21882
|
+
}
|
|
21883
|
+
const outcome = await answerQuestion(ctx, {
|
|
21884
|
+
question: options.question,
|
|
21885
|
+
repliesSoFar: session.replies.length,
|
|
21886
|
+
sessionId,
|
|
21887
|
+
workspaceId: options.workspaceId
|
|
21888
|
+
});
|
|
21889
|
+
if (outcome.type === "failed")
|
|
21890
|
+
return { result: outcome.result, type: "ended" };
|
|
21891
|
+
if (outcome.type === "declined")
|
|
21892
|
+
return { result: undefined, type: "ended" };
|
|
21893
|
+
return outcome;
|
|
21894
|
+
}
|
|
21895
|
+
|
|
21896
|
+
// src/domains/agent/followSession.ts
|
|
21897
|
+
var pollIntervalMs = 5000;
|
|
21898
|
+
async function followSession(ctx, options, deps) {
|
|
21899
|
+
const { sessionId, workspaceId } = options;
|
|
21900
|
+
const canPrompt = ctx.ui.mode === "human" && ctx.isInteractive;
|
|
21901
|
+
const startedAt = deps.now();
|
|
21902
|
+
let promptedMs = 0;
|
|
21903
|
+
const timedOut = () => deps.now() - startedAt - promptedMs >= options.timeoutSeconds * 1000;
|
|
21904
|
+
let pending = options.initial;
|
|
21905
|
+
let printed = 0;
|
|
21906
|
+
let { repliesAtAnswer } = options;
|
|
21907
|
+
let saidDetachHint = false;
|
|
21908
|
+
let waiting;
|
|
21909
|
+
const stopWaiting = () => {
|
|
21910
|
+
waiting?.stop();
|
|
21911
|
+
waiting = undefined;
|
|
21912
|
+
};
|
|
21913
|
+
const detach = ctx.signals.register(() => {
|
|
21914
|
+
stopWaiting();
|
|
21915
|
+
ctx.ui.info(agentMessages.detached(sessionId));
|
|
21916
|
+
});
|
|
21917
|
+
try {
|
|
21918
|
+
for (let poll = 1;; poll++) {
|
|
21919
|
+
let session;
|
|
21920
|
+
if (pending !== undefined) {
|
|
21921
|
+
session = pending;
|
|
21922
|
+
pending = undefined;
|
|
21923
|
+
} else {
|
|
21924
|
+
const read = await ctx.platformClient.callPublicApi(publicContractsV1.agent.get, { sessionId });
|
|
21925
|
+
if (!read.ok) {
|
|
21926
|
+
return { exitCode: exitCodes.network, ...failureFields(read) };
|
|
21927
|
+
}
|
|
21928
|
+
session = read.value;
|
|
21929
|
+
}
|
|
21930
|
+
const { replies, status } = session;
|
|
21931
|
+
const fresh = replies.slice(printed);
|
|
21932
|
+
printed = replies.length;
|
|
21933
|
+
if (fresh.length > 0)
|
|
21934
|
+
stopWaiting();
|
|
21935
|
+
for (const reply of fresh) {
|
|
21936
|
+
ctx.ui.transcript({
|
|
21937
|
+
...replyParts(reply, { listChoices: !canPrompt }),
|
|
21938
|
+
data: reply
|
|
21939
|
+
});
|
|
21940
|
+
}
|
|
21941
|
+
if (poll === 1 && replies.length === 0 && !isSettled(status)) {
|
|
21942
|
+
ctx.ui.info(agentMessages.working);
|
|
21943
|
+
}
|
|
21944
|
+
if (isSettled(status)) {
|
|
21945
|
+
stopWaiting();
|
|
21946
|
+
return reportSettlement(ctx, session);
|
|
21947
|
+
}
|
|
21948
|
+
const question = pendingQuestion(status, replies);
|
|
21949
|
+
const awaitingOurAnswer = repliesAtAnswer !== undefined && replies.length <= repliesAtAnswer;
|
|
21950
|
+
if (question !== undefined && !awaitingOurAnswer) {
|
|
21951
|
+
stopWaiting();
|
|
21952
|
+
const promptStartedAt = deps.now();
|
|
21953
|
+
const step = await handleQuestion(ctx, {
|
|
21954
|
+
canPrompt,
|
|
21955
|
+
question,
|
|
21956
|
+
session,
|
|
21957
|
+
sessionId,
|
|
21958
|
+
workspaceId
|
|
21959
|
+
});
|
|
21960
|
+
promptedMs += deps.now() - promptStartedAt;
|
|
21961
|
+
if (step.type === "ended")
|
|
21962
|
+
return step.result;
|
|
21963
|
+
repliesAtAnswer = step.repliesAtAnswer;
|
|
21964
|
+
}
|
|
21965
|
+
if (!saidDetachHint && ctx.ui.mode === "human") {
|
|
21966
|
+
saidDetachHint = true;
|
|
21967
|
+
ctx.ui.info(agentMessages.detachHint);
|
|
21968
|
+
}
|
|
21969
|
+
waiting ??= ctx.ui.wait(agentMessages.waiting);
|
|
21970
|
+
await deps.sleep(pollIntervalMs);
|
|
21971
|
+
if (timedOut()) {
|
|
21972
|
+
return {
|
|
21973
|
+
error: agentMessages.followTimedOut(sessionId, options.timeoutSeconds),
|
|
21974
|
+
exitCode: exitCodes.timeout
|
|
21975
|
+
};
|
|
21976
|
+
}
|
|
21513
21977
|
}
|
|
21514
|
-
|
|
21515
|
-
|
|
21978
|
+
} finally {
|
|
21979
|
+
stopWaiting();
|
|
21980
|
+
detach();
|
|
21516
21981
|
}
|
|
21517
21982
|
}
|
|
21518
21983
|
|
|
21519
|
-
// src/
|
|
21520
|
-
|
|
21521
|
-
|
|
21522
|
-
|
|
21984
|
+
// src/core/resolveId.ts
|
|
21985
|
+
async function resolveIdFrom(options) {
|
|
21986
|
+
if (options.given !== undefined) {
|
|
21987
|
+
return { id: options.given, source: "flag" };
|
|
21988
|
+
}
|
|
21989
|
+
const fromEnvironment = options.env[options.environmentVariable]?.trim();
|
|
21990
|
+
if (fromEnvironment) {
|
|
21991
|
+
return { id: fromEnvironment, source: "environment" };
|
|
21992
|
+
}
|
|
21993
|
+
const stored = await options.readStored();
|
|
21994
|
+
return stored === undefined ? undefined : { id: stored, source: "stored" };
|
|
21995
|
+
}
|
|
21996
|
+
|
|
21997
|
+
// src/domains/agent/resolveSessionId.ts
|
|
21998
|
+
var sessionIdEnvironmentVariable = "QAWOLF_SESSION_ID";
|
|
21999
|
+
function chooseGivenSessionId(given) {
|
|
22000
|
+
const { argument, flag } = given;
|
|
22001
|
+
if (argument !== undefined && flag !== undefined && argument !== flag) {
|
|
22002
|
+
return { error: sessionGivenTwice(argument, flag), ok: false };
|
|
22003
|
+
}
|
|
22004
|
+
return { ok: true, sessionId: argument ?? flag };
|
|
22005
|
+
}
|
|
22006
|
+
var resolveSessionId = async (session, deps) => (await resolveIdFrom({
|
|
22007
|
+
env: deps.env,
|
|
22008
|
+
environmentVariable: sessionIdEnvironmentVariable,
|
|
22009
|
+
given: session,
|
|
22010
|
+
readStored: deps.store.readLastSessionId
|
|
22011
|
+
}))?.id;
|
|
22012
|
+
|
|
22013
|
+
// src/domains/agent/get.ts
|
|
22014
|
+
function renderSession(ctx, session) {
|
|
22015
|
+
if (ctx.ui.mode !== "json") {
|
|
22016
|
+
for (const reply of session.replies) {
|
|
22017
|
+
ctx.ui.transcript({
|
|
22018
|
+
...replyParts(reply, { listChoices: true }),
|
|
22019
|
+
data: reply
|
|
22020
|
+
});
|
|
22021
|
+
}
|
|
22022
|
+
}
|
|
22023
|
+
ctx.ui.output(session, agentMessages.standing(session.status, session.url));
|
|
22024
|
+
}
|
|
22025
|
+
async function handleAgentGet(ctx, options, deps) {
|
|
22026
|
+
const timeout = parseFollowTimeout(options.timeout, defaultAgentFollowTimeoutSeconds);
|
|
22027
|
+
if (!timeout.ok) {
|
|
22028
|
+
return { error: timeout.error, exitCode: exitCodes.invalidArgs };
|
|
22029
|
+
}
|
|
22030
|
+
const given = chooseGivenSessionId({
|
|
22031
|
+
argument: options.sessionArgument,
|
|
22032
|
+
flag: options.session
|
|
22033
|
+
});
|
|
22034
|
+
if (!given.ok) {
|
|
22035
|
+
return { error: given.error, exitCode: exitCodes.invalidArgs };
|
|
22036
|
+
}
|
|
22037
|
+
const sessionId = await resolveSessionId(given.sessionId, deps);
|
|
22038
|
+
if (sessionId === undefined) {
|
|
22039
|
+
return { error: agentMessages.noSession, exitCode: exitCodes.invalidArgs };
|
|
22040
|
+
}
|
|
22041
|
+
const read = await ctx.platformClient.callPublicApi(publicContractsV1.agent.get, { sessionId });
|
|
22042
|
+
if (!read.ok)
|
|
22043
|
+
return { exitCode: exitCodes.network, ...failureFields(read) };
|
|
22044
|
+
if (!options.follow) {
|
|
22045
|
+
renderSession(ctx, read.value);
|
|
22046
|
+
return;
|
|
22047
|
+
}
|
|
22048
|
+
ctx.ui.info(agentMessages.sessionAt(read.value.url));
|
|
22049
|
+
return followSession(ctx, {
|
|
22050
|
+
initial: read.value,
|
|
22051
|
+
repliesAtAnswer: undefined,
|
|
22052
|
+
sessionId,
|
|
22053
|
+
timeoutSeconds: timeout.seconds,
|
|
22054
|
+
workspaceId: options.workspaceId
|
|
22055
|
+
}, deps);
|
|
22056
|
+
}
|
|
22057
|
+
|
|
22058
|
+
// src/shell/agent/sessionStore.ts
|
|
22059
|
+
import { join as join14 } from "node:path";
|
|
22060
|
+
|
|
22061
|
+
// src/core/parseJson.ts
|
|
22062
|
+
function parseJson(text) {
|
|
22063
|
+
try {
|
|
22064
|
+
return JSON.parse(text);
|
|
22065
|
+
} catch {
|
|
22066
|
+
return;
|
|
22067
|
+
}
|
|
22068
|
+
}
|
|
22069
|
+
|
|
22070
|
+
// src/shell/jsonFile.ts
|
|
22071
|
+
var pendingWrites = 0;
|
|
22072
|
+
async function readJsonFile(fs, path, schema) {
|
|
22073
|
+
const contents = await fs.readFile(path).catch(() => {
|
|
22074
|
+
return;
|
|
22075
|
+
});
|
|
22076
|
+
if (contents === undefined)
|
|
22077
|
+
return;
|
|
22078
|
+
const parsed = schema.safeParse(parseJson(contents));
|
|
22079
|
+
return parsed.success ? parsed.data : undefined;
|
|
22080
|
+
}
|
|
22081
|
+
async function writeJsonFileAtomically(fs, path, value) {
|
|
22082
|
+
const pendingPath = `${path}.${String(process.pid)}.${String(++pendingWrites)}.tmp`;
|
|
22083
|
+
try {
|
|
22084
|
+
await fs.writeFile(pendingPath, `${JSON.stringify(value, undefined, 2)}
|
|
22085
|
+
`);
|
|
22086
|
+
await fs.rename(pendingPath, path);
|
|
22087
|
+
} finally {
|
|
22088
|
+
await fs.rm(pendingPath, { force: true }).catch(() => {});
|
|
22089
|
+
}
|
|
22090
|
+
}
|
|
22091
|
+
|
|
22092
|
+
// src/shell/agent/sessionStore.ts
|
|
22093
|
+
var storeFileName = "agent.json";
|
|
22094
|
+
var storeSchema = object({ lastSessionId: string2().optional() });
|
|
22095
|
+
function makeAgentSessionStore(options) {
|
|
22096
|
+
const directory = join14(options.cwd, qawolfDir);
|
|
22097
|
+
const path = join14(directory, storeFileName);
|
|
22098
|
+
return {
|
|
22099
|
+
async readLastSessionId() {
|
|
22100
|
+
const stored = await readJsonFile(options.fs, path, storeSchema);
|
|
22101
|
+
return stored?.lastSessionId;
|
|
22102
|
+
},
|
|
22103
|
+
async rememberSession(sessionId) {
|
|
22104
|
+
await options.fs.mkdir(directory, { recursive: true });
|
|
22105
|
+
await writeJsonFileAtomically(options.fs, path, {
|
|
22106
|
+
lastSessionId: sessionId
|
|
22107
|
+
});
|
|
22108
|
+
}
|
|
22109
|
+
};
|
|
22110
|
+
}
|
|
22111
|
+
|
|
22112
|
+
// src/domains/agent/deps.ts
|
|
22113
|
+
function makeAgentDeps(options) {
|
|
22114
|
+
return {
|
|
22115
|
+
env: options.env,
|
|
22116
|
+
now: Date.now,
|
|
22117
|
+
sleep,
|
|
22118
|
+
store: makeAgentSessionStore({ cwd: options.cwd, fs: options.fs })
|
|
22119
|
+
};
|
|
22120
|
+
}
|
|
22121
|
+
|
|
22122
|
+
// src/commands/agent/context.ts
|
|
22123
|
+
var sessionFlagDescription = `Session to target. Defaults to ${sessionIdEnvironmentVariable}, then the session this directory last started`;
|
|
22124
|
+
var timeoutFlagDescription = "Give up following after this long. A session that never settles would otherwise hold a CI job open until the build is killed";
|
|
22125
|
+
function agentDeps(ctx) {
|
|
22126
|
+
return makeAgentDeps({
|
|
22127
|
+
cwd: process.cwd(),
|
|
22128
|
+
env: process.env,
|
|
22129
|
+
fs: ctx.fs
|
|
22130
|
+
});
|
|
22131
|
+
}
|
|
22132
|
+
|
|
22133
|
+
// src/commands/agent/get.register.ts
|
|
22134
|
+
var getExamples = `
|
|
22135
|
+
Examples:
|
|
22136
|
+
$ qawolf agent get
|
|
22137
|
+
$ qawolf agent get --follow
|
|
22138
|
+
$ qawolf agent get <sessionId> --follow
|
|
22139
|
+
$ qawolf agent get --session <sessionId>`;
|
|
22140
|
+
function registerAgentGetCommand(agent, signals) {
|
|
22141
|
+
declareCommandKind(agent.command("get [session]"), "read").description("Read what the QA Wolf AI has said and whether it is still working").option("--follow", "Stay and report what QA Wolf says until the session settles, answering its questions as they come", false).option("--session <id>", sessionFlagDescription).option("--workspace-id <id>", "The workspace an answer given during --follow is sent to. Required when authenticating with an organization or user API key").option("--timeout <seconds>", timeoutFlagDescription, String(defaultAgentFollowTimeoutSeconds)).addHelpText("after", getExamples).action((session, opts, command) => withAuthContext(signals, (ctx) => handleAgentGet(ctx, {
|
|
22142
|
+
follow: opts.follow,
|
|
22143
|
+
session: opts.session,
|
|
22144
|
+
sessionArgument: session,
|
|
22145
|
+
timeout: opts.timeout,
|
|
22146
|
+
workspaceId: opts.workspaceId
|
|
22147
|
+
}, agentDeps(ctx)))(opts, command));
|
|
22148
|
+
}
|
|
22149
|
+
|
|
22150
|
+
// src/commands/publicApi/environmentOptions.ts
|
|
22151
|
+
var environmentIdEnvironmentVariable = "QAWOLF_ENVIRONMENT";
|
|
22152
|
+
var optionEnvironmentVariables = new Map([
|
|
22153
|
+
["environmentId", environmentIdEnvironmentVariable],
|
|
22154
|
+
["public.run.create.aiTaskId", "QAWOLF_AI_TASK_ID"],
|
|
22155
|
+
["public.run.create.chatSessionId", "QAWOLF_CHAT_SESSION_ID"]
|
|
22156
|
+
]);
|
|
22157
|
+
function optionEnvironmentVariable(spec, path) {
|
|
22158
|
+
const dotted = path.join(".");
|
|
22159
|
+
return optionEnvironmentVariables.get(`${spec.trpcPath}.${dotted}`) ?? optionEnvironmentVariables.get(dotted);
|
|
22160
|
+
}
|
|
22161
|
+
var exclusiveOptions = new Map([
|
|
22162
|
+
["public.run.create", { keep: "aiTaskId", drop: "chatSessionId" }]
|
|
22163
|
+
]);
|
|
22164
|
+
function withoutExclusiveConflict(spec, command, options) {
|
|
22165
|
+
const pair = exclusiveOptions.get(spec.trpcPath);
|
|
22166
|
+
if (!pair)
|
|
22167
|
+
return options;
|
|
22168
|
+
if (options[pair.keep] === undefined || options[pair.drop] === undefined) {
|
|
22169
|
+
return options;
|
|
22170
|
+
}
|
|
22171
|
+
const fromEnvironment = (key) => command.getOptionValueSource(key) === "env";
|
|
22172
|
+
if (!fromEnvironment(pair.keep) && !fromEnvironment(pair.drop)) {
|
|
22173
|
+
return options;
|
|
22174
|
+
}
|
|
22175
|
+
const dropped = fromEnvironment(pair.drop) ? pair.drop : pair.keep;
|
|
22176
|
+
return Object.fromEntries(Object.entries(options).filter(([key]) => key !== dropped));
|
|
22177
|
+
}
|
|
22178
|
+
|
|
22179
|
+
// src/domains/agent/send.ts
|
|
22180
|
+
function parseInput(options) {
|
|
22181
|
+
return publicContractsV1.agent.send.input.safeParse({
|
|
22182
|
+
message: options.message,
|
|
22183
|
+
...options.environmentId === undefined ? {} : { environmentId: options.environmentId },
|
|
22184
|
+
...options.filePaths === undefined ? {} : { filePaths: options.filePaths },
|
|
22185
|
+
...options.session === undefined ? {} : { sessionId: options.session },
|
|
22186
|
+
...options.workspaceId === undefined ? {} : { workspaceId: options.workspaceId }
|
|
22187
|
+
});
|
|
22188
|
+
}
|
|
22189
|
+
async function handleAgentSend(ctx, options, deps) {
|
|
22190
|
+
const timeout = parseFollowTimeout(options.timeout, defaultAgentFollowTimeoutSeconds);
|
|
22191
|
+
if (!timeout.ok) {
|
|
22192
|
+
return { error: timeout.error, exitCode: exitCodes.invalidArgs };
|
|
22193
|
+
}
|
|
22194
|
+
const input = parseInput(options);
|
|
22195
|
+
if (!input.success) {
|
|
22196
|
+
return {
|
|
22197
|
+
error: prettifyError(input.error),
|
|
22198
|
+
exitCode: exitCodes.invalidArgs
|
|
22199
|
+
};
|
|
22200
|
+
}
|
|
22201
|
+
let repliesAtAnswer;
|
|
22202
|
+
if (options.follow && options.session !== undefined) {
|
|
22203
|
+
const before = await ctx.platformClient.callPublicApi(publicContractsV1.agent.get, { sessionId: options.session });
|
|
22204
|
+
if (before.ok)
|
|
22205
|
+
repliesAtAnswer = before.value.replies.length;
|
|
22206
|
+
}
|
|
22207
|
+
const sent = await ctx.platformClient.callPublicApi(publicContractsV1.agent.send, input.data);
|
|
22208
|
+
if (!sent.ok)
|
|
22209
|
+
return { exitCode: exitCodes.network, ...failureFields(sent) };
|
|
22210
|
+
ctx.ui.output(sent.value, agentMessages.started(sent.value.sessionId, sent.value.url));
|
|
22211
|
+
await deps.store.rememberSession(sent.value.sessionId).catch(() => {
|
|
22212
|
+
ctx.ui.warn(agentMessages.sessionNotRemembered(sent.value.sessionId));
|
|
22213
|
+
});
|
|
22214
|
+
if (!options.follow)
|
|
22215
|
+
return;
|
|
22216
|
+
return followSession(ctx, {
|
|
22217
|
+
initial: undefined,
|
|
22218
|
+
repliesAtAnswer,
|
|
22219
|
+
sessionId: sent.value.sessionId,
|
|
22220
|
+
timeoutSeconds: timeout.seconds,
|
|
22221
|
+
workspaceId: options.workspaceId
|
|
22222
|
+
}, deps);
|
|
22223
|
+
}
|
|
22224
|
+
|
|
22225
|
+
// src/commands/agent/send.register.ts
|
|
22226
|
+
var sendExamples = `
|
|
22227
|
+
Examples:
|
|
22228
|
+
$ qawolf agent send "cover the checkout journey"
|
|
22229
|
+
$ qawolf agent send "cover the checkout journey" --follow
|
|
22230
|
+
$ qawolf agent send "use the staging login test@example.com" --session <id>
|
|
22231
|
+
$ qawolf agent send "cover signup" --environment-id staging --follow
|
|
22232
|
+
$ qawolf agent send "cover every journey in the sheet" --file-paths uploads/journeys.csv --follow`;
|
|
22233
|
+
function registerAgentSendCommand(agent, signals) {
|
|
22234
|
+
declareCommandKind(agent.command("send <message>"), "write").description("Ask the QA Wolf AI to do a piece of work, such as covering a journey or fixing a broken flow").option("--follow", "Stay and report what QA Wolf says until the session settles, answering its questions as they come", false).option("--session <id>", "Continue this session instead of opening a new one. Send an answer, or add context to work already running").addOption(new Option2("--environment-id <env>", "QA Wolf environment to work in, by id or alias. Ignored with --session, because a session keeps the environment it opened in").env(environmentIdEnvironmentVariable)).option("--workspace-id <id>", "The workspace to work in. Required when authenticating with an organization or user API key").option("--file-paths <path...>", "Team-storage paths of files this request is about, from qawolf file requestUpload. The AI reads them from storage rather than the message, so a plan of hundreds of journeys costs nothing to send. Up to 20").option("--timeout <seconds>", timeoutFlagDescription, String(defaultAgentFollowTimeoutSeconds)).addHelpText("after", sendExamples).action((message, opts, command) => withAuthContext(signals, (ctx) => handleAgentSend(ctx, {
|
|
22235
|
+
environmentId: opts.environmentId,
|
|
22236
|
+
filePaths: opts.filePaths,
|
|
22237
|
+
follow: opts.follow,
|
|
22238
|
+
message,
|
|
22239
|
+
session: opts.session,
|
|
22240
|
+
timeout: opts.timeout,
|
|
22241
|
+
workspaceId: opts.workspaceId
|
|
22242
|
+
}, agentDeps(ctx)))(opts, command));
|
|
22243
|
+
}
|
|
22244
|
+
|
|
22245
|
+
// src/commands/agent/index.ts
|
|
22246
|
+
function registerAgentCommand(program, signals) {
|
|
22247
|
+
const agent = program.command("agent").description("Ask the QA Wolf AI for work and follow what it does");
|
|
22248
|
+
registerAgentSendCommand(agent, signals);
|
|
22249
|
+
registerAgentGetCommand(agent, signals);
|
|
22250
|
+
}
|
|
22251
|
+
|
|
22252
|
+
// src/commands/auth/loginApiKey.ts
|
|
22253
|
+
async function loginWithApiKey(ctx) {
|
|
22254
|
+
const result = await ctx.ui.password(authMessages.promptApiKey, "Set QAWOLF_API_KEY to authenticate in non-interactive environments.");
|
|
22255
|
+
if (!result.ok) {
|
|
22256
|
+
ctx.ui.cancel(authMessages.cancelled);
|
|
22257
|
+
return;
|
|
22258
|
+
}
|
|
22259
|
+
const apiKey = result.value.trim();
|
|
22260
|
+
if (!apiKey) {
|
|
22261
|
+
ctx.ui.cancel(authMessages.cancelled);
|
|
22262
|
+
return;
|
|
22263
|
+
}
|
|
22264
|
+
await ctx.ui.withProgress([
|
|
22265
|
+
{
|
|
22266
|
+
message: authMessages.verifying,
|
|
22267
|
+
task: async () => {
|
|
22268
|
+
const v = await validateApiKey({
|
|
22269
|
+
platformClient: createPlatformClient(apiKey, {
|
|
22270
|
+
baseUrl: ctx.apiBaseUrl,
|
|
22271
|
+
fetch: globalThis.fetch
|
|
22272
|
+
})
|
|
22273
|
+
});
|
|
22274
|
+
if (!v.valid)
|
|
22275
|
+
throw Error(v.error);
|
|
22276
|
+
}
|
|
22277
|
+
},
|
|
22278
|
+
{
|
|
22279
|
+
message: authMessages.storing,
|
|
22280
|
+
task: async () => saveApiKey(ctx.configDir, apiKey, ctx.fs)
|
|
22281
|
+
}
|
|
22282
|
+
], ([, saveResult]) => {
|
|
22283
|
+
return saveResult.stored === "file" ? authMessages.storedFile : authMessages.storedKeychain;
|
|
22284
|
+
});
|
|
22285
|
+
ctx.ui.outro(authMessages.outroSuccess);
|
|
22286
|
+
}
|
|
22287
|
+
|
|
22288
|
+
// src/core/deviceAuth/pollState.ts
|
|
22289
|
+
var slowDownIncrementMs = 5000;
|
|
22290
|
+
var unreachableBackoffFactor = 2;
|
|
22291
|
+
function capToLifetime(delayMs, state, nowMs) {
|
|
22292
|
+
return Math.min(delayMs, Math.max(1, state.deadlineMs - nowMs));
|
|
22293
|
+
}
|
|
22294
|
+
function nextPollStep(state, response, nowMs) {
|
|
22295
|
+
if (response.kind === "tokens") {
|
|
22296
|
+
return { action: "done", tokens: response.tokens };
|
|
22297
|
+
}
|
|
22298
|
+
if (nowMs > state.deadlineMs) {
|
|
22299
|
+
return { action: "fail", reason: "timeout", detail: undefined };
|
|
22300
|
+
}
|
|
22301
|
+
switch (response.kind) {
|
|
22302
|
+
case "pending":
|
|
22303
|
+
return {
|
|
22304
|
+
action: "poll",
|
|
22305
|
+
delayMs: capToLifetime(state.intervalMs, state, nowMs),
|
|
22306
|
+
state
|
|
22307
|
+
};
|
|
22308
|
+
case "slow-down": {
|
|
22309
|
+
const slowed = {
|
|
22310
|
+
intervalMs: state.intervalMs + slowDownIncrementMs,
|
|
22311
|
+
deadlineMs: state.deadlineMs
|
|
22312
|
+
};
|
|
22313
|
+
return {
|
|
22314
|
+
action: "poll",
|
|
22315
|
+
delayMs: capToLifetime(slowed.intervalMs, slowed, nowMs),
|
|
22316
|
+
state: slowed
|
|
22317
|
+
};
|
|
22318
|
+
}
|
|
22319
|
+
case "denied":
|
|
22320
|
+
return { action: "fail", reason: "access-denied", detail: undefined };
|
|
22321
|
+
case "expired":
|
|
22322
|
+
return { action: "fail", reason: "expired", detail: undefined };
|
|
22323
|
+
case "unreachable": {
|
|
22324
|
+
const backedOff = {
|
|
22325
|
+
intervalMs: state.intervalMs * unreachableBackoffFactor,
|
|
22326
|
+
deadlineMs: state.deadlineMs
|
|
22327
|
+
};
|
|
22328
|
+
return {
|
|
22329
|
+
action: "poll",
|
|
22330
|
+
delayMs: capToLifetime(backedOff.intervalMs, backedOff, nowMs),
|
|
22331
|
+
state: backedOff
|
|
22332
|
+
};
|
|
22333
|
+
}
|
|
22334
|
+
case "error":
|
|
22335
|
+
return { action: "fail", reason: "network", detail: response.detail };
|
|
22336
|
+
}
|
|
22337
|
+
}
|
|
22338
|
+
|
|
22339
|
+
// src/domains/auth/deviceLogin.ts
|
|
22340
|
+
var cancelled = {
|
|
22341
|
+
ok: false,
|
|
22342
|
+
reason: "cancelled",
|
|
21523
22343
|
detail: undefined
|
|
21524
22344
|
};
|
|
21525
22345
|
async function deviceLogin(deps) {
|
|
@@ -21841,10 +22661,9 @@ async function selectWorkspace(deps) {
|
|
|
21841
22661
|
}
|
|
21842
22662
|
|
|
21843
22663
|
// src/domains/auth/store/saveWorkspaceId.ts
|
|
21844
|
-
import { Entry as Entry6 } from "@napi-rs/keyring";
|
|
21845
22664
|
function makeSaveWorkspaceIdDeps(configDir, fs) {
|
|
21846
22665
|
return {
|
|
21847
|
-
loadTokens: () => loadTokens(configDir, {
|
|
22666
|
+
loadTokens: () => loadTokens(configDir, { loadEntryClass, fs }),
|
|
21848
22667
|
saveTokens: (session) => saveTokens(configDir, session, fs)
|
|
21849
22668
|
};
|
|
21850
22669
|
}
|
|
@@ -22050,11 +22869,11 @@ async function handleLogin(ctx, deps = {}) {
|
|
|
22050
22869
|
}
|
|
22051
22870
|
|
|
22052
22871
|
// src/domains/auth/store/deleteTokens.ts
|
|
22053
|
-
import { join as
|
|
22054
|
-
|
|
22055
|
-
function deleteFromKeychain2() {
|
|
22872
|
+
import { join as join15 } from "node:path";
|
|
22873
|
+
async function deleteFromKeychain2() {
|
|
22056
22874
|
try {
|
|
22057
|
-
|
|
22875
|
+
const Entry = await loadEntryClass();
|
|
22876
|
+
new Entry(service, tokensAccount).deletePassword();
|
|
22058
22877
|
return "deleted";
|
|
22059
22878
|
} catch {
|
|
22060
22879
|
return "unavailable";
|
|
@@ -22062,7 +22881,7 @@ function deleteFromKeychain2() {
|
|
|
22062
22881
|
}
|
|
22063
22882
|
async function deleteFromFile2(configDir, fs) {
|
|
22064
22883
|
try {
|
|
22065
|
-
await fs.unlink(
|
|
22884
|
+
await fs.unlink(join15(configDir, tokensFile));
|
|
22066
22885
|
return "deleted";
|
|
22067
22886
|
} catch (err) {
|
|
22068
22887
|
if (isNoEntError(err))
|
|
@@ -22072,7 +22891,7 @@ async function deleteFromFile2(configDir, fs) {
|
|
|
22072
22891
|
}
|
|
22073
22892
|
async function deleteTokens(configDir, fs) {
|
|
22074
22893
|
const [keychain, file] = await Promise.all([
|
|
22075
|
-
|
|
22894
|
+
deleteFromKeychain2(),
|
|
22076
22895
|
deleteFromFile2(configDir, fs)
|
|
22077
22896
|
]);
|
|
22078
22897
|
return { keychain, file };
|
|
@@ -22121,10 +22940,9 @@ async function handleLogout(ctx, deps = {}) {
|
|
|
22121
22940
|
}
|
|
22122
22941
|
|
|
22123
22942
|
// src/domains/auth/refreshStoredSession.ts
|
|
22124
|
-
import { Entry as Entry8 } from "@napi-rs/keyring";
|
|
22125
22943
|
function makeDefaultDeps2(fs) {
|
|
22126
22944
|
return {
|
|
22127
|
-
loadTokens: (configDir) => loadTokens(configDir, {
|
|
22945
|
+
loadTokens: (configDir) => loadTokens(configDir, { loadEntryClass, fs }),
|
|
22128
22946
|
resolveOauth: (configDir) => resolveOauthToken(configDir, makeOauthDeps(fs))
|
|
22129
22947
|
};
|
|
22130
22948
|
}
|
|
@@ -22287,8 +23105,863 @@ function registerAuthCommand(program, signals) {
|
|
|
22287
23105
|
declareCommandKind(auth.command("whoami"), "read").description("Show authentication status").action(withContext(signals, handleWhoami));
|
|
22288
23106
|
}
|
|
22289
23107
|
|
|
23108
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel2Android14.js
|
|
23109
|
+
var androidPixel2Android14Target = {
|
|
23110
|
+
meta: {
|
|
23111
|
+
androidVersion: "34",
|
|
23112
|
+
deviceModel: "Pixel 2"
|
|
23113
|
+
},
|
|
23114
|
+
platform: "android",
|
|
23115
|
+
schemaVersion: 1
|
|
23116
|
+
};
|
|
23117
|
+
|
|
23118
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel9.js
|
|
23119
|
+
var androidPixel9Target = {
|
|
23120
|
+
meta: {
|
|
23121
|
+
androidVersion: "34",
|
|
23122
|
+
deviceModel: "Pixel 9"
|
|
23123
|
+
},
|
|
23124
|
+
platform: "android",
|
|
23125
|
+
schemaVersion: 1
|
|
23126
|
+
};
|
|
23127
|
+
|
|
23128
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel9Android14.js
|
|
23129
|
+
var androidPixel9Android14Target = {
|
|
23130
|
+
meta: {
|
|
23131
|
+
androidVersion: "34",
|
|
23132
|
+
deviceModel: "Pixel 9"
|
|
23133
|
+
},
|
|
23134
|
+
platform: "android",
|
|
23135
|
+
schemaVersion: 1
|
|
23136
|
+
};
|
|
23137
|
+
|
|
23138
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel9Android15.js
|
|
23139
|
+
var androidPixel9Android15Target = {
|
|
23140
|
+
meta: {
|
|
23141
|
+
androidVersion: "35",
|
|
23142
|
+
deviceModel: "Pixel 9"
|
|
23143
|
+
},
|
|
23144
|
+
platform: "android",
|
|
23145
|
+
schemaVersion: 1
|
|
23146
|
+
};
|
|
23147
|
+
|
|
23148
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel9Android16.js
|
|
23149
|
+
var androidPixel9Android16Target = {
|
|
23150
|
+
meta: {
|
|
23151
|
+
androidVersion: "36",
|
|
23152
|
+
deviceModel: "Pixel 9"
|
|
23153
|
+
},
|
|
23154
|
+
platform: "android",
|
|
23155
|
+
schemaVersion: 1
|
|
23156
|
+
};
|
|
23157
|
+
|
|
23158
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixel.js
|
|
23159
|
+
var androidPixelTarget = {
|
|
23160
|
+
meta: {
|
|
23161
|
+
androidVersion: "34",
|
|
23162
|
+
deviceModel: "Pixel 2"
|
|
23163
|
+
},
|
|
23164
|
+
platform: "android",
|
|
23165
|
+
schemaVersion: 1
|
|
23166
|
+
};
|
|
23167
|
+
|
|
23168
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidPixelTabletAndroid14.js
|
|
23169
|
+
var androidPixelTabletAndroid14Target = {
|
|
23170
|
+
meta: {
|
|
23171
|
+
androidVersion: "34",
|
|
23172
|
+
deviceModel: "Pixel Tablet"
|
|
23173
|
+
},
|
|
23174
|
+
platform: "android",
|
|
23175
|
+
schemaVersion: 1
|
|
23176
|
+
};
|
|
23177
|
+
|
|
23178
|
+
// node_modules/@qawolf/flow-targets/dist/presets/android/androidTablet.js
|
|
23179
|
+
var androidTabletTarget = {
|
|
23180
|
+
meta: {
|
|
23181
|
+
androidVersion: "34",
|
|
23182
|
+
deviceModel: "Pixel Tablet"
|
|
23183
|
+
},
|
|
23184
|
+
platform: "android",
|
|
23185
|
+
schemaVersion: 1
|
|
23186
|
+
};
|
|
23187
|
+
|
|
23188
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/allowlistedIphone.js
|
|
23189
|
+
var allowlistedIphoneTarget = {
|
|
23190
|
+
meta: {
|
|
23191
|
+
deviceModel: "iPhone 15",
|
|
23192
|
+
iosVersion: "26",
|
|
23193
|
+
targetDevices: "Allowlisted Device"
|
|
23194
|
+
},
|
|
23195
|
+
platform: "ios",
|
|
23196
|
+
schemaVersion: 1
|
|
23197
|
+
};
|
|
23198
|
+
|
|
23199
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/appleIdEnabledIpad.js
|
|
23200
|
+
var appleIdEnabledIpadTarget = {
|
|
23201
|
+
meta: {
|
|
23202
|
+
appleId: true,
|
|
23203
|
+
deviceModel: "iPad 11",
|
|
23204
|
+
iosVersion: "18"
|
|
23205
|
+
},
|
|
23206
|
+
platform: "ios",
|
|
23207
|
+
schemaVersion: 1
|
|
23208
|
+
};
|
|
23209
|
+
|
|
23210
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/appleIdEnabledIphone.js
|
|
23211
|
+
var appleIdEnabledIphoneTarget = {
|
|
23212
|
+
meta: {
|
|
23213
|
+
appleId: true,
|
|
23214
|
+
deviceModel: "iPhone 15",
|
|
23215
|
+
iosVersion: "26"
|
|
23216
|
+
},
|
|
23217
|
+
platform: "ios",
|
|
23218
|
+
schemaVersion: 1
|
|
23219
|
+
};
|
|
23220
|
+
|
|
23221
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/ipad11ios18.js
|
|
23222
|
+
var ipad11ios18Target = {
|
|
23223
|
+
meta: {
|
|
23224
|
+
deviceModel: "iPad 11",
|
|
23225
|
+
iosVersion: "18"
|
|
23226
|
+
},
|
|
23227
|
+
platform: "ios",
|
|
23228
|
+
schemaVersion: 1
|
|
23229
|
+
};
|
|
23230
|
+
|
|
23231
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/ipad11ios18AppleId.js
|
|
23232
|
+
var ipad11ios18AppleIdTarget = {
|
|
23233
|
+
meta: {
|
|
23234
|
+
appleId: true,
|
|
23235
|
+
deviceModel: "iPad 11",
|
|
23236
|
+
iosVersion: "18"
|
|
23237
|
+
},
|
|
23238
|
+
platform: "ios",
|
|
23239
|
+
schemaVersion: 1
|
|
23240
|
+
};
|
|
23241
|
+
|
|
23242
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/ipad11ios26.js
|
|
23243
|
+
var ipad11ios26Target = {
|
|
23244
|
+
meta: {
|
|
23245
|
+
deviceModel: "iPad 11",
|
|
23246
|
+
iosVersion: "26"
|
|
23247
|
+
},
|
|
23248
|
+
platform: "ios",
|
|
23249
|
+
schemaVersion: 1
|
|
23250
|
+
};
|
|
23251
|
+
|
|
23252
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/ipad.js
|
|
23253
|
+
var ipadTarget = {
|
|
23254
|
+
meta: {
|
|
23255
|
+
deviceModel: "iPad 11",
|
|
23256
|
+
iosVersion: "18"
|
|
23257
|
+
},
|
|
23258
|
+
platform: "ios",
|
|
23259
|
+
schemaVersion: 1
|
|
23260
|
+
};
|
|
23261
|
+
|
|
23262
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios17.js
|
|
23263
|
+
var iphone15ios17Target = {
|
|
23264
|
+
meta: {
|
|
23265
|
+
deviceModel: "iPhone 15",
|
|
23266
|
+
iosVersion: "17"
|
|
23267
|
+
},
|
|
23268
|
+
platform: "ios",
|
|
23269
|
+
schemaVersion: 1
|
|
23270
|
+
};
|
|
23271
|
+
|
|
23272
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios18.js
|
|
23273
|
+
var iphone15ios18Target = {
|
|
23274
|
+
meta: {
|
|
23275
|
+
deviceModel: "iPhone 15",
|
|
23276
|
+
iosVersion: "18"
|
|
23277
|
+
},
|
|
23278
|
+
platform: "ios",
|
|
23279
|
+
schemaVersion: 1
|
|
23280
|
+
};
|
|
23281
|
+
|
|
23282
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios26.js
|
|
23283
|
+
var iphone15ios26Target = {
|
|
23284
|
+
meta: {
|
|
23285
|
+
deviceModel: "iPhone 15",
|
|
23286
|
+
iosVersion: "26"
|
|
23287
|
+
},
|
|
23288
|
+
platform: "ios",
|
|
23289
|
+
schemaVersion: 1
|
|
23290
|
+
};
|
|
23291
|
+
|
|
23292
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios26Allowlisted.js
|
|
23293
|
+
var iphone15ios26AllowlistedTarget = {
|
|
23294
|
+
meta: {
|
|
23295
|
+
deviceModel: "iPhone 15",
|
|
23296
|
+
iosVersion: "26",
|
|
23297
|
+
targetDevices: "Allowlisted Device"
|
|
23298
|
+
},
|
|
23299
|
+
platform: "ios",
|
|
23300
|
+
schemaVersion: 1
|
|
23301
|
+
};
|
|
23302
|
+
|
|
23303
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios26AppleId.js
|
|
23304
|
+
var iphone15ios26AppleIdTarget = {
|
|
23305
|
+
meta: {
|
|
23306
|
+
appleId: true,
|
|
23307
|
+
deviceModel: "iPhone 15",
|
|
23308
|
+
iosVersion: "26"
|
|
23309
|
+
},
|
|
23310
|
+
platform: "ios",
|
|
23311
|
+
schemaVersion: 1
|
|
23312
|
+
};
|
|
23313
|
+
|
|
23314
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone15ios26Private.js
|
|
23315
|
+
var iphone15ios26PrivateTarget = {
|
|
23316
|
+
meta: {
|
|
23317
|
+
deviceModel: "iPhone 15",
|
|
23318
|
+
iosVersion: "26",
|
|
23319
|
+
targetDevices: "Team Dedicated Device"
|
|
23320
|
+
},
|
|
23321
|
+
platform: "ios",
|
|
23322
|
+
schemaVersion: 1
|
|
23323
|
+
};
|
|
23324
|
+
|
|
23325
|
+
// node_modules/@qawolf/flow-targets/dist/presets/ios/iphone17ios26.js
|
|
23326
|
+
var iphone17ios26Target = {
|
|
23327
|
+
meta: {
|
|
23328
|
+
deviceModel: "iPhone 17",
|
|
23329
|
+
iosVersion: "26"
|
|
23330
|
+
},
|
|
23331
|
+
platform: "ios",
|
|
23332
|
+
schemaVersion: 1
|
|
23333
|
+
};
|
|
23334
|
+
|
|
23335
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/basic.js
|
|
23336
|
+
var webBasicTarget = {
|
|
23337
|
+
meta: "legacy",
|
|
23338
|
+
platform: "web",
|
|
23339
|
+
schemaVersion: 1
|
|
23340
|
+
};
|
|
23341
|
+
|
|
23342
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/chrome.js
|
|
23343
|
+
var webChromeTarget = {
|
|
23344
|
+
meta: {
|
|
23345
|
+
defaultBrowser: {
|
|
23346
|
+
name: "chrome"
|
|
23347
|
+
},
|
|
23348
|
+
gpuEnabled: false
|
|
23349
|
+
},
|
|
23350
|
+
platform: "web",
|
|
23351
|
+
schemaVersion: 1
|
|
23352
|
+
};
|
|
23353
|
+
|
|
23354
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/chromeWithGpu.js
|
|
23355
|
+
var webChromeWithGpuTarget = {
|
|
23356
|
+
meta: {
|
|
23357
|
+
defaultBrowser: {
|
|
23358
|
+
name: "chrome"
|
|
23359
|
+
},
|
|
23360
|
+
gpuEnabled: true
|
|
23361
|
+
},
|
|
23362
|
+
platform: "web",
|
|
23363
|
+
schemaVersion: 1
|
|
23364
|
+
};
|
|
23365
|
+
|
|
23366
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/electron.js
|
|
23367
|
+
var webElectronTarget = {
|
|
23368
|
+
meta: {
|
|
23369
|
+
gpuEnabled: false,
|
|
23370
|
+
kind: "electron"
|
|
23371
|
+
},
|
|
23372
|
+
platform: "web",
|
|
23373
|
+
schemaVersion: 1
|
|
23374
|
+
};
|
|
23375
|
+
|
|
23376
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/firefox.js
|
|
23377
|
+
var webFirefoxTarget = {
|
|
23378
|
+
meta: {
|
|
23379
|
+
defaultBrowser: {
|
|
23380
|
+
name: "firefox"
|
|
23381
|
+
},
|
|
23382
|
+
gpuEnabled: false
|
|
23383
|
+
},
|
|
23384
|
+
platform: "web",
|
|
23385
|
+
schemaVersion: 1
|
|
23386
|
+
};
|
|
23387
|
+
|
|
23388
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/firefoxWithGpu.js
|
|
23389
|
+
var webFirefoxWithGpuTarget = {
|
|
23390
|
+
meta: {
|
|
23391
|
+
defaultBrowser: {
|
|
23392
|
+
name: "firefox"
|
|
23393
|
+
},
|
|
23394
|
+
gpuEnabled: true
|
|
23395
|
+
},
|
|
23396
|
+
platform: "web",
|
|
23397
|
+
schemaVersion: 1
|
|
23398
|
+
};
|
|
23399
|
+
|
|
23400
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/safari.js
|
|
23401
|
+
var webSafariTarget = {
|
|
23402
|
+
meta: {
|
|
23403
|
+
defaultBrowser: {
|
|
23404
|
+
name: "safari"
|
|
23405
|
+
},
|
|
23406
|
+
gpuEnabled: false
|
|
23407
|
+
},
|
|
23408
|
+
platform: "web",
|
|
23409
|
+
schemaVersion: 1
|
|
23410
|
+
};
|
|
23411
|
+
|
|
23412
|
+
// node_modules/@qawolf/flow-targets/dist/presets/web/safariWithGpu.js
|
|
23413
|
+
var webSafariWithGpuTarget = {
|
|
23414
|
+
meta: {
|
|
23415
|
+
defaultBrowser: {
|
|
23416
|
+
name: "safari"
|
|
23417
|
+
},
|
|
23418
|
+
gpuEnabled: true
|
|
23419
|
+
},
|
|
23420
|
+
platform: "web",
|
|
23421
|
+
schemaVersion: 1
|
|
23422
|
+
};
|
|
23423
|
+
|
|
23424
|
+
// node_modules/@qawolf/flow-targets/dist/presets/index.js
|
|
23425
|
+
var androidPresetLiteralRaw = [
|
|
23426
|
+
"Android - Pixel",
|
|
23427
|
+
"Android - Pixel 2 (Android 14)",
|
|
23428
|
+
"Android - Pixel 9",
|
|
23429
|
+
"Android - Pixel 9 (Android 14)",
|
|
23430
|
+
"Android - Pixel 9 (Android 15)",
|
|
23431
|
+
"Android - Pixel 9 (Android 16)",
|
|
23432
|
+
"Android - Pixel Tablet (Android 14)",
|
|
23433
|
+
"Android - Tablet"
|
|
23434
|
+
];
|
|
23435
|
+
var androidPresetLiteralSchema = _enum(androidPresetLiteralRaw);
|
|
23436
|
+
var iosPresetLiteralRaw = [
|
|
23437
|
+
"iOS - Allowlisted iPhone",
|
|
23438
|
+
"iOS - Apple ID Enabled iPad",
|
|
23439
|
+
"iOS - Apple ID Enabled iPhone",
|
|
23440
|
+
"iOS - iPad",
|
|
23441
|
+
"iOS - iPad 11 (iOS 18)",
|
|
23442
|
+
"iOS - iPad 11 (iOS 18) (Apple ID)",
|
|
23443
|
+
"iOS - iPad 11 (iOS 26)",
|
|
23444
|
+
"iOS - iPhone 15 (iOS 17)",
|
|
23445
|
+
"iOS - iPhone 15 (iOS 18)",
|
|
23446
|
+
"iOS - iPhone 15 (iOS 26)",
|
|
23447
|
+
"iOS - iPhone 15 (iOS 26) (Apple ID)",
|
|
23448
|
+
"iOS - iPhone 15 (iOS 26) (allowlisted)",
|
|
23449
|
+
"iOS - iPhone 15 (iOS 26) (private)",
|
|
23450
|
+
"iOS - iPhone 17 (iOS 26)"
|
|
23451
|
+
];
|
|
23452
|
+
var iosPresetLiteralSchema = _enum(iosPresetLiteralRaw);
|
|
23453
|
+
var webPresetLiteralRaw = [
|
|
23454
|
+
"Basic",
|
|
23455
|
+
"Electron",
|
|
23456
|
+
"Web - Chrome",
|
|
23457
|
+
"Web - Chrome (GPU)",
|
|
23458
|
+
"Web - Firefox",
|
|
23459
|
+
"Web - Firefox (GPU)",
|
|
23460
|
+
"Web - Safari",
|
|
23461
|
+
"Web - Safari (GPU)"
|
|
23462
|
+
];
|
|
23463
|
+
var webPresetLiteralSchema = _enum(webPresetLiteralRaw);
|
|
23464
|
+
var presetLiteralsSchema = union([
|
|
23465
|
+
androidPresetLiteralSchema,
|
|
23466
|
+
iosPresetLiteralSchema,
|
|
23467
|
+
webPresetLiteralSchema
|
|
23468
|
+
]);
|
|
23469
|
+
var presetTargetMap = {
|
|
23470
|
+
"Android - Pixel": androidPixelTarget,
|
|
23471
|
+
"Android - Pixel 2 (Android 14)": androidPixel2Android14Target,
|
|
23472
|
+
"Android - Pixel 9": androidPixel9Target,
|
|
23473
|
+
"Android - Pixel 9 (Android 14)": androidPixel9Android14Target,
|
|
23474
|
+
"Android - Pixel 9 (Android 15)": androidPixel9Android15Target,
|
|
23475
|
+
"Android - Pixel 9 (Android 16)": androidPixel9Android16Target,
|
|
23476
|
+
"Android - Pixel Tablet (Android 14)": androidPixelTabletAndroid14Target,
|
|
23477
|
+
"Android - Tablet": androidTabletTarget,
|
|
23478
|
+
Basic: webBasicTarget,
|
|
23479
|
+
Electron: webElectronTarget,
|
|
23480
|
+
"iOS - Allowlisted iPhone": allowlistedIphoneTarget,
|
|
23481
|
+
"iOS - Apple ID Enabled iPad": appleIdEnabledIpadTarget,
|
|
23482
|
+
"iOS - Apple ID Enabled iPhone": appleIdEnabledIphoneTarget,
|
|
23483
|
+
"iOS - iPad": ipadTarget,
|
|
23484
|
+
"iOS - iPad 11 (iOS 18)": ipad11ios18Target,
|
|
23485
|
+
"iOS - iPad 11 (iOS 18) (Apple ID)": ipad11ios18AppleIdTarget,
|
|
23486
|
+
"iOS - iPad 11 (iOS 26)": ipad11ios26Target,
|
|
23487
|
+
"iOS - iPhone 15 (iOS 17)": iphone15ios17Target,
|
|
23488
|
+
"iOS - iPhone 15 (iOS 18)": iphone15ios18Target,
|
|
23489
|
+
"iOS - iPhone 15 (iOS 26)": iphone15ios26Target,
|
|
23490
|
+
"iOS - iPhone 15 (iOS 26) (allowlisted)": iphone15ios26AllowlistedTarget,
|
|
23491
|
+
"iOS - iPhone 15 (iOS 26) (Apple ID)": iphone15ios26AppleIdTarget,
|
|
23492
|
+
"iOS - iPhone 15 (iOS 26) (private)": iphone15ios26PrivateTarget,
|
|
23493
|
+
"iOS - iPhone 17 (iOS 26)": iphone17ios26Target,
|
|
23494
|
+
"Web - Chrome": webChromeTarget,
|
|
23495
|
+
"Web - Chrome (GPU)": webChromeWithGpuTarget,
|
|
23496
|
+
"Web - Firefox": webFirefoxTarget,
|
|
23497
|
+
"Web - Firefox (GPU)": webFirefoxWithGpuTarget,
|
|
23498
|
+
"Web - Safari": webSafariTarget,
|
|
23499
|
+
"Web - Safari (GPU)": webSafariWithGpuTarget
|
|
23500
|
+
};
|
|
23501
|
+
|
|
23502
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/shared/screenDimensions.js
|
|
23503
|
+
var screenDimensions = {
|
|
23504
|
+
"iPad 11": { screenHeight: 2360, screenWidth: 1640 },
|
|
23505
|
+
"iPhone 15": { screenHeight: 2556, screenWidth: 1179 },
|
|
23506
|
+
"iPhone 15 Plus": { screenHeight: 2796, screenWidth: 1290 },
|
|
23507
|
+
"iPhone 15 Pro Max": { screenHeight: 2868, screenWidth: 1320 },
|
|
23508
|
+
"iPhone 16 Plus": { screenHeight: 2796, screenWidth: 1290 },
|
|
23509
|
+
"iPhone 17": { screenHeight: 2622, screenWidth: 1206 },
|
|
23510
|
+
"Pixel 2": { screenHeight: 1920, screenWidth: 1080 },
|
|
23511
|
+
"Pixel 9": { screenHeight: 2424, screenWidth: 1080 },
|
|
23512
|
+
"Pixel Tablet": { screenHeight: 1600, screenWidth: 2560 },
|
|
23513
|
+
playwright_default: { screenHeight: 804, screenWidth: 1288 }
|
|
23514
|
+
};
|
|
23515
|
+
|
|
23516
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/shared/platforms.js
|
|
23517
|
+
var platformsSchema = _enum(["web", "android", "ios"]);
|
|
23518
|
+
|
|
23519
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/shared/runnerNames.js
|
|
23520
|
+
var runnerNamesSchema = _enum([
|
|
23521
|
+
"node20Basic",
|
|
23522
|
+
"classic",
|
|
23523
|
+
"node20GpuWithPlaywright",
|
|
23524
|
+
"node20WithPlaywright",
|
|
23525
|
+
"node20WithAndroid",
|
|
23526
|
+
"node20WithIos"
|
|
23527
|
+
]);
|
|
23528
|
+
|
|
23529
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/shared/baseSchemas.js
|
|
23530
|
+
var baseInputSchema = object({
|
|
23531
|
+
platform: platformsSchema,
|
|
23532
|
+
schemaVersion: int().positive()
|
|
23533
|
+
});
|
|
23534
|
+
var baseOutputSchema = baseInputSchema.extend({
|
|
23535
|
+
runnerName: runnerNamesSchema
|
|
23536
|
+
});
|
|
23537
|
+
|
|
23538
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/android/v1/supportedModelsSchema.js
|
|
23539
|
+
var supportedModelsInputSchema = _enum([
|
|
23540
|
+
"Pixel 2",
|
|
23541
|
+
"Pixel Tablet",
|
|
23542
|
+
"Pixel 9"
|
|
23543
|
+
]);
|
|
23544
|
+
var supportedModelsOutputSchema = _enum([
|
|
23545
|
+
"pixel_2",
|
|
23546
|
+
"pixel_tablet",
|
|
23547
|
+
"pixel_9"
|
|
23548
|
+
]);
|
|
23549
|
+
var supportedModelsSchema = codec(supportedModelsInputSchema, supportedModelsOutputSchema, {
|
|
23550
|
+
decode(deviceModel) {
|
|
23551
|
+
switch (deviceModel) {
|
|
23552
|
+
case "Pixel 2":
|
|
23553
|
+
return "pixel_2";
|
|
23554
|
+
case "Pixel 9":
|
|
23555
|
+
return "pixel_9";
|
|
23556
|
+
case "Pixel Tablet":
|
|
23557
|
+
return "pixel_tablet";
|
|
23558
|
+
default:
|
|
23559
|
+
throw Error(`Unsupported device model: ${deviceModel}`);
|
|
23560
|
+
}
|
|
23561
|
+
},
|
|
23562
|
+
encode(deviceModel) {
|
|
23563
|
+
switch (deviceModel) {
|
|
23564
|
+
case "pixel_2":
|
|
23565
|
+
return "Pixel 2";
|
|
23566
|
+
case "pixel_9":
|
|
23567
|
+
return "Pixel 9";
|
|
23568
|
+
case "pixel_tablet":
|
|
23569
|
+
return "Pixel Tablet";
|
|
23570
|
+
default:
|
|
23571
|
+
throw Error(`Unsupported device model: ${deviceModel}`);
|
|
23572
|
+
}
|
|
23573
|
+
}
|
|
23574
|
+
});
|
|
23575
|
+
|
|
23576
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/android/v1/input.js
|
|
23577
|
+
var supportedVersionsSchema = _enum(["34", "35", "36"]);
|
|
23578
|
+
var androidMetaInputSchema = discriminatedUnion("deviceModel", [
|
|
23579
|
+
object({
|
|
23580
|
+
androidVersion: supportedVersionsSchema.extract(["34"]),
|
|
23581
|
+
deviceModel: supportedModelsInputSchema.extract(["Pixel 2"])
|
|
23582
|
+
}),
|
|
23583
|
+
object({
|
|
23584
|
+
androidVersion: supportedVersionsSchema.extract(["34"]),
|
|
23585
|
+
deviceModel: supportedModelsInputSchema.extract(["Pixel Tablet"])
|
|
23586
|
+
}),
|
|
23587
|
+
object({
|
|
23588
|
+
androidVersion: supportedVersionsSchema.extract(["34", "35", "36"]),
|
|
23589
|
+
deviceModel: supportedModelsInputSchema.extract(["Pixel 9"])
|
|
23590
|
+
})
|
|
23591
|
+
]);
|
|
23592
|
+
var androidTargetInputSchema = baseInputSchema.extend({
|
|
23593
|
+
meta: androidMetaInputSchema,
|
|
23594
|
+
platform: platformsSchema.extract(["android"]),
|
|
23595
|
+
schemaVersion: literal(1)
|
|
23596
|
+
});
|
|
23597
|
+
|
|
23598
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/android/v1/output.js
|
|
23599
|
+
var androidTargetOutputSchema = baseOutputSchema.extend({
|
|
23600
|
+
...androidTargetInputSchema.shape,
|
|
23601
|
+
meta: object({
|
|
23602
|
+
androidVersion: supportedVersionsSchema,
|
|
23603
|
+
deviceModel: supportedModelsOutputSchema,
|
|
23604
|
+
screenHeight: number2(),
|
|
23605
|
+
screenWidth: number2()
|
|
23606
|
+
}),
|
|
23607
|
+
runnerName: runnerNamesSchema.extract(["node20WithAndroid"])
|
|
23608
|
+
});
|
|
23609
|
+
|
|
23610
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/android/v1/index.js
|
|
23611
|
+
var androidExecutionTargetSchema = codec(androidTargetInputSchema, androidTargetOutputSchema, {
|
|
23612
|
+
decode(value) {
|
|
23613
|
+
return {
|
|
23614
|
+
...value,
|
|
23615
|
+
meta: {
|
|
23616
|
+
...value.meta,
|
|
23617
|
+
deviceModel: supportedModelsSchema.decode(value.meta.deviceModel),
|
|
23618
|
+
...screenDimensions[value.meta.deviceModel]
|
|
23619
|
+
},
|
|
23620
|
+
runnerName: "node20WithAndroid"
|
|
23621
|
+
};
|
|
23622
|
+
},
|
|
23623
|
+
encode(value) {
|
|
23624
|
+
return androidTargetInputSchema.parse({
|
|
23625
|
+
...value,
|
|
23626
|
+
meta: {
|
|
23627
|
+
...value.meta,
|
|
23628
|
+
deviceModel: supportedModelsSchema.encode(value.meta.deviceModel)
|
|
23629
|
+
}
|
|
23630
|
+
});
|
|
23631
|
+
}
|
|
23632
|
+
});
|
|
23633
|
+
|
|
23634
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/android/index.js
|
|
23635
|
+
var androidExecutionTargetInputSchema = discriminatedUnion("schemaVersion", [androidTargetInputSchema]);
|
|
23636
|
+
var androidExecutionTargetOutputSchema = discriminatedUnion("schemaVersion", [androidTargetOutputSchema]);
|
|
23637
|
+
var androidExecutionTargetSchema2 = discriminatedUnion("schemaVersion", [androidExecutionTargetSchema]);
|
|
23638
|
+
|
|
23639
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/v1/supportedModelsSchema.js
|
|
23640
|
+
var supportedModelsInputSchema2 = _enum([
|
|
23641
|
+
"iPhone 15",
|
|
23642
|
+
"iPhone 15 Plus",
|
|
23643
|
+
"iPhone 15 Pro Max",
|
|
23644
|
+
"iPhone 16 Plus",
|
|
23645
|
+
"iPhone 17",
|
|
23646
|
+
"iPad 11"
|
|
23647
|
+
]);
|
|
23648
|
+
var supportedModelsOutputSchema2 = _enum([
|
|
23649
|
+
"iphone15_4",
|
|
23650
|
+
"iphone15_5",
|
|
23651
|
+
"iphone16_2",
|
|
23652
|
+
"iphone17_4",
|
|
23653
|
+
"iphone18_3",
|
|
23654
|
+
"ipad15_7"
|
|
23655
|
+
]);
|
|
23656
|
+
var supportedModelsSchema2 = codec(supportedModelsInputSchema2, supportedModelsOutputSchema2, {
|
|
23657
|
+
decode(deviceModel) {
|
|
23658
|
+
switch (deviceModel) {
|
|
23659
|
+
case "iPad 11":
|
|
23660
|
+
return "ipad15_7";
|
|
23661
|
+
case "iPhone 15":
|
|
23662
|
+
return "iphone15_4";
|
|
23663
|
+
case "iPhone 15 Plus":
|
|
23664
|
+
return "iphone15_5";
|
|
23665
|
+
case "iPhone 15 Pro Max":
|
|
23666
|
+
return "iphone16_2";
|
|
23667
|
+
case "iPhone 16 Plus":
|
|
23668
|
+
return "iphone17_4";
|
|
23669
|
+
case "iPhone 17":
|
|
23670
|
+
return "iphone18_3";
|
|
23671
|
+
default:
|
|
23672
|
+
throw Error(`Unsupported device model: ${deviceModel}`);
|
|
23673
|
+
}
|
|
23674
|
+
},
|
|
23675
|
+
encode(value) {
|
|
23676
|
+
switch (value) {
|
|
23677
|
+
case "ipad15_7":
|
|
23678
|
+
return "iPad 11";
|
|
23679
|
+
case "iphone15_4":
|
|
23680
|
+
return "iPhone 15";
|
|
23681
|
+
case "iphone15_5":
|
|
23682
|
+
return "iPhone 15 Plus";
|
|
23683
|
+
case "iphone16_2":
|
|
23684
|
+
return "iPhone 15 Pro Max";
|
|
23685
|
+
case "iphone17_4":
|
|
23686
|
+
return "iPhone 16 Plus";
|
|
23687
|
+
case "iphone18_3":
|
|
23688
|
+
return "iPhone 17";
|
|
23689
|
+
default:
|
|
23690
|
+
throw Error(`Unsupported device model: ${value}`);
|
|
23691
|
+
}
|
|
23692
|
+
}
|
|
23693
|
+
});
|
|
23694
|
+
|
|
23695
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/v1/supportedTargetDevicesSchema.js
|
|
23696
|
+
var supportedTargetDevicesInputSchema = _enum([
|
|
23697
|
+
"Any Device",
|
|
23698
|
+
"Allowlisted Device",
|
|
23699
|
+
"Team Dedicated Device"
|
|
23700
|
+
]);
|
|
23701
|
+
var supportedTargetDevicesOutputSchema = _enum([
|
|
23702
|
+
"anyDevice",
|
|
23703
|
+
"allowlistedDevice",
|
|
23704
|
+
"teamDedicatedDevice"
|
|
23705
|
+
]);
|
|
23706
|
+
var supportedTargetDevicesSchema = codec(supportedTargetDevicesInputSchema, supportedTargetDevicesOutputSchema, {
|
|
23707
|
+
decode(targetDevices) {
|
|
23708
|
+
switch (targetDevices) {
|
|
23709
|
+
case "Allowlisted Device":
|
|
23710
|
+
return "allowlistedDevice";
|
|
23711
|
+
case "Any Device":
|
|
23712
|
+
return "anyDevice";
|
|
23713
|
+
case "Team Dedicated Device":
|
|
23714
|
+
return "teamDedicatedDevice";
|
|
23715
|
+
default:
|
|
23716
|
+
throw Error(`Unsupported target devices: ${targetDevices}`);
|
|
23717
|
+
}
|
|
23718
|
+
},
|
|
23719
|
+
encode(targetDevices) {
|
|
23720
|
+
switch (targetDevices) {
|
|
23721
|
+
case "allowlistedDevice":
|
|
23722
|
+
return "Allowlisted Device";
|
|
23723
|
+
case "anyDevice":
|
|
23724
|
+
return "Any Device";
|
|
23725
|
+
case "teamDedicatedDevice":
|
|
23726
|
+
return "Team Dedicated Device";
|
|
23727
|
+
default:
|
|
23728
|
+
throw Error(`Unsupported target devices: ${targetDevices}`);
|
|
23729
|
+
}
|
|
23730
|
+
}
|
|
23731
|
+
});
|
|
23732
|
+
|
|
23733
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/v1/input.js
|
|
23734
|
+
var supportedVersionsInputSchema = _enum(["17", "18", "26"]);
|
|
23735
|
+
var baseMetaInputSchema = object({
|
|
23736
|
+
appleId: union([email2(), boolean2()]).optional(),
|
|
23737
|
+
deviceUdid: string2().optional(),
|
|
23738
|
+
targetDevices: supportedTargetDevicesInputSchema.default("Any Device")
|
|
23739
|
+
});
|
|
23740
|
+
var iosMetaInputSchema = discriminatedUnion("deviceModel", [
|
|
23741
|
+
baseMetaInputSchema.extend({
|
|
23742
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPhone 15"]),
|
|
23743
|
+
iosVersion: supportedVersionsInputSchema.extract(["17", "18", "26"])
|
|
23744
|
+
}),
|
|
23745
|
+
baseMetaInputSchema.extend({
|
|
23746
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPhone 15 Plus"]),
|
|
23747
|
+
iosVersion: supportedVersionsInputSchema.extract(["17"])
|
|
23748
|
+
}),
|
|
23749
|
+
baseMetaInputSchema.extend({
|
|
23750
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPhone 15 Pro Max"]),
|
|
23751
|
+
iosVersion: supportedVersionsInputSchema.extract(["17"])
|
|
23752
|
+
}),
|
|
23753
|
+
baseMetaInputSchema.extend({
|
|
23754
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPhone 16 Plus"]),
|
|
23755
|
+
iosVersion: supportedVersionsInputSchema.extract(["26"])
|
|
23756
|
+
}),
|
|
23757
|
+
baseMetaInputSchema.extend({
|
|
23758
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPhone 17"]),
|
|
23759
|
+
iosVersion: supportedVersionsInputSchema.extract(["26"])
|
|
23760
|
+
}),
|
|
23761
|
+
baseMetaInputSchema.extend({
|
|
23762
|
+
deviceModel: supportedModelsInputSchema2.extract(["iPad 11"]),
|
|
23763
|
+
iosVersion: supportedVersionsInputSchema.extract(["18", "26"])
|
|
23764
|
+
})
|
|
23765
|
+
]);
|
|
23766
|
+
var iosTargetInputSchema = baseInputSchema.extend({
|
|
23767
|
+
meta: iosMetaInputSchema,
|
|
23768
|
+
platform: platformsSchema.extract(["ios"]),
|
|
23769
|
+
schemaVersion: literal(1)
|
|
23770
|
+
});
|
|
23771
|
+
|
|
23772
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/v1/output.js
|
|
23773
|
+
var iosTargetOutputSchema = baseOutputSchema.extend({
|
|
23774
|
+
...iosTargetInputSchema.shape,
|
|
23775
|
+
meta: object({
|
|
23776
|
+
appleId: union([email2(), boolean2()]).optional(),
|
|
23777
|
+
deviceModel: supportedModelsOutputSchema2,
|
|
23778
|
+
deviceUdid: string2().optional(),
|
|
23779
|
+
iosVersion: supportedVersionsInputSchema,
|
|
23780
|
+
screenHeight: number2(),
|
|
23781
|
+
screenWidth: number2(),
|
|
23782
|
+
targetDevices: supportedTargetDevicesOutputSchema
|
|
23783
|
+
}),
|
|
23784
|
+
runnerName: runnerNamesSchema.extract(["node20WithIos"])
|
|
23785
|
+
});
|
|
23786
|
+
|
|
23787
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/v1/index.js
|
|
23788
|
+
var iosExecutionTargetSchema = codec(iosTargetInputSchema, iosTargetOutputSchema, {
|
|
23789
|
+
decode(value) {
|
|
23790
|
+
return {
|
|
23791
|
+
...value,
|
|
23792
|
+
meta: {
|
|
23793
|
+
...value.meta,
|
|
23794
|
+
appleId: value.meta.appleId || undefined,
|
|
23795
|
+
deviceModel: supportedModelsSchema2.decode(value.meta.deviceModel),
|
|
23796
|
+
...screenDimensions[value.meta.deviceModel],
|
|
23797
|
+
targetDevices: supportedTargetDevicesSchema.decode(value.meta.targetDevices)
|
|
23798
|
+
},
|
|
23799
|
+
runnerName: "node20WithIos"
|
|
23800
|
+
};
|
|
23801
|
+
},
|
|
23802
|
+
encode(value) {
|
|
23803
|
+
return iosTargetInputSchema.parse({
|
|
23804
|
+
...value,
|
|
23805
|
+
meta: {
|
|
23806
|
+
...value.meta,
|
|
23807
|
+
deviceModel: supportedModelsSchema2.encode(value.meta.deviceModel),
|
|
23808
|
+
targetDevices: supportedTargetDevicesSchema.encode(value.meta.targetDevices)
|
|
23809
|
+
}
|
|
23810
|
+
});
|
|
23811
|
+
}
|
|
23812
|
+
});
|
|
23813
|
+
|
|
23814
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/ios/index.js
|
|
23815
|
+
var iosExecutionTargetInputSchema = discriminatedUnion("schemaVersion", [iosTargetInputSchema]);
|
|
23816
|
+
var iosExecutionTargetOutputSchema = discriminatedUnion("schemaVersion", [iosTargetOutputSchema]);
|
|
23817
|
+
var iosExecutionTargetSchema2 = discriminatedUnion("schemaVersion", [
|
|
23818
|
+
iosExecutionTargetSchema
|
|
23819
|
+
]);
|
|
23820
|
+
|
|
23821
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/web/v1/input.js
|
|
23822
|
+
var supportedBrowserNamesSchema = _enum(["chrome", "firefox", "safari"]);
|
|
23823
|
+
var defaultScreenDimensions = {
|
|
23824
|
+
height: 804,
|
|
23825
|
+
width: 1288
|
|
23826
|
+
};
|
|
23827
|
+
var webBrowserInputSchema = object({
|
|
23828
|
+
name: supportedBrowserNamesSchema,
|
|
23829
|
+
screenHeight: int().positive().default(defaultScreenDimensions.height),
|
|
23830
|
+
screenWidth: int().positive().default(defaultScreenDimensions.width)
|
|
23831
|
+
});
|
|
23832
|
+
var defaultBrowserInfoSchema = object({
|
|
23833
|
+
browser: optional(never()),
|
|
23834
|
+
defaultBrowser: webBrowserInputSchema,
|
|
23835
|
+
gpuEnabled: boolean2(),
|
|
23836
|
+
kind: literal("browser").default("browser")
|
|
23837
|
+
});
|
|
23838
|
+
var legacyBrowserInfoSchema = object({
|
|
23839
|
+
browser: webBrowserInputSchema,
|
|
23840
|
+
defaultBrowser: optional(never()),
|
|
23841
|
+
gpuEnabled: boolean2(),
|
|
23842
|
+
kind: literal("browser").default("browser")
|
|
23843
|
+
});
|
|
23844
|
+
var electronInfoSchema = object({
|
|
23845
|
+
browser: optional(never()),
|
|
23846
|
+
defaultBrowser: optional(never()),
|
|
23847
|
+
gpuEnabled: literal(false).default(false),
|
|
23848
|
+
kind: literal("electron")
|
|
23849
|
+
});
|
|
23850
|
+
var browserInfoSchema = union([
|
|
23851
|
+
defaultBrowserInfoSchema,
|
|
23852
|
+
legacyBrowserInfoSchema
|
|
23853
|
+
]);
|
|
23854
|
+
var webMetaSchema = union([browserInfoSchema, electronInfoSchema]);
|
|
23855
|
+
var webTargetInputSchema = baseInputSchema.extend({
|
|
23856
|
+
meta: union([webMetaSchema, literal("legacy")]),
|
|
23857
|
+
platform: platformsSchema.extract(["web"]),
|
|
23858
|
+
schemaVersion: literal(1)
|
|
23859
|
+
});
|
|
23860
|
+
function getWebBrowserInfo(meta) {
|
|
23861
|
+
if ("defaultBrowser" in meta && meta.defaultBrowser)
|
|
23862
|
+
return webBrowserInputSchema.parse(meta.defaultBrowser);
|
|
23863
|
+
if ("browser" in meta && meta.browser)
|
|
23864
|
+
return webBrowserInputSchema.parse(meta.browser);
|
|
23865
|
+
throw Error("Expected either defaultBrowser or browser in web meta");
|
|
23866
|
+
}
|
|
23867
|
+
|
|
23868
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/web/v1/webRunnerNames.js
|
|
23869
|
+
var webRunnerNamesSchema = runnerNamesSchema.extract([
|
|
23870
|
+
"node20Basic",
|
|
23871
|
+
"node20WithPlaywright",
|
|
23872
|
+
"node20GpuWithPlaywright"
|
|
23873
|
+
]);
|
|
23874
|
+
|
|
23875
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/web/v1/output.js
|
|
23876
|
+
var webOutputMetaSchema = union([
|
|
23877
|
+
object({
|
|
23878
|
+
defaultBrowser: webBrowserInputSchema,
|
|
23879
|
+
gpuEnabled: boolean2(),
|
|
23880
|
+
kind: literal("browser").default("browser")
|
|
23881
|
+
}),
|
|
23882
|
+
object({
|
|
23883
|
+
browser: webBrowserInputSchema,
|
|
23884
|
+
gpuEnabled: boolean2(),
|
|
23885
|
+
kind: literal("browser").default("browser")
|
|
23886
|
+
}),
|
|
23887
|
+
object({
|
|
23888
|
+
gpuEnabled: literal(false),
|
|
23889
|
+
kind: literal("electron")
|
|
23890
|
+
}),
|
|
23891
|
+
literal("legacy")
|
|
23892
|
+
]);
|
|
23893
|
+
var webTargetOutputSchema = baseOutputSchema.extend({
|
|
23894
|
+
meta: webOutputMetaSchema,
|
|
23895
|
+
platform: literal("web"),
|
|
23896
|
+
runnerName: webRunnerNamesSchema,
|
|
23897
|
+
schemaVersion: literal(1)
|
|
23898
|
+
});
|
|
23899
|
+
|
|
23900
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/web/v1/index.js
|
|
23901
|
+
var webExecutionTargetSchema = codec(webTargetInputSchema, webTargetOutputSchema, {
|
|
23902
|
+
decode(value) {
|
|
23903
|
+
const runnerName = value.meta === "legacy" ? "node20Basic" : value.meta.gpuEnabled ? "node20GpuWithPlaywright" : "node20WithPlaywright";
|
|
23904
|
+
let meta;
|
|
23905
|
+
if (value.meta === "legacy")
|
|
23906
|
+
meta = value.meta;
|
|
23907
|
+
else if (value.meta.kind === "electron") {
|
|
23908
|
+
meta = {
|
|
23909
|
+
gpuEnabled: false,
|
|
23910
|
+
kind: "electron"
|
|
23911
|
+
};
|
|
23912
|
+
} else {
|
|
23913
|
+
const browserInfo = getWebBrowserInfo(value.meta);
|
|
23914
|
+
meta = {
|
|
23915
|
+
defaultBrowser: browserInfo,
|
|
23916
|
+
gpuEnabled: value.meta.gpuEnabled,
|
|
23917
|
+
kind: "browser"
|
|
23918
|
+
};
|
|
23919
|
+
}
|
|
23920
|
+
return {
|
|
23921
|
+
...value,
|
|
23922
|
+
meta,
|
|
23923
|
+
runnerName
|
|
23924
|
+
};
|
|
23925
|
+
},
|
|
23926
|
+
encode(value) {
|
|
23927
|
+
return webTargetInputSchema.parse(value);
|
|
23928
|
+
}
|
|
23929
|
+
});
|
|
23930
|
+
|
|
23931
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/web/index.js
|
|
23932
|
+
var webExecutionTargetInputSchema = discriminatedUnion("schemaVersion", [webTargetInputSchema]);
|
|
23933
|
+
var webExecutionTargetOutputSchema = discriminatedUnion("schemaVersion", [webTargetOutputSchema]);
|
|
23934
|
+
var webExecutionTargetSchema2 = discriminatedUnion("schemaVersion", [
|
|
23935
|
+
webExecutionTargetSchema
|
|
23936
|
+
]);
|
|
23937
|
+
|
|
23938
|
+
// node_modules/@qawolf/flow-targets/dist/schemas/index.js
|
|
23939
|
+
var executionTargetInputSchema = discriminatedUnion("platform", [
|
|
23940
|
+
androidExecutionTargetInputSchema,
|
|
23941
|
+
iosExecutionTargetInputSchema,
|
|
23942
|
+
webExecutionTargetInputSchema
|
|
23943
|
+
]);
|
|
23944
|
+
var executionTargetOutputSchema = discriminatedUnion("platform", [
|
|
23945
|
+
androidExecutionTargetOutputSchema,
|
|
23946
|
+
iosExecutionTargetOutputSchema,
|
|
23947
|
+
webExecutionTargetOutputSchema
|
|
23948
|
+
]);
|
|
23949
|
+
var executionTargetSchema = discriminatedUnion("platform", [
|
|
23950
|
+
androidExecutionTargetSchema2,
|
|
23951
|
+
iosExecutionTargetSchema2,
|
|
23952
|
+
webExecutionTargetSchema2
|
|
23953
|
+
]);
|
|
23954
|
+
|
|
23955
|
+
// node_modules/@qawolf/flow-targets/dist/parseExecutionTarget.js
|
|
23956
|
+
var isPresetLiteral = (input) => presetLiteralsSchema.safeParse(input).success;
|
|
23957
|
+
var parseExecutionTarget = (input) => executionTargetSchema.decode(isPresetLiteral(input) ? presetTargetMap[input] : input);
|
|
23958
|
+
// node_modules/@qawolf/flow-targets/dist/index.js
|
|
23959
|
+
var presetLiteralOrAdHocTargetSchema = union([
|
|
23960
|
+
presetLiteralsSchema,
|
|
23961
|
+
executionTargetInputSchema
|
|
23962
|
+
]);
|
|
23963
|
+
|
|
22290
23964
|
// src/core/androidTargets.ts
|
|
22291
|
-
import { parseExecutionTarget } from "@qawolf/flow-targets";
|
|
22292
23965
|
function makeAvdName(deviceModel, androidVersion) {
|
|
22293
23966
|
return `qawolf_${deviceModel.toLowerCase().replace(/ /g, "_")}_api${androidVersion}`;
|
|
22294
23967
|
}
|
|
@@ -22333,11 +24006,11 @@ async function* batchMap(items, fn, size) {
|
|
|
22333
24006
|
}
|
|
22334
24007
|
|
|
22335
24008
|
// src/core/nodeModulesBins.ts
|
|
22336
|
-
import { join as
|
|
24009
|
+
import { join as join16 } from "node:path";
|
|
22337
24010
|
function nodeModulesBinCandidates(envDir, name, platform) {
|
|
22338
|
-
const binDir =
|
|
24011
|
+
const binDir = join16(envDir, "node_modules", ".bin");
|
|
22339
24012
|
const names = platform === "win32" ? [`${name}.cmd`, `${name}.exe`] : [name];
|
|
22340
|
-
return names.map((shim) =>
|
|
24013
|
+
return names.map((shim) => join16(binDir, shim));
|
|
22341
24014
|
}
|
|
22342
24015
|
function appiumCliCandidates(envDir, platform) {
|
|
22343
24016
|
return nodeModulesBinCandidates(envDir, "appium", platform);
|
|
@@ -22394,21 +24067,21 @@ async function checkUiautomator2(spawn, appiumBin, platform) {
|
|
|
22394
24067
|
}
|
|
22395
24068
|
|
|
22396
24069
|
// src/core/androidBins.ts
|
|
22397
|
-
import { join as
|
|
24070
|
+
import { join as join17 } from "node:path";
|
|
22398
24071
|
function withExeSuffix(name, platform) {
|
|
22399
24072
|
return platform === "win32" ? `${name}.exe` : name;
|
|
22400
24073
|
}
|
|
22401
24074
|
function emulatorBin(home, platform) {
|
|
22402
24075
|
const name = withExeSuffix("emulator", platform);
|
|
22403
|
-
return home ?
|
|
24076
|
+
return home ? join17(home, "emulator", name) : name;
|
|
22404
24077
|
}
|
|
22405
24078
|
function adbBin(home, platform) {
|
|
22406
24079
|
const name = withExeSuffix("adb", platform);
|
|
22407
|
-
return home ?
|
|
24080
|
+
return home ? join17(home, "platform-tools", name) : name;
|
|
22408
24081
|
}
|
|
22409
24082
|
function cmdlineToolsBin(home, name, platform) {
|
|
22410
24083
|
const file = platform === "win32" ? `${name}.bat` : name;
|
|
22411
|
-
return
|
|
24084
|
+
return join17(home, "cmdline-tools", "latest", "bin", file);
|
|
22412
24085
|
}
|
|
22413
24086
|
function sdkManagerBin(home, platform) {
|
|
22414
24087
|
return cmdlineToolsBin(home, "sdkmanager", platform);
|
|
@@ -22705,9 +24378,9 @@ async function checkNpmRegistry(deps) {
|
|
|
22705
24378
|
}
|
|
22706
24379
|
|
|
22707
24380
|
// src/core/playwrightCli.ts
|
|
22708
|
-
import { join as
|
|
24381
|
+
import { join as join18 } from "node:path";
|
|
22709
24382
|
function playwrightCliJsPath(envDir) {
|
|
22710
|
-
return
|
|
24383
|
+
return join18(envDir, "node_modules", "playwright", "cli.js");
|
|
22711
24384
|
}
|
|
22712
24385
|
function playwrightCliInvocation(args) {
|
|
22713
24386
|
return {
|
|
@@ -22721,7 +24394,7 @@ function playwrightCliInvocation(args) {
|
|
|
22721
24394
|
var flowsVersion = "0.1.4";
|
|
22722
24395
|
var playwrightVersion = "1.62.0";
|
|
22723
24396
|
var emailsVersion = "1.1.1";
|
|
22724
|
-
var testkitVersion = "1.
|
|
24397
|
+
var testkitVersion = "1.2.1";
|
|
22725
24398
|
var appiumVersion = "3.6.0";
|
|
22726
24399
|
var appiumUiautomator2DriverVersion = "8.4.0";
|
|
22727
24400
|
var expectWebdriverioVersion = "5.6.5";
|
|
@@ -22857,11 +24530,11 @@ function renderResults(ui, results) {
|
|
|
22857
24530
|
}
|
|
22858
24531
|
|
|
22859
24532
|
// src/domains/flows/ensureDeps.ts
|
|
22860
|
-
import { dirname as dirname4, join as
|
|
24533
|
+
import { dirname as dirname4, join as join19 } from "node:path";
|
|
22861
24534
|
function findEnvDir(flowPath, fs) {
|
|
22862
24535
|
let dir = dirname4(flowPath);
|
|
22863
24536
|
while (true) {
|
|
22864
|
-
if (fs.existsSync(
|
|
24537
|
+
if (fs.existsSync(join19(dir, "package.json")))
|
|
22865
24538
|
return dir;
|
|
22866
24539
|
const parent = dirname4(dir);
|
|
22867
24540
|
if (parent === dir)
|
|
@@ -22887,7 +24560,7 @@ function resolveProjectDirSafe(files, fs) {
|
|
|
22887
24560
|
}
|
|
22888
24561
|
|
|
22889
24562
|
// src/domains/flows/expand.ts
|
|
22890
|
-
import { join as
|
|
24563
|
+
import { join as join20, resolve as resolve3 } from "node:path";
|
|
22891
24564
|
|
|
22892
24565
|
// node_modules/tinyglobby/dist/index.mjs
|
|
22893
24566
|
import { readdir, readdirSync, realpath, realpathSync, stat, statSync } from "fs";
|
|
@@ -23716,7 +25389,6 @@ async function glob(globInput, options) {
|
|
|
23716
25389
|
}
|
|
23717
25390
|
|
|
23718
25391
|
// src/core/flowMeta.ts
|
|
23719
|
-
import { getWebBrowserInfo, parseExecutionTarget as parseExecutionTarget2 } from "@qawolf/flow-targets";
|
|
23720
25392
|
import { basename as basename2 } from "node:path";
|
|
23721
25393
|
|
|
23722
25394
|
// src/core/stringLiteral.ts
|
|
@@ -23832,7 +25504,7 @@ var browserNameToPlaywright = {
|
|
|
23832
25504
|
function classifyTarget(target) {
|
|
23833
25505
|
let parsed;
|
|
23834
25506
|
try {
|
|
23835
|
-
parsed =
|
|
25507
|
+
parsed = parseExecutionTarget(target);
|
|
23836
25508
|
} catch {
|
|
23837
25509
|
return { kind: "unrecognized" };
|
|
23838
25510
|
}
|
|
@@ -23876,11 +25548,11 @@ function makePeekFlowMeta(fs) {
|
|
|
23876
25548
|
};
|
|
23877
25549
|
}
|
|
23878
25550
|
async function resolveGlobRoots(cwd, fs) {
|
|
23879
|
-
const qawolfPath =
|
|
25551
|
+
const qawolfPath = join20(cwd, ".qawolf");
|
|
23880
25552
|
let envDirs = [];
|
|
23881
25553
|
try {
|
|
23882
25554
|
const entries = await fs.readdirWithTypes(qawolfPath);
|
|
23883
|
-
envDirs = entries.filter((e) => e.isDirectory()).map((e) =>
|
|
25555
|
+
envDirs = entries.filter((e) => e.isDirectory()).map((e) => join20(qawolfPath, e.name));
|
|
23884
25556
|
} catch {}
|
|
23885
25557
|
return [cwd, ...envDirs];
|
|
23886
25558
|
}
|
|
@@ -23906,11 +25578,11 @@ async function expandPatterns(patterns, cwd, logger, fs) {
|
|
|
23906
25578
|
}
|
|
23907
25579
|
|
|
23908
25580
|
// src/domains/runtimeEnv/clearRuntimeEnv.ts
|
|
23909
|
-
import { join as
|
|
25581
|
+
import { join as join22 } from "node:path";
|
|
23910
25582
|
|
|
23911
25583
|
// src/domains/runtimeEnv/managedEnvDir.ts
|
|
23912
25584
|
import { createHash } from "node:crypto";
|
|
23913
|
-
import { join as
|
|
25585
|
+
import { join as join21, resolve as resolve4 } from "node:path";
|
|
23914
25586
|
|
|
23915
25587
|
// src/domains/runtimeEnv/pinnedPackages.ts
|
|
23916
25588
|
var pinnedPackages = [
|
|
@@ -23941,19 +25613,19 @@ function managedEnvBaseDir() {
|
|
|
23941
25613
|
const override = process.env["QAWOLF_RUNTIME_DIR"]?.trim();
|
|
23942
25614
|
if (override)
|
|
23943
25615
|
return resolve4(override);
|
|
23944
|
-
return
|
|
25616
|
+
return join21(getDataDir(), "runtime");
|
|
23945
25617
|
}
|
|
23946
25618
|
function runStagingRoot() {
|
|
23947
25619
|
return `${managedEnvBaseDir()}-runs`;
|
|
23948
25620
|
}
|
|
23949
25621
|
function managedEnvDir() {
|
|
23950
|
-
return
|
|
25622
|
+
return join21(managedEnvBaseDir(), managedEnvHash());
|
|
23951
25623
|
}
|
|
23952
25624
|
async function scaffoldManagedEnv(dir, fs) {
|
|
23953
25625
|
await fs.mkdir(dir, { recursive: true });
|
|
23954
25626
|
const dependencies = Object.fromEntries(pinnedPackages.map(({ name, version }) => [name, version]));
|
|
23955
|
-
await fs.writeFile(
|
|
23956
|
-
await fs.writeFile(
|
|
25627
|
+
await fs.writeFile(join21(dir, "package.json"), JSON.stringify({ name: "qawolf-runtime", private: true, dependencies }, undefined, 2));
|
|
25628
|
+
await fs.writeFile(join21(dir, ".npmrc"), `@qawolf:registry=https://registry.npmjs.org/
|
|
23957
25629
|
`);
|
|
23958
25630
|
}
|
|
23959
25631
|
|
|
@@ -23975,14 +25647,14 @@ async function isManagedRuntimeBase(dir, fs) {
|
|
|
23975
25647
|
for (const entry of entries) {
|
|
23976
25648
|
if (!entry.isDirectory())
|
|
23977
25649
|
return false;
|
|
23978
|
-
if (!await hasRuntimeSentinel(
|
|
25650
|
+
if (!await hasRuntimeSentinel(join22(dir, entry.name), fs))
|
|
23979
25651
|
return false;
|
|
23980
25652
|
}
|
|
23981
25653
|
return true;
|
|
23982
25654
|
}
|
|
23983
25655
|
async function hasRuntimeSentinel(hashDir, fs) {
|
|
23984
25656
|
try {
|
|
23985
|
-
const pkg = JSON.parse(await fs.readFile(
|
|
25657
|
+
const pkg = JSON.parse(await fs.readFile(join22(hashDir, "package.json")));
|
|
23986
25658
|
return pkg.name === runtimeSentinel;
|
|
23987
25659
|
} catch {
|
|
23988
25660
|
return false;
|
|
@@ -24008,10 +25680,10 @@ function spawnNpmInstall(cwd, spawn2 = spawn) {
|
|
|
24008
25680
|
}
|
|
24009
25681
|
|
|
24010
25682
|
// src/domains/runtimeEnv/resolvePinned.ts
|
|
24011
|
-
import { join as
|
|
25683
|
+
import { join as join23 } from "node:path";
|
|
24012
25684
|
function readInstalledVersion(dir, pkgName, fs) {
|
|
24013
25685
|
try {
|
|
24014
|
-
const pkgPath =
|
|
25686
|
+
const pkgPath = join23(dir, "node_modules", ...pkgName.split("/"), "package.json");
|
|
24015
25687
|
const raw = JSON.parse(fs.readFileSync(pkgPath));
|
|
24016
25688
|
const { version } = raw;
|
|
24017
25689
|
return typeof version === "string" ? version : undefined;
|
|
@@ -24059,10 +25731,10 @@ function allPinnedResolved(dir, fs, platform) {
|
|
|
24059
25731
|
}
|
|
24060
25732
|
|
|
24061
25733
|
// src/domains/runtimeEnv/shimDeps.ts
|
|
24062
|
-
import { join as
|
|
25734
|
+
import { join as join25 } from "node:path";
|
|
24063
25735
|
|
|
24064
25736
|
// src/shell/resolveExport.ts
|
|
24065
|
-
import { join as
|
|
25737
|
+
import { join as join24 } from "node:path";
|
|
24066
25738
|
function pickPath(entry, preference) {
|
|
24067
25739
|
if (typeof entry === "string")
|
|
24068
25740
|
return entry;
|
|
@@ -24094,28 +25766,28 @@ function resolveFromEnvDir(envDir, specifier, preference = "esm", fs = makeDefau
|
|
|
24094
25766
|
const pkgName = parts.slice(0, pkgPartCount).join("/");
|
|
24095
25767
|
const rest = parts.slice(pkgPartCount);
|
|
24096
25768
|
const subpath = rest.length > 0 ? "./" + rest.join("/") : ".";
|
|
24097
|
-
const pkgDir =
|
|
25769
|
+
const pkgDir = join24(envDir, "node_modules", ...pkgName.split("/"));
|
|
24098
25770
|
let pkg;
|
|
24099
25771
|
try {
|
|
24100
|
-
pkg = JSON.parse(fs.readFileSync(
|
|
25772
|
+
pkg = JSON.parse(fs.readFileSync(join24(pkgDir, "package.json")));
|
|
24101
25773
|
} catch (err) {
|
|
24102
25774
|
if (isNoEntError(err))
|
|
24103
|
-
throw new Error(`Package '${pkgName}' not found in ${
|
|
25775
|
+
throw new Error(`Package '${pkgName}' not found in ${join24(envDir, "node_modules")}`, { cause: err });
|
|
24104
25776
|
throw err;
|
|
24105
25777
|
}
|
|
24106
25778
|
const exportsMap = normalizeExports(pkg.exports);
|
|
24107
25779
|
const entry = exportsMap?.[subpath];
|
|
24108
25780
|
const relative = pickPath(entry, preference) ?? (subpath === "." ? pkg.module ?? pkg.main : undefined);
|
|
24109
25781
|
if (!relative) {
|
|
24110
|
-
throw new Error(`No entry for "${subpath}" in exports of ${
|
|
25782
|
+
throw new Error(`No entry for "${subpath}" in exports of ${join24(pkgDir, "package.json")}`);
|
|
24111
25783
|
}
|
|
24112
|
-
return
|
|
25784
|
+
return join24(pkgDir, relative);
|
|
24113
25785
|
}
|
|
24114
25786
|
|
|
24115
25787
|
// src/domains/runtimeEnv/shimDeps.ts
|
|
24116
25788
|
function readShimMarker(shimDir, fs) {
|
|
24117
25789
|
try {
|
|
24118
|
-
const pkg = JSON.parse(fs.readFileSync(
|
|
25790
|
+
const pkg = JSON.parse(fs.readFileSync(join25(shimDir, "package.json")));
|
|
24119
25791
|
if (pkg._qawolf_format) {
|
|
24120
25792
|
return {
|
|
24121
25793
|
_qawolf_version: pkg._qawolf_version ?? "",
|
|
@@ -24131,11 +25803,11 @@ function resolveBunBuild(bunBuild) {
|
|
|
24131
25803
|
return bunBuild === false ? undefined : { build: bunBuild };
|
|
24132
25804
|
}
|
|
24133
25805
|
async function removeStaleShims(flowsDir, flowsDeps, fs) {
|
|
24134
|
-
const shimsDir =
|
|
25806
|
+
const shimsDir = join25(flowsDir, "node_modules");
|
|
24135
25807
|
if (!fs.existsSync(shimsDir))
|
|
24136
25808
|
return;
|
|
24137
25809
|
for (const dep of flowsDeps) {
|
|
24138
|
-
const shimDepDir =
|
|
25810
|
+
const shimDepDir = join25(shimsDir, ...dep.split("/"));
|
|
24139
25811
|
if (readShimMarker(shimDepDir, fs)) {
|
|
24140
25812
|
await fs.rm(shimDepDir, { recursive: true, force: true });
|
|
24141
25813
|
}
|
|
@@ -24144,17 +25816,17 @@ async function removeStaleShims(flowsDir, flowsDeps, fs) {
|
|
|
24144
25816
|
async function buildDepShim(args) {
|
|
24145
25817
|
const { envDir, flowsDir, dep, fs, build } = args;
|
|
24146
25818
|
const depParts = dep.split("/");
|
|
24147
|
-
const depDir =
|
|
25819
|
+
const depDir = join25(envDir, "node_modules", ...depParts);
|
|
24148
25820
|
if (!fs.existsSync(depDir))
|
|
24149
25821
|
return;
|
|
24150
25822
|
let depVersion;
|
|
24151
25823
|
try {
|
|
24152
|
-
const pkg = JSON.parse(fs.readFileSync(
|
|
25824
|
+
const pkg = JSON.parse(fs.readFileSync(join25(depDir, "package.json")));
|
|
24153
25825
|
depVersion = pkg.version ?? "unknown";
|
|
24154
25826
|
} catch {
|
|
24155
25827
|
depVersion = "unknown";
|
|
24156
25828
|
}
|
|
24157
|
-
const shimDir =
|
|
25829
|
+
const shimDir = join25(flowsDir, "node_modules", ...depParts);
|
|
24158
25830
|
if (fs.existsSync(shimDir)) {
|
|
24159
25831
|
const marker = readShimMarker(shimDir, fs);
|
|
24160
25832
|
if (!marker)
|
|
@@ -24181,20 +25853,20 @@ async function buildDepShim(args) {
|
|
|
24181
25853
|
}
|
|
24182
25854
|
const shimCode = await output.text();
|
|
24183
25855
|
await fs.mkdir(shimDir, { recursive: true });
|
|
24184
|
-
await fs.writeFile(
|
|
25856
|
+
await fs.writeFile(join25(shimDir, "package.json"), JSON.stringify({
|
|
24185
25857
|
name: dep,
|
|
24186
25858
|
_qawolf_version: depVersion,
|
|
24187
25859
|
_qawolf_format: "bun-build-v1"
|
|
24188
25860
|
}));
|
|
24189
|
-
await fs.writeFile(
|
|
25861
|
+
await fs.writeFile(join25(shimDir, "index.js"), shimCode);
|
|
24190
25862
|
}
|
|
24191
25863
|
async function shimFlowsDeps(envDir, fs = makeDefaultFs(), bunBuild) {
|
|
24192
|
-
const flowsDir =
|
|
25864
|
+
const flowsDir = join25(envDir, "node_modules", "@qawolf", "flows");
|
|
24193
25865
|
if (!fs.existsSync(flowsDir))
|
|
24194
25866
|
return;
|
|
24195
25867
|
let flowsDeps;
|
|
24196
25868
|
try {
|
|
24197
|
-
const flowsPkg = JSON.parse(fs.readFileSync(
|
|
25869
|
+
const flowsPkg = JSON.parse(fs.readFileSync(join25(flowsDir, "package.json")));
|
|
24198
25870
|
flowsDeps = Object.keys(flowsPkg.dependencies ?? {});
|
|
24199
25871
|
} catch {
|
|
24200
25872
|
return;
|
|
@@ -24375,11 +26047,11 @@ function collectValue(value, previous) {
|
|
|
24375
26047
|
}
|
|
24376
26048
|
|
|
24377
26049
|
// src/shell/manifest/pulledEnv.ts
|
|
24378
|
-
import { join as
|
|
26050
|
+
import { join as join27 } from "node:path";
|
|
24379
26051
|
|
|
24380
26052
|
// src/shell/manifest/io.ts
|
|
24381
26053
|
import { createHash as createHash2 } from "node:crypto";
|
|
24382
|
-
import { join as
|
|
26054
|
+
import { join as join26 } from "node:path";
|
|
24383
26055
|
var manifestFilename = ".manifest.json";
|
|
24384
26056
|
var flowEntrySchema = object({
|
|
24385
26057
|
path: string2(),
|
|
@@ -24401,7 +26073,7 @@ var manifestSchema = object({
|
|
|
24401
26073
|
async function readManifest(envDir, fs = makeDefaultFs()) {
|
|
24402
26074
|
let raw;
|
|
24403
26075
|
try {
|
|
24404
|
-
raw = await fs.readFile(
|
|
26076
|
+
raw = await fs.readFile(join26(envDir, manifestFilename));
|
|
24405
26077
|
} catch (err) {
|
|
24406
26078
|
if (isNoEntError(err))
|
|
24407
26079
|
return "missing";
|
|
@@ -24435,7 +26107,7 @@ async function readManifest(envDir, fs = makeDefaultFs()) {
|
|
|
24435
26107
|
}
|
|
24436
26108
|
async function writeManifest(envDir, manifest, fs = makeDefaultFs()) {
|
|
24437
26109
|
const body = JSON.stringify(manifest, undefined, 2);
|
|
24438
|
-
await fs.writeFile(
|
|
26110
|
+
await fs.writeFile(join26(envDir, manifestFilename), `${body}
|
|
24439
26111
|
`);
|
|
24440
26112
|
}
|
|
24441
26113
|
function hashFile(absPath, fs = makeDefaultFs()) {
|
|
@@ -24461,7 +26133,7 @@ async function findPulledEnv(ref, cwd, fs = makeDefaultFs()) {
|
|
|
24461
26133
|
return;
|
|
24462
26134
|
}
|
|
24463
26135
|
async function listPulledEnvDirs(cwd, fs = makeDefaultFs()) {
|
|
24464
|
-
const root =
|
|
26136
|
+
const root = join27(cwd, ".qawolf");
|
|
24465
26137
|
let entries;
|
|
24466
26138
|
try {
|
|
24467
26139
|
entries = await fs.readdirWithTypes(root);
|
|
@@ -24474,7 +26146,7 @@ async function listPulledEnvDirs(cwd, fs = makeDefaultFs()) {
|
|
|
24474
26146
|
for (const entry of entries) {
|
|
24475
26147
|
if (!entry.isDirectory())
|
|
24476
26148
|
continue;
|
|
24477
|
-
const envDir =
|
|
26149
|
+
const envDir = join27(root, entry.name);
|
|
24478
26150
|
const manifest = await readManifest(envDir, fs);
|
|
24479
26151
|
if (typeof manifest === "string")
|
|
24480
26152
|
continue;
|
|
@@ -24866,7 +26538,7 @@ async function flowsListRemote(ctx, pattern, options) {
|
|
|
24866
26538
|
}
|
|
24867
26539
|
|
|
24868
26540
|
// src/domains/flows/pull/handler.ts
|
|
24869
|
-
import { dirname as dirname8, join as
|
|
26541
|
+
import { dirname as dirname8, join as join32, resolve as resolve8 } from "node:path";
|
|
24870
26542
|
|
|
24871
26543
|
// src/domains/flows/pull/fetchPhase.ts
|
|
24872
26544
|
async function fetchTags(ctx, envId) {
|
|
@@ -24888,6 +26560,7 @@ async function fetchBundleAndEnvVars(ctx, envId) {
|
|
|
24888
26560
|
let bundleFetchedAt;
|
|
24889
26561
|
let envVars;
|
|
24890
26562
|
let envVarsFetchedAt;
|
|
26563
|
+
let teamId;
|
|
24891
26564
|
let tags;
|
|
24892
26565
|
await ctx.ui.withProgress([
|
|
24893
26566
|
{
|
|
@@ -24903,10 +26576,11 @@ async function fetchBundleAndEnvVars(ctx, envId) {
|
|
|
24903
26576
|
{
|
|
24904
26577
|
message: flowsMessages.pull.fetchingEnvVars,
|
|
24905
26578
|
task: async () => {
|
|
24906
|
-
const result = await platformClient.
|
|
26579
|
+
const result = await platformClient.getEnvironmentWithVariables(envId);
|
|
24907
26580
|
if (!result.ok)
|
|
24908
26581
|
throw new Error(result.error);
|
|
24909
|
-
envVars = result.value;
|
|
26582
|
+
envVars = result.value.environmentVariables;
|
|
26583
|
+
teamId = result.value.teamId;
|
|
24910
26584
|
envVarsFetchedAt = new Date;
|
|
24911
26585
|
}
|
|
24912
26586
|
},
|
|
@@ -24917,10 +26591,17 @@ async function fetchBundleAndEnvVars(ctx, envId) {
|
|
|
24917
26591
|
}
|
|
24918
26592
|
}
|
|
24919
26593
|
], flowsMessages.pull.downloadComplete);
|
|
24920
|
-
if (tmpArchive === undefined || bundleFetchedAt === undefined || envVars === undefined || envVarsFetchedAt === undefined) {
|
|
26594
|
+
if (tmpArchive === undefined || bundleFetchedAt === undefined || envVars === undefined || envVarsFetchedAt === undefined || teamId === undefined) {
|
|
24921
26595
|
throw new Error("Unexpected state: the bundle and env vars were not fetched. " + "This is a bug - please report it at https://github.com/qawolf/cli/issues");
|
|
24922
26596
|
}
|
|
24923
|
-
return {
|
|
26597
|
+
return {
|
|
26598
|
+
tmpArchive,
|
|
26599
|
+
bundleFetchedAt,
|
|
26600
|
+
envVars,
|
|
26601
|
+
envVarsFetchedAt,
|
|
26602
|
+
teamId,
|
|
26603
|
+
tags
|
|
26604
|
+
};
|
|
24924
26605
|
}
|
|
24925
26606
|
|
|
24926
26607
|
// src/domains/flows/pull/safety.ts
|
|
@@ -25010,7 +26691,7 @@ async function checkSafety(args) {
|
|
|
25010
26691
|
}
|
|
25011
26692
|
|
|
25012
26693
|
// src/domains/flows/pull/reportPull.ts
|
|
25013
|
-
import { join as
|
|
26694
|
+
import { join as join28 } from "node:path";
|
|
25014
26695
|
function reportPullResult(ui, args) {
|
|
25015
26696
|
if (ui.mode !== "json")
|
|
25016
26697
|
return;
|
|
@@ -25025,12 +26706,12 @@ function reportPullResult(ui, args) {
|
|
|
25025
26706
|
assetDownloadedCount: args.assets.downloadedCount,
|
|
25026
26707
|
assetReusedCount: args.assets.reusedCount,
|
|
25027
26708
|
assetSkippedCount: args.assets.skippedCount,
|
|
25028
|
-
manifestPath:
|
|
26709
|
+
manifestPath: join28(args.stage.envDir, manifestFilename)
|
|
25029
26710
|
}, "");
|
|
25030
26711
|
}
|
|
25031
26712
|
|
|
25032
26713
|
// src/domains/flows/pull/bundle.ts
|
|
25033
|
-
import { join as
|
|
26714
|
+
import { join as join29, relative as relative6 } from "node:path";
|
|
25034
26715
|
async function flattenSingleWrapper(dir, fs = makeDefaultFs()) {
|
|
25035
26716
|
const entries = await fs.readdir(dir);
|
|
25036
26717
|
if (entries.length !== 1)
|
|
@@ -25038,12 +26719,12 @@ async function flattenSingleWrapper(dir, fs = makeDefaultFs()) {
|
|
|
25038
26719
|
const innerName = entries[0];
|
|
25039
26720
|
if (!innerName)
|
|
25040
26721
|
return;
|
|
25041
|
-
const inner =
|
|
26722
|
+
const inner = join29(dir, innerName);
|
|
25042
26723
|
const innerStat = await fs.stat(inner);
|
|
25043
26724
|
if (!innerStat.isDirectory())
|
|
25044
26725
|
return;
|
|
25045
26726
|
for (const e of await fs.readdir(inner)) {
|
|
25046
|
-
await fs.rename(
|
|
26727
|
+
await fs.rename(join29(inner, e), join29(dir, e));
|
|
25047
26728
|
}
|
|
25048
26729
|
const leftovers = await fs.readdir(inner);
|
|
25049
26730
|
if (leftovers.length > 0) {
|
|
@@ -25062,7 +26743,7 @@ async function buildManifest(args, fs = makeDefaultFs()) {
|
|
|
25062
26743
|
const flowPaths = await walkForFlows(args.bundleDir, fs);
|
|
25063
26744
|
const flows = await Promise.all(flowPaths.map(async (rel) => ({
|
|
25064
26745
|
path: toPosix(rel),
|
|
25065
|
-
contentHash: await hashFile(
|
|
26746
|
+
contentHash: await hashFile(join29(args.bundleDir, rel), fs),
|
|
25066
26747
|
tags: args.tags?.byPath.get(toPosix(rel))
|
|
25067
26748
|
})));
|
|
25068
26749
|
return {
|
|
@@ -25086,7 +26767,7 @@ async function walkForFlows(root, fs) {
|
|
|
25086
26767
|
async function walk(current, root, out, fs) {
|
|
25087
26768
|
const entries = await fs.readdirWithTypes(current);
|
|
25088
26769
|
for (const e of entries) {
|
|
25089
|
-
const abs =
|
|
26770
|
+
const abs = join29(current, e.name);
|
|
25090
26771
|
if (e.isDirectory()) {
|
|
25091
26772
|
await walk(abs, root, out, fs);
|
|
25092
26773
|
} else if (e.isFile() && flowExtensions.some((ext) => e.name.endsWith(ext))) {
|
|
@@ -25099,11 +26780,11 @@ async function sampleQawolfCommittedAt(bundleDir, fs = makeDefaultFs()) {
|
|
|
25099
26780
|
const sample = flowPaths[0];
|
|
25100
26781
|
if (!sample)
|
|
25101
26782
|
return;
|
|
25102
|
-
return (await fs.stat(
|
|
26783
|
+
return (await fs.stat(join29(bundleDir, sample))).mtime.toISOString();
|
|
25103
26784
|
}
|
|
25104
26785
|
|
|
25105
26786
|
// src/domains/flows/pull/applyTeamStorageRewrite.ts
|
|
25106
|
-
import { join as
|
|
26787
|
+
import { join as join30, relative as relative7 } from "node:path";
|
|
25107
26788
|
|
|
25108
26789
|
// src/domains/flows/pull/rewriteTeamStorage.ts
|
|
25109
26790
|
var runnerMountPrefix = "/home/wolf/team-storage/";
|
|
@@ -25139,7 +26820,7 @@ function isFlowFile(name) {
|
|
|
25139
26820
|
async function walk2(dir, out, fs) {
|
|
25140
26821
|
const entries = await fs.readdirWithTypes(dir);
|
|
25141
26822
|
for (const e of entries) {
|
|
25142
|
-
const abs =
|
|
26823
|
+
const abs = join30(dir, e.name);
|
|
25143
26824
|
if (e.isDirectory()) {
|
|
25144
26825
|
await walk2(abs, out, fs);
|
|
25145
26826
|
} else if (e.isFile() && isSourceFile(e.name)) {
|
|
@@ -25167,7 +26848,7 @@ async function applyTeamStorageRewrite(rootDir, fs = makeDefaultFs()) {
|
|
|
25167
26848
|
}
|
|
25168
26849
|
|
|
25169
26850
|
// src/domains/flows/pull/envVars.ts
|
|
25170
|
-
import { join as
|
|
26851
|
+
import { join as join31 } from "node:path";
|
|
25171
26852
|
|
|
25172
26853
|
// src/core/dotenv.ts
|
|
25173
26854
|
var bareKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -25232,7 +26913,7 @@ function unquote(escaped) {
|
|
|
25232
26913
|
async function writeEnvFile(envDir, vars, fs = makeDefaultFs()) {
|
|
25233
26914
|
if (Object.keys(vars).length === 0)
|
|
25234
26915
|
return;
|
|
25235
|
-
await fs.writeFile(
|
|
26916
|
+
await fs.writeFile(join31(envDir, ".env"), serializeDotenv(vars), {
|
|
25236
26917
|
mode: 384
|
|
25237
26918
|
});
|
|
25238
26919
|
}
|
|
@@ -25647,7 +27328,7 @@ var Jr = I.writev;
|
|
|
25647
27328
|
var ht = Symbol("_autoClose");
|
|
25648
27329
|
var H = Symbol("_close");
|
|
25649
27330
|
var te = Symbol("_ended");
|
|
25650
|
-
var
|
|
27331
|
+
var m4 = Symbol("_fd");
|
|
25651
27332
|
var Ni = Symbol("_finished");
|
|
25652
27333
|
var tt = Symbol("_flags");
|
|
25653
27334
|
var Ai = Symbol("_flush");
|
|
@@ -25674,7 +27355,7 @@ var Me = Symbol("_defaultFlag");
|
|
|
25674
27355
|
var bt = Symbol("_errored");
|
|
25675
27356
|
var _t = class extends A2 {
|
|
25676
27357
|
[bt] = false;
|
|
25677
|
-
[
|
|
27358
|
+
[m4];
|
|
25678
27359
|
[U2];
|
|
25679
27360
|
[Ci];
|
|
25680
27361
|
[j] = false;
|
|
@@ -25684,10 +27365,10 @@ var _t = class extends A2 {
|
|
|
25684
27365
|
constructor(t, e) {
|
|
25685
27366
|
if (e = e || {}, super(e), this.readable = true, this.writable = false, typeof t != "string")
|
|
25686
27367
|
throw new TypeError("path must be a string");
|
|
25687
|
-
this[bt] = false, this[
|
|
27368
|
+
this[bt] = false, this[m4] = typeof e.fd == "number" ? e.fd : undefined, this[U2] = t, this[Ci] = e.readSize || 16 * 1024 * 1024, this[j] = false, this[Fi] = typeof e.size == "number" ? e.size : 1 / 0, this[ee] = this[Fi], this[ht] = typeof e.autoClose == "boolean" ? e.autoClose : true, typeof this[m4] == "number" ? this[zt]() : this[at]();
|
|
25688
27369
|
}
|
|
25689
27370
|
get fd() {
|
|
25690
|
-
return this[
|
|
27371
|
+
return this[m4];
|
|
25691
27372
|
}
|
|
25692
27373
|
get path() {
|
|
25693
27374
|
return this[U2];
|
|
@@ -25702,7 +27383,7 @@ var _t = class extends A2 {
|
|
|
25702
27383
|
I.open(this[U2], "r", (t, e) => this[Ht](t, e));
|
|
25703
27384
|
}
|
|
25704
27385
|
[Ht](t, e) {
|
|
25705
|
-
t ? this[Ut](t) : (this[
|
|
27386
|
+
t ? this[Ut](t) : (this[m4] = e, this.emit("open", e), this[zt]());
|
|
25706
27387
|
}
|
|
25707
27388
|
[vi]() {
|
|
25708
27389
|
return Buffer.allocUnsafe(Math.min(this[Ci], this[ee]));
|
|
@@ -25713,16 +27394,16 @@ var _t = class extends A2 {
|
|
|
25713
27394
|
let t = this[vi]();
|
|
25714
27395
|
if (t.length === 0)
|
|
25715
27396
|
return process.nextTick(() => this[Ii](null, 0, t));
|
|
25716
|
-
I.read(this[
|
|
27397
|
+
I.read(this[m4], t, 0, t.length, null, (e, i, r) => this[Ii](e, i, r));
|
|
25717
27398
|
}
|
|
25718
27399
|
}
|
|
25719
27400
|
[Ii](t, e, i) {
|
|
25720
27401
|
this[j] = false, t ? this[Ut](t) : this[ki](e, i) && this[zt]();
|
|
25721
27402
|
}
|
|
25722
27403
|
[H]() {
|
|
25723
|
-
if (this[ht] && typeof this[
|
|
25724
|
-
let t = this[
|
|
25725
|
-
this[
|
|
27404
|
+
if (this[ht] && typeof this[m4] == "number") {
|
|
27405
|
+
let t = this[m4];
|
|
27406
|
+
this[m4] = undefined, I.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
|
|
25726
27407
|
}
|
|
25727
27408
|
}
|
|
25728
27409
|
[Ut](t) {
|
|
@@ -25738,7 +27419,7 @@ var _t = class extends A2 {
|
|
|
25738
27419
|
case "finish":
|
|
25739
27420
|
return false;
|
|
25740
27421
|
case "drain":
|
|
25741
|
-
return typeof this[
|
|
27422
|
+
return typeof this[m4] == "number" && this[zt](), false;
|
|
25742
27423
|
case "error":
|
|
25743
27424
|
return this[bt] ? false : (this[bt] = true, super.emit(t, ...e));
|
|
25744
27425
|
default:
|
|
@@ -25761,7 +27442,7 @@ var Be = class extends _t {
|
|
|
25761
27442
|
if (!this[j]) {
|
|
25762
27443
|
this[j] = true;
|
|
25763
27444
|
do {
|
|
25764
|
-
let e = this[vi](), i = e.length === 0 ? 0 : I.readSync(this[
|
|
27445
|
+
let e = this[vi](), i = e.length === 0 ? 0 : I.readSync(this[m4], e, 0, e.length, null);
|
|
25765
27446
|
if (!this[ki](i, e))
|
|
25766
27447
|
break;
|
|
25767
27448
|
} while (true);
|
|
@@ -25773,9 +27454,9 @@ var Be = class extends _t {
|
|
|
25773
27454
|
}
|
|
25774
27455
|
}
|
|
25775
27456
|
[H]() {
|
|
25776
|
-
if (this[ht] && typeof this[
|
|
25777
|
-
let t = this[
|
|
25778
|
-
this[
|
|
27457
|
+
if (this[ht] && typeof this[m4] == "number") {
|
|
27458
|
+
let t = this[m4];
|
|
27459
|
+
this[m4] = undefined, I.closeSync(t), this.emit("close");
|
|
25779
27460
|
}
|
|
25780
27461
|
}
|
|
25781
27462
|
};
|
|
@@ -25790,15 +27471,15 @@ var et = class extends Qr {
|
|
|
25790
27471
|
[U2];
|
|
25791
27472
|
[ie];
|
|
25792
27473
|
[ht];
|
|
25793
|
-
[
|
|
27474
|
+
[m4];
|
|
25794
27475
|
[Me];
|
|
25795
27476
|
[tt];
|
|
25796
27477
|
[Ni] = false;
|
|
25797
27478
|
[ot];
|
|
25798
27479
|
constructor(t, e) {
|
|
25799
|
-
e = e || {}, super(e), this[U2] = t, this[
|
|
27480
|
+
e = e || {}, super(e), this[U2] = t, this[m4] = typeof e.fd == "number" ? e.fd : undefined, this[ie] = e.mode === undefined ? 438 : e.mode, this[ot] = typeof e.start == "number" ? e.start : undefined, this[ht] = typeof e.autoClose == "boolean" ? e.autoClose : true;
|
|
25800
27481
|
let i = this[ot] !== undefined ? "r+" : "w";
|
|
25801
|
-
this[Me] = e.flags === undefined, this[tt] = e.flags === undefined ? i : e.flags, this[
|
|
27482
|
+
this[Me] = e.flags === undefined, this[tt] = e.flags === undefined ? i : e.flags, this[m4] === undefined && this[at]();
|
|
25802
27483
|
}
|
|
25803
27484
|
emit(t, ...e) {
|
|
25804
27485
|
if (t === "error") {
|
|
@@ -25809,7 +27490,7 @@ var et = class extends Qr {
|
|
|
25809
27490
|
return super.emit(t, ...e);
|
|
25810
27491
|
}
|
|
25811
27492
|
get fd() {
|
|
25812
|
-
return this[
|
|
27493
|
+
return this[m4];
|
|
25813
27494
|
}
|
|
25814
27495
|
get path() {
|
|
25815
27496
|
return this[U2];
|
|
@@ -25821,16 +27502,16 @@ var et = class extends Qr {
|
|
|
25821
27502
|
I.open(this[U2], this[tt], this[ie], (t, e) => this[Ht](t, e));
|
|
25822
27503
|
}
|
|
25823
27504
|
[Ht](t, e) {
|
|
25824
|
-
this[Me] && this[tt] === "r+" && t && t.code === "ENOENT" ? (this[tt] = "w", this[at]()) : t ? this[Ut](t) : (this[
|
|
27505
|
+
this[Me] && this[tt] === "r+" && t && t.code === "ENOENT" ? (this[tt] = "w", this[at]()) : t ? this[Ut](t) : (this[m4] = e, this.emit("open", e), this[gt] || this[Ai]());
|
|
25825
27506
|
}
|
|
25826
27507
|
end(t, e) {
|
|
25827
|
-
return t && this.write(t, e), this[te] = true, !this[gt] && !this[Y].length && typeof this[
|
|
27508
|
+
return t && this.write(t, e), this[te] = true, !this[gt] && !this[Y].length && typeof this[m4] == "number" && this[Pt](null, 0), this;
|
|
25828
27509
|
}
|
|
25829
27510
|
write(t, e) {
|
|
25830
|
-
return typeof t == "string" && (t = Buffer.from(t, e)), this[te] ? (this.emit("error", new Error("write() after end()")), false) : this[
|
|
27511
|
+
return typeof t == "string" && (t = Buffer.from(t, e)), this[te] ? (this.emit("error", new Error("write() after end()")), false) : this[m4] === undefined || this[gt] || this[Y].length ? (this[Y].push(t), this[ke] = true, false) : (this[gt] = true, this[ve](t), true);
|
|
25831
27512
|
}
|
|
25832
27513
|
[ve](t) {
|
|
25833
|
-
I.write(this[
|
|
27514
|
+
I.write(this[m4], t, 0, t.length, this[ot], (e, i) => this[Pt](e, i));
|
|
25834
27515
|
}
|
|
25835
27516
|
[Pt](t, e) {
|
|
25836
27517
|
t ? this[Ut](t) : (this[ot] !== undefined && typeof e == "number" && (this[ot] += e), this[Y].length ? this[Ai]() : (this[gt] = false, this[te] && !this[Ni] ? (this[Ni] = true, this[H](), this.emit("finish")) : this[ke] && (this[ke] = false, this.emit("drain"))));
|
|
@@ -25842,13 +27523,13 @@ var et = class extends Qr {
|
|
|
25842
27523
|
this[ve](this[Y].pop());
|
|
25843
27524
|
else {
|
|
25844
27525
|
let t = this[Y];
|
|
25845
|
-
this[Y] = [], Jr(this[
|
|
27526
|
+
this[Y] = [], Jr(this[m4], t, this[ot], (e, i) => this[Pt](e, i));
|
|
25846
27527
|
}
|
|
25847
27528
|
}
|
|
25848
27529
|
[H]() {
|
|
25849
|
-
if (this[ht] && typeof this[
|
|
25850
|
-
let t = this[
|
|
25851
|
-
this[
|
|
27530
|
+
if (this[ht] && typeof this[m4] == "number") {
|
|
27531
|
+
let t = this[m4];
|
|
27532
|
+
this[m4] = undefined, I.close(t, (e) => e ? this.emit("error", e) : this.emit("close"));
|
|
25852
27533
|
}
|
|
25853
27534
|
}
|
|
25854
27535
|
};
|
|
@@ -25868,15 +27549,15 @@ var Wt = class extends et {
|
|
|
25868
27549
|
this[Ht](null, t);
|
|
25869
27550
|
}
|
|
25870
27551
|
[H]() {
|
|
25871
|
-
if (this[ht] && typeof this[
|
|
25872
|
-
let t = this[
|
|
25873
|
-
this[
|
|
27552
|
+
if (this[ht] && typeof this[m4] == "number") {
|
|
27553
|
+
let t = this[m4];
|
|
27554
|
+
this[m4] = undefined, I.closeSync(t), this.emit("close");
|
|
25874
27555
|
}
|
|
25875
27556
|
}
|
|
25876
27557
|
[ve](t) {
|
|
25877
27558
|
let e = true;
|
|
25878
27559
|
try {
|
|
25879
|
-
this[Pt](null, I.writeSync(this[
|
|
27560
|
+
this[Pt](null, I.writeSync(this[m4], t, 0, t.length, this[ot])), e = false;
|
|
25880
27561
|
} finally {
|
|
25881
27562
|
if (e)
|
|
25882
27563
|
try {
|
|
@@ -28674,8 +30355,8 @@ async function handleFlowsPull(ctx, opts, deps) {
|
|
|
28674
30355
|
ctx.ui.error(validation.error);
|
|
28675
30356
|
return { error: validation.error };
|
|
28676
30357
|
}
|
|
28677
|
-
const destAbs = resolve8(opts.out ??
|
|
28678
|
-
const assetsAbs =
|
|
30358
|
+
const destAbs = resolve8(opts.out ?? join32(".qawolf", opts.env));
|
|
30359
|
+
const assetsAbs = join32(dirname8(destAbs), "assets");
|
|
28679
30360
|
await resolvedDeps.fs.mkdir(assetsAbs, { recursive: true });
|
|
28680
30361
|
const yes = opts.yes ?? false;
|
|
28681
30362
|
let archive;
|
|
@@ -28721,6 +30402,7 @@ async function handleFlowsPull(ctx, opts, deps) {
|
|
|
28721
30402
|
message: flowsMessages.pull.downloadingTeamStorageAssets,
|
|
28722
30403
|
task: async (update) => {
|
|
28723
30404
|
const result = await ctx.platformClient.syncTeamStorageAssets(assetsAbs, {
|
|
30405
|
+
teamId: fetched.teamId,
|
|
28724
30406
|
onProgress: ({ current, total }) => update(flowsMessages.pull.downloadingTeamStorageAssetsProgress(current, total))
|
|
28725
30407
|
});
|
|
28726
30408
|
if (!result.ok)
|
|
@@ -29009,10 +30691,10 @@ async function resolveEnvChoice(args) {
|
|
|
29009
30691
|
|
|
29010
30692
|
// src/core/flowFailureHint.ts
|
|
29011
30693
|
function flowFailureHint(errText, projectDir) {
|
|
29012
|
-
const
|
|
29013
|
-
if (
|
|
30694
|
+
const missing = extractMissingSpecifier(errText);
|
|
30695
|
+
if (missing === undefined)
|
|
29014
30696
|
return;
|
|
29015
|
-
return runnerMessages.moduleNotFoundHint(
|
|
30697
|
+
return missing.kind === "path-alias" ? runnerMessages.pathAliasNotFoundHint(missing.specifier, projectDir) : runnerMessages.moduleNotFoundHint(missing.specifier, projectDir);
|
|
29016
30698
|
}
|
|
29017
30699
|
|
|
29018
30700
|
// src/shell/reporter/createCompositeReporter.ts
|
|
@@ -29101,9 +30783,6 @@ ${hint}`);
|
|
|
29101
30783
|
};
|
|
29102
30784
|
}
|
|
29103
30785
|
|
|
29104
|
-
// src/domains/runner/runAndroidFlowUtils.ts
|
|
29105
|
-
import { parseExecutionTarget as parseExecutionTarget3 } from "@qawolf/flow-targets";
|
|
29106
|
-
|
|
29107
30786
|
// src/domains/runner/unsupportedDepNames.ts
|
|
29108
30787
|
var unsupportedSharedDepNames = [
|
|
29109
30788
|
"fetchLatestEnvironmentVariables",
|
|
@@ -29129,7 +30808,7 @@ function resolveAvdName(targetInput) {
|
|
|
29129
30808
|
const { deviceModel, androidVersion } = raw.meta;
|
|
29130
30809
|
return makeAvdName(deviceModel, androidVersion);
|
|
29131
30810
|
}
|
|
29132
|
-
const parsed =
|
|
30811
|
+
const parsed = parseExecutionTarget(raw);
|
|
29133
30812
|
if (parsed.platform !== "android") {
|
|
29134
30813
|
throw new Error(`runAndroidFlow: expected an Android target, got platform "${parsed.platform}"`);
|
|
29135
30814
|
}
|
|
@@ -29550,15 +31229,15 @@ async function defaultRunWebFlowDeps(envDir = process.cwd(), signals) {
|
|
|
29550
31229
|
|
|
29551
31230
|
// src/domains/runtimeEnv/prepareRunDir.ts
|
|
29552
31231
|
import { createHash as createHash4 } from "node:crypto";
|
|
29553
|
-
import { join as
|
|
31232
|
+
import { join as join41, resolve as resolve9 } from "node:path";
|
|
29554
31233
|
|
|
29555
31234
|
// src/domains/runtimeEnv/execSubpathImports.ts
|
|
29556
|
-
import { join as
|
|
31235
|
+
import { join as join33 } from "node:path";
|
|
29557
31236
|
var flowSubpathImports = { "#playwright": "playwright" };
|
|
29558
31237
|
var packageJsonSchema = looseObject({ imports: record(string2(), unknown()).catch({}) }).catch({ imports: {} });
|
|
29559
31238
|
async function writeExecSubpathImports(args) {
|
|
29560
31239
|
const { execDir, fs } = args;
|
|
29561
|
-
const pkgPath =
|
|
31240
|
+
const pkgPath = join33(execDir, "package.json");
|
|
29562
31241
|
const pkg = packageJsonSchema.parse(await readPackageJson(pkgPath, fs));
|
|
29563
31242
|
const merged = { ...pkg, imports: { ...pkg.imports, ...flowSubpathImports } };
|
|
29564
31243
|
await fs.writeFile(pkgPath, JSON.stringify(merged, undefined, 2));
|
|
@@ -29580,10 +31259,10 @@ async function readPackageJson(pkgPath, fs) {
|
|
|
29580
31259
|
}
|
|
29581
31260
|
|
|
29582
31261
|
// src/domains/runtimeEnv/innerHop.ts
|
|
29583
|
-
import { join as
|
|
31262
|
+
import { join as join35 } from "node:path";
|
|
29584
31263
|
|
|
29585
31264
|
// src/domains/runtimeEnv/linkPinnedPackages.ts
|
|
29586
|
-
import { dirname as dirname9, join as
|
|
31265
|
+
import { dirname as dirname9, join as join34 } from "node:path";
|
|
29587
31266
|
|
|
29588
31267
|
// src/domains/runtimeEnv/symlinkDir.ts
|
|
29589
31268
|
import { symlink } from "node:fs/promises";
|
|
@@ -29595,16 +31274,16 @@ async function createDirSymlink(source, target) {
|
|
|
29595
31274
|
// src/domains/runtimeEnv/linkPinnedPackages.ts
|
|
29596
31275
|
async function linkPinnedPackages(args) {
|
|
29597
31276
|
const { depsRoot, nodeModulesDir, fs } = args;
|
|
29598
|
-
const managedModules =
|
|
31277
|
+
const managedModules = join34(depsRoot, "node_modules");
|
|
29599
31278
|
await fs.mkdir(nodeModulesDir, { recursive: true });
|
|
29600
31279
|
for (const { name } of pinnedPackages) {
|
|
29601
31280
|
const segments = name.split("/");
|
|
29602
|
-
const target =
|
|
31281
|
+
const target = join34(nodeModulesDir, ...segments);
|
|
29603
31282
|
if (segments.length > 1) {
|
|
29604
31283
|
await fs.mkdir(dirname9(target), { recursive: true });
|
|
29605
31284
|
}
|
|
29606
31285
|
await fs.rm(target, { recursive: true, force: true });
|
|
29607
|
-
await createDirSymlink(
|
|
31286
|
+
await createDirSymlink(join34(managedModules, ...segments), target);
|
|
29608
31287
|
}
|
|
29609
31288
|
}
|
|
29610
31289
|
|
|
@@ -29613,18 +31292,18 @@ async function populateInnerHop(args) {
|
|
|
29613
31292
|
const { depsRoot, execDir, fs } = args;
|
|
29614
31293
|
await linkPinnedPackages({
|
|
29615
31294
|
depsRoot,
|
|
29616
|
-
nodeModulesDir:
|
|
31295
|
+
nodeModulesDir: join35(execDir, "node_modules"),
|
|
29617
31296
|
fs
|
|
29618
31297
|
});
|
|
29619
31298
|
}
|
|
29620
31299
|
|
|
29621
31300
|
// src/domains/runtimeEnv/outerHop.ts
|
|
29622
31301
|
import { lstat as lstat2 } from "node:fs/promises";
|
|
29623
|
-
import { dirname as dirname11, join as
|
|
31302
|
+
import { dirname as dirname11, join as join37 } from "node:path";
|
|
29624
31303
|
|
|
29625
31304
|
// src/domains/runtimeEnv/carryOverPackages.ts
|
|
29626
31305
|
import { lstat } from "node:fs/promises";
|
|
29627
|
-
import { dirname as dirname10, join as
|
|
31306
|
+
import { dirname as dirname10, join as join36 } from "node:path";
|
|
29628
31307
|
|
|
29629
31308
|
// src/domains/runtimeEnv/carryOverPlan.ts
|
|
29630
31309
|
var executorPackageNames = new Set(pinnedPackages.map((p) => p.name));
|
|
@@ -29646,12 +31325,12 @@ async function carryOverPackages(args) {
|
|
|
29646
31325
|
const linked = [];
|
|
29647
31326
|
for (const name of names) {
|
|
29648
31327
|
const segments = name.split("/");
|
|
29649
|
-
const target =
|
|
31328
|
+
const target = join36(nodeModulesDir, ...segments);
|
|
29650
31329
|
if (await pathOccupied(target))
|
|
29651
31330
|
continue;
|
|
29652
31331
|
if (segments.length > 1)
|
|
29653
31332
|
await fs.mkdir(dirname10(target), { recursive: true });
|
|
29654
|
-
await createDirSymlink(
|
|
31333
|
+
await createDirSymlink(join36(projectModulesDir, ...segments), target);
|
|
29655
31334
|
linked.push(name);
|
|
29656
31335
|
}
|
|
29657
31336
|
return linked;
|
|
@@ -29674,18 +31353,18 @@ async function listPackageNames(dir, fs) {
|
|
|
29674
31353
|
const names = [];
|
|
29675
31354
|
for (const entry of entries) {
|
|
29676
31355
|
if (!entry.startsWith("@")) {
|
|
29677
|
-
if (fs.existsSync(
|
|
31356
|
+
if (fs.existsSync(join36(dir, entry, "package.json")))
|
|
29678
31357
|
names.push(entry);
|
|
29679
31358
|
continue;
|
|
29680
31359
|
}
|
|
29681
31360
|
let scoped;
|
|
29682
31361
|
try {
|
|
29683
|
-
scoped = await fs.readdir(
|
|
31362
|
+
scoped = await fs.readdir(join36(dir, entry));
|
|
29684
31363
|
} catch {
|
|
29685
31364
|
continue;
|
|
29686
31365
|
}
|
|
29687
31366
|
for (const inner of scoped) {
|
|
29688
|
-
if (fs.existsSync(
|
|
31367
|
+
if (fs.existsSync(join36(dir, entry, inner, "package.json"))) {
|
|
29689
31368
|
names.push(`${entry}/${inner}`);
|
|
29690
31369
|
}
|
|
29691
31370
|
}
|
|
@@ -29703,7 +31382,7 @@ async function populateOuterHop(args) {
|
|
|
29703
31382
|
const depNames = Object.keys(installableDeps);
|
|
29704
31383
|
const { satisfying, rejected } = await findSatisfyingNodeModulesDir(projectDir, depNames, fs);
|
|
29705
31384
|
if (satisfying !== undefined) {
|
|
29706
|
-
await createDirSymlink(satisfying,
|
|
31385
|
+
await createDirSymlink(satisfying, join37(runDir, "node_modules"));
|
|
29707
31386
|
return { mode: "symlink", nodeModulesDir: satisfying };
|
|
29708
31387
|
}
|
|
29709
31388
|
if (depNames.length === 0)
|
|
@@ -29712,12 +31391,12 @@ async function populateOuterHop(args) {
|
|
|
29712
31391
|
await installOuterDeps(runDir, installableDeps, fs, args.install ?? spawnNpmInstall);
|
|
29713
31392
|
await linkPinnedPackages({
|
|
29714
31393
|
depsRoot: args.depsRoot,
|
|
29715
|
-
nodeModulesDir:
|
|
31394
|
+
nodeModulesDir: join37(runDir, "node_modules"),
|
|
29716
31395
|
fs
|
|
29717
31396
|
});
|
|
29718
31397
|
const carriedOver = await carryOverPackages({
|
|
29719
|
-
projectModulesDir:
|
|
29720
|
-
nodeModulesDir:
|
|
31398
|
+
projectModulesDir: join37(projectDir, "node_modules"),
|
|
31399
|
+
nodeModulesDir: join37(runDir, "node_modules"),
|
|
29721
31400
|
fs
|
|
29722
31401
|
});
|
|
29723
31402
|
return { mode: "install", depCount: depNames.length, rejected, carriedOver };
|
|
@@ -29726,10 +31405,10 @@ async function findSatisfyingNodeModulesDir(startDir, depNames, fs) {
|
|
|
29726
31405
|
const rejected = [];
|
|
29727
31406
|
let dir = startDir;
|
|
29728
31407
|
while (true) {
|
|
29729
|
-
const candidate =
|
|
31408
|
+
const candidate = join37(dir, "node_modules");
|
|
29730
31409
|
const stats = await lstatSafe(candidate);
|
|
29731
31410
|
if (stats !== undefined && stats.isDirectory() && !stats.isSymbolicLink()) {
|
|
29732
|
-
const missing = depNames.filter((name) => !fs.existsSync(
|
|
31411
|
+
const missing = depNames.filter((name) => !fs.existsSync(join37(candidate, name, "package.json")));
|
|
29733
31412
|
if (missing.length === 0)
|
|
29734
31413
|
return { satisfying: candidate, rejected };
|
|
29735
31414
|
rejected.push({ dir: candidate, missing });
|
|
@@ -29750,7 +31429,7 @@ async function lstatSafe(path) {
|
|
|
29750
31429
|
async function readInstallableDeps(projectDir, fs) {
|
|
29751
31430
|
let content;
|
|
29752
31431
|
try {
|
|
29753
|
-
content = await fs.readFile(
|
|
31432
|
+
content = await fs.readFile(join37(projectDir, "package.json"));
|
|
29754
31433
|
} catch {
|
|
29755
31434
|
return {};
|
|
29756
31435
|
}
|
|
@@ -29768,8 +31447,8 @@ async function readInstallableDeps(projectDir, fs) {
|
|
|
29768
31447
|
return Object.fromEntries(Object.entries(rawDeps).filter(([name]) => !executorPackageNames2.has(name)).filter((entry) => typeof entry[1] === "string"));
|
|
29769
31448
|
}
|
|
29770
31449
|
async function installOuterDeps(runDir, deps, fs, install) {
|
|
29771
|
-
await fs.writeFile(
|
|
29772
|
-
await fs.writeFile(
|
|
31450
|
+
await fs.writeFile(join37(runDir, "package.json"), JSON.stringify({ name: "qawolf-run", private: true, dependencies: deps }, undefined, 2));
|
|
31451
|
+
await fs.writeFile(join37(runDir, ".npmrc"), `@qawolf:registry=https://registry.npmjs.org/
|
|
29773
31452
|
`);
|
|
29774
31453
|
const result = await install(runDir);
|
|
29775
31454
|
if (result.exitCode !== 0) {
|
|
@@ -29777,16 +31456,266 @@ async function installOuterDeps(runDir, deps, fs, install) {
|
|
|
29777
31456
|
}
|
|
29778
31457
|
}
|
|
29779
31458
|
|
|
31459
|
+
// src/domains/runtimeEnv/rewriteStagedAliases.ts
|
|
31460
|
+
import { join as join38 } from "node:path";
|
|
31461
|
+
|
|
31462
|
+
// src/core/aliasImports/rewriteAliasImports.ts
|
|
31463
|
+
import { posix as posix3 } from "node:path";
|
|
31464
|
+
|
|
31465
|
+
// src/core/aliasImports/collectAliasSpecifiers.ts
|
|
31466
|
+
function isRelativeSpecifier(specifier) {
|
|
31467
|
+
return specifier.startsWith("./") || specifier.startsWith("../");
|
|
31468
|
+
}
|
|
31469
|
+
function collectAliasSpecifiers(options) {
|
|
31470
|
+
const { sourceFile, typescript: compiler } = options;
|
|
31471
|
+
const specifiers = [];
|
|
31472
|
+
const addCandidate = (literal) => {
|
|
31473
|
+
if (isRelativeSpecifier(literal.text))
|
|
31474
|
+
return;
|
|
31475
|
+
specifiers.push({
|
|
31476
|
+
end: literal.getEnd(),
|
|
31477
|
+
specifier: literal.text,
|
|
31478
|
+
start: literal.getStart(sourceFile)
|
|
31479
|
+
});
|
|
31480
|
+
};
|
|
31481
|
+
for (const statement of sourceFile.statements) {
|
|
31482
|
+
if (compiler.isImportDeclaration(statement)) {
|
|
31483
|
+
const phase = statement.importClause?.phaseModifier;
|
|
31484
|
+
if (phase === compiler.SyntaxKind.TypeKeyword)
|
|
31485
|
+
continue;
|
|
31486
|
+
if (compiler.isStringLiteral(statement.moduleSpecifier)) {
|
|
31487
|
+
addCandidate(statement.moduleSpecifier);
|
|
31488
|
+
}
|
|
31489
|
+
continue;
|
|
31490
|
+
}
|
|
31491
|
+
if (compiler.isExportDeclaration(statement) && !statement.isTypeOnly) {
|
|
31492
|
+
const { moduleSpecifier } = statement;
|
|
31493
|
+
if (moduleSpecifier !== undefined && compiler.isStringLiteral(moduleSpecifier)) {
|
|
31494
|
+
addCandidate(moduleSpecifier);
|
|
31495
|
+
}
|
|
31496
|
+
}
|
|
31497
|
+
}
|
|
31498
|
+
const visit = (node) => {
|
|
31499
|
+
if (compiler.isCallExpression(node) && node.expression.kind === compiler.SyntaxKind.ImportKeyword) {
|
|
31500
|
+
const [firstArgument] = node.arguments;
|
|
31501
|
+
if (firstArgument !== undefined && (compiler.isStringLiteral(firstArgument) || compiler.isNoSubstitutionTemplateLiteral(firstArgument))) {
|
|
31502
|
+
addCandidate(firstArgument);
|
|
31503
|
+
}
|
|
31504
|
+
return;
|
|
31505
|
+
}
|
|
31506
|
+
compiler.forEachChild(node, visit);
|
|
31507
|
+
};
|
|
31508
|
+
visit(sourceFile);
|
|
31509
|
+
return specifiers;
|
|
31510
|
+
}
|
|
31511
|
+
|
|
31512
|
+
// src/core/aliasImports/filePathVariants.ts
|
|
31513
|
+
var sourceExtensionPattern = /\.(js|ts)$/;
|
|
31514
|
+
var sourceExtensions2 = [".ts", ".js"];
|
|
31515
|
+
function filePathVariants(importPath) {
|
|
31516
|
+
const hasSourceExtension = sourceExtensionPattern.test(importPath);
|
|
31517
|
+
const base = importPath.replace(sourceExtensionPattern, "");
|
|
31518
|
+
const siblings = sourceExtensions2.map((extension) => base + extension);
|
|
31519
|
+
const indexes = hasSourceExtension ? [] : sourceExtensions2.map((extension) => `${base}/index${extension}`);
|
|
31520
|
+
return [...new Set([importPath, ...siblings, ...indexes])];
|
|
31521
|
+
}
|
|
31522
|
+
|
|
31523
|
+
// src/core/aliasImports/tsconfigPaths.ts
|
|
31524
|
+
function isRecord2(value) {
|
|
31525
|
+
return typeof value === "object" && value !== null;
|
|
31526
|
+
}
|
|
31527
|
+
function isTsconfigPaths(value) {
|
|
31528
|
+
return isRecord2(value) && Object.values(value).every((targets) => Array.isArray(targets) && targets.every((target) => typeof target === "string"));
|
|
31529
|
+
}
|
|
31530
|
+
function parseTsconfigContent(tsconfigContent) {
|
|
31531
|
+
let parsed;
|
|
31532
|
+
try {
|
|
31533
|
+
parsed = JSON.parse(tsconfigContent);
|
|
31534
|
+
} catch {
|
|
31535
|
+
return { type: "unparseable" };
|
|
31536
|
+
}
|
|
31537
|
+
if (!isRecord2(parsed))
|
|
31538
|
+
return { paths: undefined, type: "parsed" };
|
|
31539
|
+
const compilerOptions = parsed["compilerOptions"];
|
|
31540
|
+
if (!isRecord2(compilerOptions))
|
|
31541
|
+
return { paths: undefined, type: "parsed" };
|
|
31542
|
+
const paths = compilerOptions["paths"];
|
|
31543
|
+
return {
|
|
31544
|
+
paths: isTsconfigPaths(paths) ? paths : undefined,
|
|
31545
|
+
type: "parsed"
|
|
31546
|
+
};
|
|
31547
|
+
}
|
|
31548
|
+
function parseTsconfigPaths(tsconfigContent) {
|
|
31549
|
+
const parsed = parseTsconfigContent(tsconfigContent);
|
|
31550
|
+
return parsed.type === "parsed" ? parsed.paths : undefined;
|
|
31551
|
+
}
|
|
31552
|
+
function parseWildcardPattern(pattern) {
|
|
31553
|
+
const wildcard = pattern.indexOf("*");
|
|
31554
|
+
if (wildcard === -1 || wildcard !== pattern.lastIndexOf("*"))
|
|
31555
|
+
return;
|
|
31556
|
+
return {
|
|
31557
|
+
prefix: pattern.slice(0, wildcard),
|
|
31558
|
+
suffix: pattern.slice(wildcard + 1)
|
|
31559
|
+
};
|
|
31560
|
+
}
|
|
31561
|
+
function matchesWildcard(importPath, { prefix, suffix }) {
|
|
31562
|
+
return importPath.length >= prefix.length + suffix.length && importPath.startsWith(prefix) && importPath.endsWith(suffix);
|
|
31563
|
+
}
|
|
31564
|
+
function longestPrefixMatch(importPath, paths) {
|
|
31565
|
+
return Object.entries(paths).flatMap(([pattern, targets]) => {
|
|
31566
|
+
const parsed = parseWildcardPattern(pattern);
|
|
31567
|
+
if (parsed === undefined || !matchesWildcard(importPath, parsed)) {
|
|
31568
|
+
return [];
|
|
31569
|
+
}
|
|
31570
|
+
return [{ pattern: parsed, targets }];
|
|
31571
|
+
}).reduce((best, candidate) => best === undefined || candidate.pattern.prefix.length > best.pattern.prefix.length ? candidate : best, undefined);
|
|
31572
|
+
}
|
|
31573
|
+
function resolvePathAlias(importPath, paths) {
|
|
31574
|
+
if (paths === undefined)
|
|
31575
|
+
return;
|
|
31576
|
+
const [exactTarget] = paths[importPath] ?? [];
|
|
31577
|
+
if (exactTarget !== undefined)
|
|
31578
|
+
return exactTarget;
|
|
31579
|
+
const match = longestPrefixMatch(importPath, paths);
|
|
31580
|
+
if (match === undefined)
|
|
31581
|
+
return;
|
|
31582
|
+
const [target] = match.targets;
|
|
31583
|
+
if (target === undefined)
|
|
31584
|
+
return;
|
|
31585
|
+
const substituted = importPath.slice(match.pattern.prefix.length, importPath.length - match.pattern.suffix.length);
|
|
31586
|
+
return target.replace("*", substituted);
|
|
31587
|
+
}
|
|
31588
|
+
|
|
31589
|
+
// src/core/aliasImports/rewriteAliasImports.ts
|
|
31590
|
+
function findTargetFilePath(options) {
|
|
31591
|
+
return filePathVariants(posix3.normalize(options.aliasTarget)).find((candidate) => options.projectFilePaths.has(candidate));
|
|
31592
|
+
}
|
|
31593
|
+
function toRelativeSpecifier(options) {
|
|
31594
|
+
const relativePath = posix3.relative(posix3.dirname(options.importingFilePath), options.targetFilePath);
|
|
31595
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
31596
|
+
}
|
|
31597
|
+
function applyEdit(code, edit) {
|
|
31598
|
+
const quote = code.slice(edit.start, edit.start + 1);
|
|
31599
|
+
return code.slice(0, edit.start) + quote + edit.relativeSpecifier + quote + code.slice(edit.end);
|
|
31600
|
+
}
|
|
31601
|
+
function rewriteAliasImports(options) {
|
|
31602
|
+
const { code, importingFilePath, projectFilePaths, tsconfigPaths } = options;
|
|
31603
|
+
const compiler = options.typescript;
|
|
31604
|
+
if (tsconfigPaths === undefined)
|
|
31605
|
+
return code;
|
|
31606
|
+
const sourceFile = compiler.createSourceFile(importingFilePath, code, compiler.ScriptTarget.Latest, true);
|
|
31607
|
+
const edits = collectAliasSpecifiers({
|
|
31608
|
+
sourceFile,
|
|
31609
|
+
typescript: compiler
|
|
31610
|
+
}).flatMap((candidate) => {
|
|
31611
|
+
const aliasTarget = resolvePathAlias(candidate.specifier, tsconfigPaths);
|
|
31612
|
+
if (aliasTarget === undefined)
|
|
31613
|
+
return [];
|
|
31614
|
+
const targetFilePath = findTargetFilePath({
|
|
31615
|
+
aliasTarget,
|
|
31616
|
+
projectFilePaths
|
|
31617
|
+
});
|
|
31618
|
+
if (targetFilePath === undefined)
|
|
31619
|
+
return [];
|
|
31620
|
+
return [
|
|
31621
|
+
{
|
|
31622
|
+
end: candidate.end,
|
|
31623
|
+
relativeSpecifier: toRelativeSpecifier({
|
|
31624
|
+
importingFilePath,
|
|
31625
|
+
targetFilePath
|
|
31626
|
+
}),
|
|
31627
|
+
start: candidate.start
|
|
31628
|
+
}
|
|
31629
|
+
];
|
|
31630
|
+
});
|
|
31631
|
+
return edits.sort((left, right) => right.start - left.start).reduce(applyEdit, code);
|
|
31632
|
+
}
|
|
31633
|
+
|
|
31634
|
+
// src/domains/runtimeEnv/rewriteStagedAliases.ts
|
|
31635
|
+
var skippedDirs = new Set(["node_modules", ".git", ".qawolf"]);
|
|
31636
|
+
var sourceExtensions3 = [".ts", ".js"];
|
|
31637
|
+
async function rewriteStagedAliases(args) {
|
|
31638
|
+
const tsconfig = await readStagedTsconfig(args);
|
|
31639
|
+
if (tsconfig.type === "unparseable") {
|
|
31640
|
+
args.onTsconfigUnparsed?.();
|
|
31641
|
+
return [];
|
|
31642
|
+
}
|
|
31643
|
+
if (tsconfig.type === "absent" || tsconfig.paths === undefined)
|
|
31644
|
+
return [];
|
|
31645
|
+
const tsconfigPaths = tsconfig.paths;
|
|
31646
|
+
const stagedPaths = await listStagedSourceFiles({
|
|
31647
|
+
dir: args.execDir,
|
|
31648
|
+
fs: args.fs,
|
|
31649
|
+
prefix: ""
|
|
31650
|
+
});
|
|
31651
|
+
const projectFilePaths = new Set(stagedPaths);
|
|
31652
|
+
const aliasPrefixes = Object.keys(tsconfigPaths).map((pattern) => pattern.split("*")[0] ?? pattern);
|
|
31653
|
+
const mentionsAnAlias = (code) => aliasPrefixes.some((prefix) => code.includes(prefix));
|
|
31654
|
+
const { default: typescript } = await import("typescript");
|
|
31655
|
+
const rewriteOne = async (stagedPath) => {
|
|
31656
|
+
const absolutePath = join38(args.execDir, stagedPath);
|
|
31657
|
+
const code = await args.fs.readFile(absolutePath);
|
|
31658
|
+
if (!mentionsAnAlias(code))
|
|
31659
|
+
return;
|
|
31660
|
+
const rewritten = rewriteAliasImports({
|
|
31661
|
+
code,
|
|
31662
|
+
importingFilePath: stagedPath,
|
|
31663
|
+
projectFilePaths,
|
|
31664
|
+
tsconfigPaths,
|
|
31665
|
+
typescript
|
|
31666
|
+
});
|
|
31667
|
+
if (rewritten === code)
|
|
31668
|
+
return;
|
|
31669
|
+
await args.fs.writeFile(absolutePath, rewritten);
|
|
31670
|
+
return stagedPath;
|
|
31671
|
+
};
|
|
31672
|
+
const rewrittenPaths = [];
|
|
31673
|
+
for await (const stagedPath of batchMap(stagedPaths, rewriteOne, flowBatchSize)) {
|
|
31674
|
+
if (stagedPath !== undefined)
|
|
31675
|
+
rewrittenPaths.push(stagedPath);
|
|
31676
|
+
}
|
|
31677
|
+
return rewrittenPaths;
|
|
31678
|
+
}
|
|
31679
|
+
async function readStagedTsconfig(options) {
|
|
31680
|
+
let content;
|
|
31681
|
+
try {
|
|
31682
|
+
content = await options.fs.readFile(join38(options.execDir, "tsconfig.json"));
|
|
31683
|
+
} catch (err) {
|
|
31684
|
+
if (isNoEntError(err))
|
|
31685
|
+
return { type: "absent" };
|
|
31686
|
+
throw err;
|
|
31687
|
+
}
|
|
31688
|
+
return parseTsconfigContent(content);
|
|
31689
|
+
}
|
|
31690
|
+
async function listStagedSourceFiles(options) {
|
|
31691
|
+
const entries = await options.fs.readdirWithTypes(options.dir);
|
|
31692
|
+
const nested = await Promise.all(entries.map(async (entry) => {
|
|
31693
|
+
if (skippedDirs.has(entry.name))
|
|
31694
|
+
return [];
|
|
31695
|
+
const stagedPath = options.prefix === "" ? entry.name : `${options.prefix}/${entry.name}`;
|
|
31696
|
+
if (entry.isDirectory()) {
|
|
31697
|
+
return listStagedSourceFiles({
|
|
31698
|
+
dir: join38(options.dir, entry.name),
|
|
31699
|
+
fs: options.fs,
|
|
31700
|
+
prefix: stagedPath
|
|
31701
|
+
});
|
|
31702
|
+
}
|
|
31703
|
+
const isSource = sourceExtensions3.some((extension) => entry.name.endsWith(extension));
|
|
31704
|
+
return entry.isFile() && isSource ? [stagedPath] : [];
|
|
31705
|
+
}));
|
|
31706
|
+
return nested.flat();
|
|
31707
|
+
}
|
|
31708
|
+
|
|
29780
31709
|
// src/domains/runtimeEnv/stageFlowFiles.ts
|
|
29781
31710
|
import { createHash as createHash3 } from "node:crypto";
|
|
29782
|
-
import { basename as basename6, dirname as dirname12, join as
|
|
31711
|
+
import { basename as basename6, dirname as dirname12, join as join40, sep as sep4 } from "node:path";
|
|
29783
31712
|
|
|
29784
31713
|
// src/shell/copyDir.ts
|
|
29785
31714
|
import { cp, readdir as readdir2 } from "node:fs/promises";
|
|
29786
|
-
import { basename as basename5, join as
|
|
31715
|
+
import { basename as basename5, join as join39 } from "node:path";
|
|
29787
31716
|
async function copyDirExcluding(source, destination, excludedNames) {
|
|
29788
31717
|
const entries = await readdir2(source, { withFileTypes: true });
|
|
29789
|
-
await Promise.all(entries.filter((entry) => !excludedNames.has(entry.name)).map((entry) => cp(
|
|
31718
|
+
await Promise.all(entries.filter((entry) => !excludedNames.has(entry.name)).map((entry) => cp(join39(source, entry.name), join39(destination, entry.name), {
|
|
29790
31719
|
recursive: true,
|
|
29791
31720
|
filter: (path) => !excludedNames.has(basename5(path))
|
|
29792
31721
|
})));
|
|
@@ -29803,14 +31732,14 @@ async function stageFlowFiles(args) {
|
|
|
29803
31732
|
if (files.length > 1) {
|
|
29804
31733
|
return Promise.all(files.map((f) => stageOneFile(f, execDir, fs)));
|
|
29805
31734
|
}
|
|
29806
|
-
await Promise.all(files.map((f) => fs.copyFile(f,
|
|
29807
|
-
return files.map((f) =>
|
|
31735
|
+
await Promise.all(files.map((f) => fs.copyFile(f, join40(execDir, basename6(f)))));
|
|
31736
|
+
return files.map((f) => join40(execDir, basename6(f)));
|
|
29808
31737
|
}
|
|
29809
31738
|
async function stageOneFile(file, execDir, fs) {
|
|
29810
31739
|
const dirHash = createHash3("sha256").update(dirname12(file)).digest("hex").slice(0, 8);
|
|
29811
|
-
const subDir =
|
|
31740
|
+
const subDir = join40(execDir, dirHash);
|
|
29812
31741
|
await fs.mkdir(subDir, { recursive: true });
|
|
29813
|
-
const dest =
|
|
31742
|
+
const dest = join40(subDir, basename6(file));
|
|
29814
31743
|
await fs.copyFile(file, dest);
|
|
29815
31744
|
return dest;
|
|
29816
31745
|
}
|
|
@@ -29818,7 +31747,7 @@ function remapPath(file, projectDir, execDir) {
|
|
|
29818
31747
|
if (file === projectDir)
|
|
29819
31748
|
return execDir;
|
|
29820
31749
|
if (file.startsWith(projectDir + sep4)) {
|
|
29821
|
-
return
|
|
31750
|
+
return join40(execDir, file.slice(projectDir.length + 1));
|
|
29822
31751
|
}
|
|
29823
31752
|
return;
|
|
29824
31753
|
}
|
|
@@ -29828,15 +31757,21 @@ async function prepareRunDir(args) {
|
|
|
29828
31757
|
const { files, projectDir, depsRoot, runRoot } = args;
|
|
29829
31758
|
const fs = args.fs ?? makeDefaultFs();
|
|
29830
31759
|
const runId = buildRunId(projectDir, files);
|
|
29831
|
-
const runDir =
|
|
31760
|
+
const runDir = join41(runRoot, runId);
|
|
29832
31761
|
await fs.rm(runDir, { recursive: true, force: true });
|
|
29833
31762
|
await fs.mkdir(runDir, { recursive: true });
|
|
29834
|
-
const execDir =
|
|
31763
|
+
const execDir = join41(runDir, "exec");
|
|
29835
31764
|
await fs.mkdir(execDir, { recursive: true });
|
|
29836
31765
|
await populateInnerHop({ depsRoot, execDir, fs });
|
|
29837
31766
|
const stagedFiles = await stageFlowFiles({ files, projectDir, execDir, fs });
|
|
29838
31767
|
if (projectDir !== undefined) {
|
|
29839
31768
|
await writeExecSubpathImports({ execDir, fs });
|
|
31769
|
+
const onTsconfigUnparsed = args.onTsconfigUnparsed;
|
|
31770
|
+
await rewriteStagedAliases({
|
|
31771
|
+
execDir,
|
|
31772
|
+
fs,
|
|
31773
|
+
...onTsconfigUnparsed !== undefined ? { onTsconfigUnparsed: () => onTsconfigUnparsed(projectDir) } : {}
|
|
31774
|
+
});
|
|
29840
31775
|
}
|
|
29841
31776
|
const outerHop = await populateOuterHop({
|
|
29842
31777
|
projectDir,
|
|
@@ -29862,17 +31797,17 @@ function buildRunId(projectDir, files) {
|
|
|
29862
31797
|
}
|
|
29863
31798
|
|
|
29864
31799
|
// src/shell/testkit.ts
|
|
29865
|
-
import { join as
|
|
31800
|
+
import { join as join42 } from "node:path";
|
|
29866
31801
|
function notAvailableLocally(name) {
|
|
29867
31802
|
throw new Error(runnerMessages.notAvailableLocally(name));
|
|
29868
31803
|
}
|
|
29869
31804
|
async function loadSdkDeps(cwd) {
|
|
29870
|
-
const testkitDir =
|
|
31805
|
+
const testkitDir = join42(cwd, "node_modules", "@qawolf", "testkit");
|
|
29871
31806
|
try {
|
|
29872
31807
|
const clientMod = await importFromPath(resolveFromEnvDir(cwd, "@qawolf/testkit/client"));
|
|
29873
31808
|
if (typeof clientMod.createTestkitClient !== "function")
|
|
29874
31809
|
throw new Error("createTestkitClient is not a function");
|
|
29875
|
-
const scopeMod = await importFromPath(
|
|
31810
|
+
const scopeMod = await importFromPath(join42(testkitDir, "dist", "clientScope.js"));
|
|
29876
31811
|
if (typeof scopeMod.configureTestkitClient !== "function")
|
|
29877
31812
|
throw new Error("configureTestkitClient is not a function");
|
|
29878
31813
|
return {
|
|
@@ -29930,9 +31865,9 @@ async function registerLazyEmailsClient(getInbox, cwd, deps) {
|
|
|
29930
31865
|
}
|
|
29931
31866
|
|
|
29932
31867
|
// src/commands/flows/envVarDeps.ts
|
|
29933
|
-
import { join as
|
|
31868
|
+
import { join as join43 } from "node:path";
|
|
29934
31869
|
function envFilePath(envDir) {
|
|
29935
|
-
return
|
|
31870
|
+
return join43(envDir, ".env");
|
|
29936
31871
|
}
|
|
29937
31872
|
async function readEnv(envDir, fs) {
|
|
29938
31873
|
try {
|
|
@@ -30056,7 +31991,7 @@ async function selectRunByTag(args) {
|
|
|
30056
31991
|
}
|
|
30057
31992
|
|
|
30058
31993
|
// src/commands/flows/runStagedFlows.ts
|
|
30059
|
-
import { join as
|
|
31994
|
+
import { join as join47 } from "node:path";
|
|
30060
31995
|
|
|
30061
31996
|
// src/shell/appium/createAppiumServer.ts
|
|
30062
31997
|
import { existsSync as existsSync2 } from "node:fs";
|
|
@@ -30190,7 +32125,7 @@ var defaultAdb = async (args) => {
|
|
|
30190
32125
|
|
|
30191
32126
|
// src/shell/appium/createAndroidEmulator.ts
|
|
30192
32127
|
var defaultBootTimeoutMs = 120000;
|
|
30193
|
-
var
|
|
32128
|
+
var pollIntervalMs2 = 2000;
|
|
30194
32129
|
var defaultSpawnEmulator = (bin, args) => {
|
|
30195
32130
|
const child = spawn3(bin, args, { stdio: "ignore" });
|
|
30196
32131
|
child.unref();
|
|
@@ -30208,7 +32143,7 @@ async function bootSequence(adb, serial, cancelled) {
|
|
|
30208
32143
|
]).catch(() => ({ stdout: "" }));
|
|
30209
32144
|
if (stdout.trim() === "1")
|
|
30210
32145
|
return;
|
|
30211
|
-
await new Promise((r) => setTimeout(r,
|
|
32146
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs2));
|
|
30212
32147
|
}
|
|
30213
32148
|
}
|
|
30214
32149
|
function waitForBoot(adb, serial, timeoutMs) {
|
|
@@ -31362,14 +33297,14 @@ async function runWebFlow({
|
|
|
31362
33297
|
|
|
31363
33298
|
// src/shell/embeddedWorkerCli.ts
|
|
31364
33299
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
31365
|
-
import { basename as basename7, join as
|
|
33300
|
+
import { basename as basename7, join as join44 } from "node:path";
|
|
31366
33301
|
var embeddedCliPathEnv = "QAWOLF_EMBEDDED_CLI_PATH";
|
|
31367
33302
|
function extractEmbeddedWorkerCli() {
|
|
31368
33303
|
const assetPath = process.env[embeddedCliPathEnv];
|
|
31369
33304
|
if (assetPath === undefined || assetPath === "")
|
|
31370
33305
|
return;
|
|
31371
|
-
const dir =
|
|
31372
|
-
const dest =
|
|
33306
|
+
const dir = join44(getDataDir(), "worker");
|
|
33307
|
+
const dest = join44(dir, basename7(assetPath));
|
|
31373
33308
|
if (existsSync3(dest))
|
|
31374
33309
|
return dest;
|
|
31375
33310
|
mkdirSync3(dir, { recursive: true });
|
|
@@ -31527,33 +33462,33 @@ function makePooledDispatch(resolvedDir) {
|
|
|
31527
33462
|
import { dirname as dirname13 } from "node:path";
|
|
31528
33463
|
|
|
31529
33464
|
// src/shell/reporter/createConsoleReporter.ts
|
|
31530
|
-
import { styleText as
|
|
33465
|
+
import { styleText as styleText5 } from "node:util";
|
|
31531
33466
|
function fmtDuration(ms) {
|
|
31532
33467
|
return `(${(ms / 1000).toFixed(2)}s)`;
|
|
31533
33468
|
}
|
|
31534
33469
|
function fmtStampLine(manifest) {
|
|
31535
33470
|
const shortHash = manifest.contentHash.slice(0, 8);
|
|
31536
|
-
return ` ${
|
|
33471
|
+
return ` ${styleText5("dim", `env=${manifest.envId} hash=${shortHash}`)}
|
|
31537
33472
|
`;
|
|
31538
33473
|
}
|
|
31539
33474
|
function createConsoleReporter(deps) {
|
|
31540
33475
|
return {
|
|
31541
33476
|
onFlowStart({ name, path }) {
|
|
31542
|
-
deps.stdout.write(`${
|
|
33477
|
+
deps.stdout.write(`${styleText5("magenta", "•")} ${styleText5(["bold", "magenta"], name)} ${styleText5("dim", path)}
|
|
31543
33478
|
`);
|
|
31544
33479
|
},
|
|
31545
33480
|
onTestResult({ label, status, durationMs }) {
|
|
31546
|
-
const icon = status === "pass" ?
|
|
31547
|
-
deps.stdout.write(` - ${label} ${icon} ${
|
|
33481
|
+
const icon = status === "pass" ? styleText5("green", "✓") : styleText5("red", "✗");
|
|
33482
|
+
deps.stdout.write(` - ${label} ${icon} ${styleText5("dim", fmtDuration(durationMs))}
|
|
31548
33483
|
`);
|
|
31549
33484
|
},
|
|
31550
33485
|
onScreenshot({ path }) {
|
|
31551
|
-
deps.stdout.write(` ${
|
|
33486
|
+
deps.stdout.write(` ${styleText5("dim", runnerMessages.screenshot(path))}
|
|
31552
33487
|
`);
|
|
31553
33488
|
},
|
|
31554
33489
|
onFlowPass({ tests, durationMs, manifest }) {
|
|
31555
33490
|
const counts = tests.total > 0 ? `${tests.passed}/${tests.total} tests ` : "";
|
|
31556
|
-
deps.stdout.write(` ${
|
|
33491
|
+
deps.stdout.write(` ${styleText5("green", "✓")} ${counts}passed ${styleText5("dim", fmtDuration(durationMs))}
|
|
31557
33492
|
`);
|
|
31558
33493
|
if (manifest)
|
|
31559
33494
|
deps.stdout.write(fmtStampLine(manifest));
|
|
@@ -31564,8 +33499,8 @@ function createConsoleReporter(deps) {
|
|
|
31564
33499
|
`);
|
|
31565
33500
|
const indent = " ";
|
|
31566
33501
|
const formatted = [
|
|
31567
|
-
|
|
31568
|
-
...restLines.map((line) =>
|
|
33502
|
+
styleText5("red", `${indent}${firstLine}`),
|
|
33503
|
+
...restLines.map((line) => styleText5("dim", `${indent}${line}`))
|
|
31569
33504
|
].join(`
|
|
31570
33505
|
`);
|
|
31571
33506
|
deps.stderr.write(`${formatted}
|
|
@@ -31573,12 +33508,12 @@ function createConsoleReporter(deps) {
|
|
|
31573
33508
|
`);
|
|
31574
33509
|
const hint = flowFailureHint(errStr, deps.projectDir);
|
|
31575
33510
|
if (hint !== undefined) {
|
|
31576
|
-
deps.stderr.write(`${
|
|
33511
|
+
deps.stderr.write(`${styleText5("yellow", `${indent}${hint}`)}
|
|
31577
33512
|
|
|
31578
33513
|
`);
|
|
31579
33514
|
}
|
|
31580
33515
|
const counts = tests.total > 0 ? `${tests.passed}/${tests.total} tests ` : "";
|
|
31581
|
-
deps.stdout.write(` ${
|
|
33516
|
+
deps.stdout.write(` ${styleText5("red", "✗")} ${counts}passed ${styleText5("dim", fmtDuration(durationMs))}
|
|
31582
33517
|
`);
|
|
31583
33518
|
if (manifest)
|
|
31584
33519
|
deps.stdout.write(fmtStampLine(manifest));
|
|
@@ -31593,21 +33528,21 @@ ${runnerMessages.retrying(attempt, maxAttempts)}
|
|
|
31593
33528
|
if (total <= 1)
|
|
31594
33529
|
return;
|
|
31595
33530
|
const allPassed = summary.flowsFailed === 0;
|
|
31596
|
-
const icon =
|
|
33531
|
+
const icon = styleText5(allPassed ? "green" : "red", allPassed ? "✓" : "✗");
|
|
31597
33532
|
const skippedStr = summary.flowsSkipped > 0 ? ` (${summary.flowsSkipped} skipped)` : "";
|
|
31598
33533
|
const flowCount = `${summary.flowsPassed}/${total} flows passed${skippedStr}`;
|
|
31599
33534
|
const testCount = summary.testsTotal > 0 ? ` · ${summary.testsPassed}/${summary.testsTotal} tests passed` : "";
|
|
31600
33535
|
const width = deps.columns ?? process.stdout.columns ?? 72;
|
|
31601
33536
|
deps.stdout.write(`
|
|
31602
|
-
${
|
|
33537
|
+
${styleText5("dim", "─".repeat(width))}
|
|
31603
33538
|
`);
|
|
31604
|
-
deps.stdout.write(` ${icon} ${flowCount}${testCount} ${
|
|
33539
|
+
deps.stdout.write(` ${icon} ${flowCount}${testCount} ${styleText5("dim", fmtDuration(summary.durationMs))}
|
|
31605
33540
|
`);
|
|
31606
33541
|
}
|
|
31607
33542
|
};
|
|
31608
33543
|
}
|
|
31609
33544
|
// src/shell/reporter/createJUnitReporter.ts
|
|
31610
|
-
import { join as
|
|
33545
|
+
import { join as join45 } from "node:path";
|
|
31611
33546
|
|
|
31612
33547
|
// src/shell/reporter/junitXml.ts
|
|
31613
33548
|
function escapeXml(str) {
|
|
@@ -31646,7 +33581,7 @@ ${suites}`;
|
|
|
31646
33581
|
|
|
31647
33582
|
// src/shell/reporter/createJUnitReporter.ts
|
|
31648
33583
|
function resolveJUnitOutputPath(junit, outputDir) {
|
|
31649
|
-
return typeof junit === "string" && junit.trim() !== "" ? junit :
|
|
33584
|
+
return typeof junit === "string" && junit.trim() !== "" ? junit : join45(outputDir, "junit-report.xml");
|
|
31650
33585
|
}
|
|
31651
33586
|
function createJUnitReporter(deps) {
|
|
31652
33587
|
const flows = [];
|
|
@@ -31737,11 +33672,11 @@ function buildFlowsRunDeps(args) {
|
|
|
31737
33672
|
|
|
31738
33673
|
// src/commands/flows/loadEnvFile.ts
|
|
31739
33674
|
import { readFile } from "node:fs/promises";
|
|
31740
|
-
import { join as
|
|
33675
|
+
import { join as join46 } from "node:path";
|
|
31741
33676
|
async function loadEnvFile(envDir) {
|
|
31742
33677
|
let content;
|
|
31743
33678
|
try {
|
|
31744
|
-
content = await readFile(
|
|
33679
|
+
content = await readFile(join46(envDir, ".env"), "utf8");
|
|
31745
33680
|
} catch (err) {
|
|
31746
33681
|
if (isNoEntError(err))
|
|
31747
33682
|
return;
|
|
@@ -31779,14 +33714,15 @@ async function runStagedFlows(args) {
|
|
|
31779
33714
|
projectDir,
|
|
31780
33715
|
depsRoot: runtimeEnv.depsRoot,
|
|
31781
33716
|
runRoot: runStagingRoot(),
|
|
31782
|
-
onInstallStart: (depCount) => ctx.ui.info(runnerMessages.installingProjectDeps(depCount))
|
|
33717
|
+
onInstallStart: (depCount) => ctx.ui.info(runnerMessages.installingProjectDeps(depCount)),
|
|
33718
|
+
onTsconfigUnparsed: (dir) => ctx.ui.warn(runnerMessages.tsconfigUnparsedNotice(dir))
|
|
31783
33719
|
});
|
|
31784
33720
|
if (staged.outerHop.mode === "install") {
|
|
31785
33721
|
const log = ctx.log("runner");
|
|
31786
33722
|
for (const candidate of staged.outerHop.rejected) {
|
|
31787
33723
|
log.debug(runnerMessages.outerHopCandidateRejected(candidate.dir, candidate.missing));
|
|
31788
33724
|
}
|
|
31789
|
-
const ownModules = projectDir === undefined ? undefined :
|
|
33725
|
+
const ownModules = projectDir === undefined ? undefined : join47(projectDir, "node_modules");
|
|
31790
33726
|
const own = staged.outerHop.rejected.find((c) => c.dir === ownModules);
|
|
31791
33727
|
if (own !== undefined) {
|
|
31792
33728
|
ctx.ui.warn(runnerMessages.outerHopFallbackNotice(own.dir, own.missing));
|
|
@@ -31882,7 +33818,7 @@ async function chooseEnv(ctx, files, allEnvs) {
|
|
|
31882
33818
|
}
|
|
31883
33819
|
|
|
31884
33820
|
// src/commands/flows/hybridRunDefaults.ts
|
|
31885
|
-
import { join as
|
|
33821
|
+
import { join as join48, resolve as resolve10 } from "node:path";
|
|
31886
33822
|
|
|
31887
33823
|
// src/core/selectFlowFiles.ts
|
|
31888
33824
|
function selectFlowFiles(args) {
|
|
@@ -31987,7 +33923,7 @@ async function handleHybridFlowsRun(ctx, pattern, flags, options = {}) {
|
|
|
31987
33923
|
if (validation !== "ok") {
|
|
31988
33924
|
return { error: validation.error, exitCode: 2 };
|
|
31989
33925
|
}
|
|
31990
|
-
const envDir = resolve10(
|
|
33926
|
+
const envDir = resolve10(join48(".qawolf", flags.env));
|
|
31991
33927
|
const patternArgs = buildPatternArgs(pattern);
|
|
31992
33928
|
const globFlows = () => resolvedDeps.expandPatterns(patternArgs, envDir, ctx.log("flows"));
|
|
31993
33929
|
let files = await globFlows();
|
|
@@ -32183,12 +34119,12 @@ function registerFlowsCommand(program, signals, deps = { withResolvedEnv }) {
|
|
|
32183
34119
|
}
|
|
32184
34120
|
|
|
32185
34121
|
// src/domains/init/init.ts
|
|
32186
|
-
import { dirname as dirname14, join as
|
|
34122
|
+
import { dirname as dirname14, join as join50, relative as relative9 } from "node:path";
|
|
32187
34123
|
|
|
32188
34124
|
// src/domains/init/ensurePackageJson.ts
|
|
32189
|
-
import { join as
|
|
34125
|
+
import { join as join49 } from "node:path";
|
|
32190
34126
|
async function ensurePackageJson(ctx, yes, deps) {
|
|
32191
|
-
const pkgPath =
|
|
34127
|
+
const pkgPath = join49(deps.cwd, "package.json");
|
|
32192
34128
|
if (!await deps.fs.pathExists(pkgPath)) {
|
|
32193
34129
|
const confirmed = await ctx.ui.confirm(initMessages.createPackageJsonPrompt, { yes });
|
|
32194
34130
|
if (!confirmed.ok || !confirmed.value) {
|
|
@@ -32214,7 +34150,7 @@ async function ensurePackageJson(ctx, yes, deps) {
|
|
|
32214
34150
|
ctx.ui.warn(initMessages.packageJsonInvalidJson);
|
|
32215
34151
|
return;
|
|
32216
34152
|
}
|
|
32217
|
-
if (!
|
|
34153
|
+
if (!isRecord3(parsed)) {
|
|
32218
34154
|
ctx.ui.warn(initMessages.packageJsonNotAnObject);
|
|
32219
34155
|
return;
|
|
32220
34156
|
}
|
|
@@ -32265,14 +34201,14 @@ async function ensurePackageJson(ctx, yes, deps) {
|
|
|
32265
34201
|
ctx.ui.warn(initMessages.typeChanged(label));
|
|
32266
34202
|
}
|
|
32267
34203
|
}
|
|
32268
|
-
function
|
|
34204
|
+
function isRecord3(value) {
|
|
32269
34205
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32270
34206
|
}
|
|
32271
34207
|
function readSection(ctx, pkg, key) {
|
|
32272
34208
|
const value = pkg[key];
|
|
32273
34209
|
if (value === undefined)
|
|
32274
34210
|
return {};
|
|
32275
|
-
if (
|
|
34211
|
+
if (isRecord3(value))
|
|
32276
34212
|
return value;
|
|
32277
34213
|
ctx.ui.warn(initMessages.packageJsonMalformedSection(key));
|
|
32278
34214
|
return;
|
|
@@ -32314,9 +34250,9 @@ function makeDefaultInitDeps() {
|
|
|
32314
34250
|
async function handleInit(ctx, opts, deps = makeDefaultInitDeps()) {
|
|
32315
34251
|
ctx.ui.gap();
|
|
32316
34252
|
ctx.ui.intro(initMessages.title);
|
|
32317
|
-
const configPath =
|
|
32318
|
-
const flowPath =
|
|
32319
|
-
const gitignorePath =
|
|
34253
|
+
const configPath = join50(deps.cwd, "qawolf.config.ts");
|
|
34254
|
+
const flowPath = join50(deps.cwd, "src", "flows", "example.flow.ts");
|
|
34255
|
+
const gitignorePath = join50(deps.cwd, ".qawolf", ".gitignore");
|
|
32320
34256
|
await writeWithPrompt(ctx, configPath, qawolfConfigTs, opts.yes, deps);
|
|
32321
34257
|
await writeWithPrompt(ctx, flowPath, exampleFlowTs, opts.yes, deps);
|
|
32322
34258
|
await writeWithPrompt(ctx, gitignorePath, qawolfGitignore, opts.yes, deps);
|
|
@@ -32350,11 +34286,8 @@ Examples:
|
|
|
32350
34286
|
});
|
|
32351
34287
|
}
|
|
32352
34288
|
|
|
32353
|
-
// src/domains/install/android/index.ts
|
|
32354
|
-
import { parseExecutionTarget as parseExecutionTarget4 } from "@qawolf/flow-targets";
|
|
32355
|
-
|
|
32356
34289
|
// src/domains/install/android/avd.ts
|
|
32357
|
-
import { join as
|
|
34290
|
+
import { join as join51 } from "node:path";
|
|
32358
34291
|
async function installAvds(ctx, specs, deps) {
|
|
32359
34292
|
const sdkManagerPath = sdkManagerBin(deps.androidHome, deps.platform);
|
|
32360
34293
|
const avdManagerPath = avdManagerBin(deps.androidHome, deps.platform);
|
|
@@ -32364,7 +34297,7 @@ async function installAvds(ctx, specs, deps) {
|
|
|
32364
34297
|
if (versionResult.exitCode !== 0) {
|
|
32365
34298
|
throw new Error(installMessages.android.sdkmanagerNotFound(sdkManagerPath));
|
|
32366
34299
|
}
|
|
32367
|
-
const licenseFile =
|
|
34300
|
+
const licenseFile = join51(deps.androidHome, "licenses", "android-sdk-license");
|
|
32368
34301
|
if (deps.checkExists(licenseFile)) {
|
|
32369
34302
|
ctx.ui.info(installMessages.android.licensesAlreadyAccepted);
|
|
32370
34303
|
} else {
|
|
@@ -32379,7 +34312,7 @@ async function installAvds(ctx, specs, deps) {
|
|
|
32379
34312
|
for (const spec of specs) {
|
|
32380
34313
|
if (installedImages.has(spec.systemImage))
|
|
32381
34314
|
continue;
|
|
32382
|
-
const systemImg =
|
|
34315
|
+
const systemImg = join51(deps.androidHome, ...spec.systemImage.split(";"), "system.img");
|
|
32383
34316
|
if (deps.checkExists(systemImg)) {
|
|
32384
34317
|
ctx.ui.info(installMessages.android.systemImageAlreadyInstalled(spec.systemImage));
|
|
32385
34318
|
installedImages.add(spec.systemImage);
|
|
@@ -32492,7 +34425,7 @@ function buildAvdSpecs(targets, arch) {
|
|
|
32492
34425
|
const avdName = avdNameForTarget(target);
|
|
32493
34426
|
if (!avdName || seen.has(avdName))
|
|
32494
34427
|
continue;
|
|
32495
|
-
const parsed =
|
|
34428
|
+
const parsed = parseExecutionTarget(target);
|
|
32496
34429
|
if (parsed.platform !== "android")
|
|
32497
34430
|
continue;
|
|
32498
34431
|
const { deviceModel, androidVersion } = parsed.meta;
|
|
@@ -32820,14 +34753,14 @@ function parseKeyValueRecord(flag, pairs) {
|
|
|
32820
34753
|
}
|
|
32821
34754
|
return { ok: true, record };
|
|
32822
34755
|
}
|
|
32823
|
-
var
|
|
34756
|
+
var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32824
34757
|
function setAtPath(input, path, value) {
|
|
32825
34758
|
const leaf = path[path.length - 1];
|
|
32826
34759
|
if (leaf === undefined)
|
|
32827
34760
|
return;
|
|
32828
34761
|
const target = path.slice(0, -1).reduce((node, segment) => {
|
|
32829
34762
|
const existing = node[segment];
|
|
32830
|
-
const next =
|
|
34763
|
+
const next = isRecord4(existing) ? existing : {};
|
|
32831
34764
|
node[segment] = next;
|
|
32832
34765
|
return next;
|
|
32833
34766
|
}, input);
|
|
@@ -32881,6 +34814,8 @@ async function handlePublicApiCommand(ctx, spec, options) {
|
|
|
32881
34814
|
|
|
32882
34815
|
// src/domains/publicApi/skippedContracts.ts
|
|
32883
34816
|
var skippedContractNames = new Set([
|
|
34817
|
+
"agent.get",
|
|
34818
|
+
"agent.send",
|
|
32884
34819
|
"flow.list",
|
|
32885
34820
|
"runner.evaluateSnippet",
|
|
32886
34821
|
"runner.get",
|
|
@@ -32899,34 +34834,6 @@ var skippedContractNames = new Set([
|
|
|
32899
34834
|
"runner.terminate"
|
|
32900
34835
|
]);
|
|
32901
34836
|
|
|
32902
|
-
// src/commands/publicApi/environmentOptions.ts
|
|
32903
|
-
var optionEnvironmentVariables = new Map([
|
|
32904
|
-
["environmentId", "QAWOLF_ENVIRONMENT"],
|
|
32905
|
-
["public.run.create.aiTaskId", "QAWOLF_AI_TASK_ID"],
|
|
32906
|
-
["public.run.create.chatSessionId", "QAWOLF_CHAT_SESSION_ID"]
|
|
32907
|
-
]);
|
|
32908
|
-
function optionEnvironmentVariable(spec, path) {
|
|
32909
|
-
const dotted = path.join(".");
|
|
32910
|
-
return optionEnvironmentVariables.get(`${spec.trpcPath}.${dotted}`) ?? optionEnvironmentVariables.get(dotted);
|
|
32911
|
-
}
|
|
32912
|
-
var exclusiveOptions = new Map([
|
|
32913
|
-
["public.run.create", { keep: "aiTaskId", drop: "chatSessionId" }]
|
|
32914
|
-
]);
|
|
32915
|
-
function withoutExclusiveConflict(spec, command, options) {
|
|
32916
|
-
const pair = exclusiveOptions.get(spec.trpcPath);
|
|
32917
|
-
if (!pair)
|
|
32918
|
-
return options;
|
|
32919
|
-
if (options[pair.keep] === undefined || options[pair.drop] === undefined) {
|
|
32920
|
-
return options;
|
|
32921
|
-
}
|
|
32922
|
-
const fromEnvironment = (key) => command.getOptionValueSource(key) === "env";
|
|
32923
|
-
if (!fromEnvironment(pair.keep) && !fromEnvironment(pair.drop)) {
|
|
32924
|
-
return options;
|
|
32925
|
-
}
|
|
32926
|
-
const dropped = fromEnvironment(pair.drop) ? pair.drop : pair.keep;
|
|
32927
|
-
return Object.fromEntries(Object.entries(options).filter(([key]) => key !== dropped));
|
|
32928
|
-
}
|
|
32929
|
-
|
|
32930
34837
|
// src/commands/publicApi/index.ts
|
|
32931
34838
|
var groupDescriptions = {
|
|
32932
34839
|
run: "Trigger and manage QA Wolf runs on the platform"
|
|
@@ -33063,19 +34970,17 @@ function parseRunnerName(runnerName) {
|
|
|
33063
34970
|
|
|
33064
34971
|
// src/domains/interactiveRunner/resolveRunner.ts
|
|
33065
34972
|
var runnerIdEnvironmentVariable = "QAWOLF_RUNNER_ID";
|
|
33066
|
-
|
|
33067
|
-
|
|
33068
|
-
|
|
33069
|
-
|
|
33070
|
-
|
|
33071
|
-
|
|
33072
|
-
return deps.store.readDefaultRunnerId();
|
|
33073
|
-
}
|
|
34973
|
+
var chooseRunnerId = (runner, deps) => resolveIdFrom({
|
|
34974
|
+
env: deps.env,
|
|
34975
|
+
environmentVariable: runnerIdEnvironmentVariable,
|
|
34976
|
+
given: runner,
|
|
34977
|
+
readStored: deps.store.readDefaultRunnerId
|
|
34978
|
+
});
|
|
33074
34979
|
async function resolveRunner(ctx, options, deps) {
|
|
33075
34980
|
const chosen = await chooseRunnerId(options.runner, deps);
|
|
33076
34981
|
if (chosen !== undefined) {
|
|
33077
|
-
const parsed = parseRunnerId(chosen);
|
|
33078
|
-
return parsed.ok ? { runnerId: parsed.id, type: "resolved" } : {
|
|
34982
|
+
const parsed = parseRunnerId(chosen.id);
|
|
34983
|
+
return parsed.ok ? { runnerId: parsed.id, source: chosen.source, type: "resolved" } : {
|
|
33079
34984
|
error: parsed.error,
|
|
33080
34985
|
exitCode: exitCodes.invalidArgs,
|
|
33081
34986
|
type: "failed"
|
|
@@ -33096,12 +35001,32 @@ async function resolveRunner(ctx, options, deps) {
|
|
|
33096
35001
|
type: "failed"
|
|
33097
35002
|
};
|
|
33098
35003
|
}
|
|
33099
|
-
return {
|
|
35004
|
+
return {
|
|
35005
|
+
runnerId: launched.value.id,
|
|
35006
|
+
source: "launched",
|
|
35007
|
+
type: "launched",
|
|
35008
|
+
url: launched.value.url
|
|
35009
|
+
};
|
|
33100
35010
|
}
|
|
33101
35011
|
function announceRunner(ctx, resolved) {
|
|
33102
35012
|
if (resolved.type === "launched") {
|
|
33103
|
-
ctx.ui.info(interactiveRunnerMessages.launchedForCommand(resolved.runnerId));
|
|
35013
|
+
ctx.ui.info(interactiveRunnerMessages.launchedForCommand(resolved.runnerId, resolved.url));
|
|
35014
|
+
}
|
|
35015
|
+
}
|
|
35016
|
+
|
|
35017
|
+
// src/domains/interactiveRunner/runnerRequestFailure.ts
|
|
35018
|
+
function runnerRequestFailure(failure, runner) {
|
|
35019
|
+
const fields = failureFields(failure);
|
|
35020
|
+
if (failure.exitCode !== exitCodes.notFound) {
|
|
35021
|
+
return { ...fields, exitCode: failure.exitCode ?? exitCodes.network };
|
|
33104
35022
|
}
|
|
35023
|
+
const cameFrom = interactiveRunnerMessages.runnerIdCameFrom(runner.runnerId, runner.source);
|
|
35024
|
+
return {
|
|
35025
|
+
...fields,
|
|
35026
|
+
errorBody: fields.errorBody ? `${fields.errorBody}
|
|
35027
|
+
${cameFrom}` : cameFrom,
|
|
35028
|
+
exitCode: exitCodes.notFound
|
|
35029
|
+
};
|
|
33105
35030
|
}
|
|
33106
35031
|
|
|
33107
35032
|
// src/core/interactiveRunner/runFiles.ts
|
|
@@ -33215,10 +35140,7 @@ async function handleRunnerExec(ctx, options, deps) {
|
|
|
33215
35140
|
...scope.files === undefined ? {} : { files: scope.files }
|
|
33216
35141
|
}, runnerCallOptions);
|
|
33217
35142
|
if (!result.ok) {
|
|
33218
|
-
return
|
|
33219
|
-
...failureFields(result),
|
|
33220
|
-
exitCode: result.exitCode ?? exitCodes.network
|
|
33221
|
-
};
|
|
35143
|
+
return runnerRequestFailure(result, resolved);
|
|
33222
35144
|
}
|
|
33223
35145
|
if (result.value.outcome === "failure") {
|
|
33224
35146
|
return describeEvaluateSnippetFailure(result.value);
|
|
@@ -33241,7 +35163,7 @@ async function handleRunnerExec(ctx, options, deps) {
|
|
|
33241
35163
|
}
|
|
33242
35164
|
|
|
33243
35165
|
// src/shell/interactiveRunner/collectRunFiles.ts
|
|
33244
|
-
import { join as
|
|
35166
|
+
import { join as join53 } from "node:path";
|
|
33245
35167
|
|
|
33246
35168
|
// src/core/interactiveRunner/getImports.ts
|
|
33247
35169
|
function getImports(options) {
|
|
@@ -33280,46 +35202,7 @@ function isPathAlias(importPath, paths) {
|
|
|
33280
35202
|
}
|
|
33281
35203
|
|
|
33282
35204
|
// src/core/interactiveRunner/resolveImportPath.ts
|
|
33283
|
-
import { dirname as dirname15, join as
|
|
33284
|
-
|
|
33285
|
-
// src/core/interactiveRunner/tsconfigPaths.ts
|
|
33286
|
-
function isRecord4(value) {
|
|
33287
|
-
return typeof value === "object" && value !== null;
|
|
33288
|
-
}
|
|
33289
|
-
function isTsconfigPaths(value) {
|
|
33290
|
-
return isRecord4(value) && Object.values(value).every((targets) => Array.isArray(targets) && targets.every((target) => typeof target === "string"));
|
|
33291
|
-
}
|
|
33292
|
-
function parseTsconfigPaths(tsconfigContent) {
|
|
33293
|
-
let parsed;
|
|
33294
|
-
try {
|
|
33295
|
-
parsed = JSON.parse(tsconfigContent);
|
|
33296
|
-
} catch {
|
|
33297
|
-
return;
|
|
33298
|
-
}
|
|
33299
|
-
if (!isRecord4(parsed))
|
|
33300
|
-
return;
|
|
33301
|
-
const compilerOptions = parsed["compilerOptions"];
|
|
33302
|
-
if (!isRecord4(compilerOptions))
|
|
33303
|
-
return;
|
|
33304
|
-
const paths = compilerOptions["paths"];
|
|
33305
|
-
return isTsconfigPaths(paths) ? paths : undefined;
|
|
33306
|
-
}
|
|
33307
|
-
function resolvePathAlias(importPath, paths) {
|
|
33308
|
-
if (paths === undefined)
|
|
33309
|
-
return;
|
|
33310
|
-
for (const [pattern, targets] of Object.entries(paths)) {
|
|
33311
|
-
const prefix = pattern.replace("*", "");
|
|
33312
|
-
if (!importPath.startsWith(prefix))
|
|
33313
|
-
continue;
|
|
33314
|
-
const [target] = targets;
|
|
33315
|
-
if (target !== undefined) {
|
|
33316
|
-
return target.replace("*", importPath.slice(prefix.length));
|
|
33317
|
-
}
|
|
33318
|
-
}
|
|
33319
|
-
return;
|
|
33320
|
-
}
|
|
33321
|
-
|
|
33322
|
-
// src/core/interactiveRunner/resolveImportPath.ts
|
|
35205
|
+
import { dirname as dirname15, join as join52, normalize as normalize3 } from "node:path/posix";
|
|
33323
35206
|
var supportedExtensions = [".ts", ".js"];
|
|
33324
35207
|
function candidatesForExplicitExtension(options) {
|
|
33325
35208
|
const matching = supportedExtensions.find((extension) => options.importPath.endsWith(extension));
|
|
@@ -33333,7 +35216,7 @@ function candidatesForExplicitExtension(options) {
|
|
|
33333
35216
|
}
|
|
33334
35217
|
function resolveImportPath(options) {
|
|
33335
35218
|
const aliasTarget = resolvePathAlias(options.importPath, options.tsconfigPaths);
|
|
33336
|
-
const resolvedPath = aliasTarget === undefined ? normalize3(
|
|
35219
|
+
const resolvedPath = aliasTarget === undefined ? normalize3(join52(dirname15(options.importingFilePath), options.importPath)) : normalize3(aliasTarget);
|
|
33337
35220
|
const hasExplicitExtension = supportedExtensions.some((extension) => options.importPath.endsWith(extension));
|
|
33338
35221
|
const candidates = hasExplicitExtension ? candidatesForExplicitExtension({
|
|
33339
35222
|
importPath: options.importPath,
|
|
@@ -33357,7 +35240,7 @@ function resolveImportPath(options) {
|
|
|
33357
35240
|
var tsconfigPath = "tsconfig.json";
|
|
33358
35241
|
async function collectRunFiles(options) {
|
|
33359
35242
|
const held = await listShippablePaths(options);
|
|
33360
|
-
const readFile = (path) => options.fs.readFile(
|
|
35243
|
+
const readFile = (path) => options.fs.readFile(join53(options.cwd, path));
|
|
33361
35244
|
const tsconfigContent = held.has(tsconfigPath) ? await readFile(tsconfigPath).catch(() => {
|
|
33362
35245
|
return;
|
|
33363
35246
|
}) : undefined;
|
|
@@ -33440,7 +35323,7 @@ function makeRunnerId() {
|
|
|
33440
35323
|
}
|
|
33441
35324
|
|
|
33442
35325
|
// src/shell/interactiveRunner/runFilesManifest.ts
|
|
33443
|
-
import { join as
|
|
35326
|
+
import { join as join54 } from "node:path";
|
|
33444
35327
|
var manifestFileName = "runner-files.json";
|
|
33445
35328
|
var manifestSchema2 = object({
|
|
33446
35329
|
files: array(object({ contentHash: string2(), path: string2() })),
|
|
@@ -33448,75 +35331,37 @@ var manifestSchema2 = object({
|
|
|
33448
35331
|
version: literal(1)
|
|
33449
35332
|
});
|
|
33450
35333
|
function makeRunFilesManifestStore(options) {
|
|
33451
|
-
const directory =
|
|
33452
|
-
const path =
|
|
33453
|
-
let pendingWrites = 0;
|
|
35334
|
+
const directory = join54(options.cwd, qawolfDir);
|
|
35335
|
+
const path = join54(directory, manifestFileName);
|
|
33454
35336
|
return {
|
|
33455
|
-
|
|
33456
|
-
const contents = await options.fs.readFile(path).catch(() => {
|
|
33457
|
-
return;
|
|
33458
|
-
});
|
|
33459
|
-
if (contents === undefined)
|
|
33460
|
-
return;
|
|
33461
|
-
const parsed = manifestSchema2.safeParse(parseJson(contents));
|
|
33462
|
-
return parsed.success ? parsed.data : undefined;
|
|
33463
|
-
},
|
|
35337
|
+
read: () => readJsonFile(options.fs, path, manifestSchema2),
|
|
33464
35338
|
async write(manifest) {
|
|
33465
|
-
const pendingPath = `${path}.${String(process.pid)}.${String(++pendingWrites)}.tmp`;
|
|
33466
35339
|
await options.fs.mkdir(directory, { recursive: true });
|
|
33467
|
-
await options.fs
|
|
33468
|
-
`);
|
|
33469
|
-
await options.fs.rename(pendingPath, path);
|
|
35340
|
+
await writeJsonFileAtomically(options.fs, path, manifest);
|
|
33470
35341
|
}
|
|
33471
35342
|
};
|
|
33472
35343
|
}
|
|
33473
|
-
function parseJson(text) {
|
|
33474
|
-
try {
|
|
33475
|
-
return JSON.parse(text);
|
|
33476
|
-
} catch {
|
|
33477
|
-
return;
|
|
33478
|
-
}
|
|
33479
|
-
}
|
|
33480
35344
|
|
|
33481
35345
|
// src/shell/interactiveRunner/runnerStore.ts
|
|
33482
|
-
import { join as
|
|
33483
|
-
var
|
|
35346
|
+
import { join as join55 } from "node:path";
|
|
35347
|
+
var storeFileName2 = "runner.json";
|
|
33484
35348
|
var runnersDirName = "runners";
|
|
33485
35349
|
var storedRunnerSchema = object({
|
|
33486
35350
|
id: string2(),
|
|
33487
35351
|
runnerName: string2().optional()
|
|
33488
35352
|
});
|
|
33489
|
-
var
|
|
35353
|
+
var storeSchema2 = object({
|
|
33490
35354
|
defaultRunnerId: string2().optional()
|
|
33491
35355
|
});
|
|
33492
|
-
function parseJson2(text) {
|
|
33493
|
-
try {
|
|
33494
|
-
return JSON.parse(text);
|
|
33495
|
-
} catch {
|
|
33496
|
-
return;
|
|
33497
|
-
}
|
|
33498
|
-
}
|
|
33499
|
-
var pendingWrites = 0;
|
|
33500
35356
|
function makeRunnerStore(options) {
|
|
33501
|
-
const directory =
|
|
33502
|
-
const path =
|
|
33503
|
-
const runnersDir =
|
|
33504
|
-
const
|
|
33505
|
-
const
|
|
33506
|
-
const writeAtomically = async (target, contents) => {
|
|
33507
|
-
const pendingPath = nextPendingPath(target);
|
|
33508
|
-
await options.fs.writeFile(pendingPath, `${JSON.stringify(contents, undefined, 2)}
|
|
33509
|
-
`);
|
|
33510
|
-
await options.fs.rename(pendingPath, target);
|
|
33511
|
-
};
|
|
35357
|
+
const directory = join55(options.cwd, qawolfDir);
|
|
35358
|
+
const path = join55(directory, storeFileName2);
|
|
35359
|
+
const runnersDir = join55(directory, runnersDirName);
|
|
35360
|
+
const runnerPath = (runnerId) => join55(runnersDir, `${encodeURIComponent(runnerId)}.json`);
|
|
35361
|
+
const writeAtomically = (target, contents) => writeJsonFileAtomically(options.fs, target, contents);
|
|
33512
35362
|
const readDefaultRunnerId = async () => {
|
|
33513
|
-
const
|
|
33514
|
-
|
|
33515
|
-
});
|
|
33516
|
-
if (contents === undefined)
|
|
33517
|
-
return;
|
|
33518
|
-
const parsed = storeSchema.safeParse(parseJson2(contents));
|
|
33519
|
-
return parsed.success ? parsed.data.defaultRunnerId : undefined;
|
|
35363
|
+
const stored = await readJsonFile(options.fs, path, storeSchema2);
|
|
35364
|
+
return stored?.defaultRunnerId;
|
|
33520
35365
|
};
|
|
33521
35366
|
const writeDefaultRunnerId = async (runnerId) => {
|
|
33522
35367
|
await options.fs.mkdir(directory, { recursive: true });
|
|
@@ -33538,15 +35383,7 @@ function makeRunnerStore(options) {
|
|
|
33538
35383
|
},
|
|
33539
35384
|
readDefaultRunnerId,
|
|
33540
35385
|
async readRunners() {
|
|
33541
|
-
const runners = await Promise.all((await readRunnerFileNames()).map(
|
|
33542
|
-
const contents = await options.fs.readFile(join53(runnersDir, name)).catch(() => {
|
|
33543
|
-
return;
|
|
33544
|
-
});
|
|
33545
|
-
if (contents === undefined)
|
|
33546
|
-
return;
|
|
33547
|
-
const parsed = storedRunnerSchema.safeParse(parseJson2(contents));
|
|
33548
|
-
return parsed.success ? parsed.data : undefined;
|
|
33549
|
-
}));
|
|
35386
|
+
const runners = await Promise.all((await readRunnerFileNames()).map((name) => readJsonFile(options.fs, join55(runnersDir, name), storedRunnerSchema)));
|
|
33550
35387
|
return runners.filter((runner) => !!runner).sort((left, right) => left.id.localeCompare(right.id));
|
|
33551
35388
|
},
|
|
33552
35389
|
async rememberLaunch(runner) {
|
|
@@ -33558,13 +35395,13 @@ function makeRunnerStore(options) {
|
|
|
33558
35395
|
await Promise.all(runnerIds.map((runnerId) => options.fs.rm(runnerPath(runnerId), { force: true })));
|
|
33559
35396
|
const names = await readRunnerFileNames();
|
|
33560
35397
|
await Promise.all(names.map(async (name) => {
|
|
33561
|
-
const runnerFile =
|
|
35398
|
+
const runnerFile = join55(runnersDir, name);
|
|
33562
35399
|
const contents = await options.fs.readFile(runnerFile).catch(() => {
|
|
33563
35400
|
return;
|
|
33564
35401
|
});
|
|
33565
35402
|
if (contents === undefined)
|
|
33566
35403
|
return;
|
|
33567
|
-
if (storedRunnerSchema.safeParse(
|
|
35404
|
+
if (storedRunnerSchema.safeParse(parseJson(contents)).success)
|
|
33568
35405
|
return;
|
|
33569
35406
|
await options.fs.rm(runnerFile, { force: true });
|
|
33570
35407
|
}));
|
|
@@ -33673,7 +35510,7 @@ async function handleRunnerHighlightSelector(ctx, options, deps) {
|
|
|
33673
35510
|
const selector = options.selector ?? "";
|
|
33674
35511
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.highlightSelector, { id: resolved.runnerId, selector }, runnerCallOptions);
|
|
33675
35512
|
if (!result.ok) {
|
|
33676
|
-
return
|
|
35513
|
+
return runnerRequestFailure(result, resolved);
|
|
33677
35514
|
}
|
|
33678
35515
|
const { outcome } = result.value;
|
|
33679
35516
|
switch (outcome) {
|
|
@@ -33736,7 +35573,7 @@ function registerRunnerHighlightSelectorCommand(runner, signals) {
|
|
|
33736
35573
|
}
|
|
33737
35574
|
|
|
33738
35575
|
// src/domains/interactiveRunner/importPackage.ts
|
|
33739
|
-
import { join as
|
|
35576
|
+
import { join as join56 } from "node:path";
|
|
33740
35577
|
|
|
33741
35578
|
// src/core/interactiveRunner/npmDependencies.ts
|
|
33742
35579
|
var sectionsInPrecedenceOrder = ["dependencies", "devDependencies"];
|
|
@@ -33777,7 +35614,7 @@ function readNpmDependencies(packageJsonContent) {
|
|
|
33777
35614
|
// src/domains/interactiveRunner/importPackage.ts
|
|
33778
35615
|
var defaultPackageVersion = "latest";
|
|
33779
35616
|
async function handleRunnerImportPackage(ctx, options, deps) {
|
|
33780
|
-
const content = await deps.readFile(
|
|
35617
|
+
const content = await deps.readFile(join56(deps.cwd, runPackageJsonPath)).catch(() => {
|
|
33781
35618
|
return;
|
|
33782
35619
|
});
|
|
33783
35620
|
if (content === undefined) {
|
|
@@ -33809,10 +35646,7 @@ async function handleRunnerImportPackage(ctx, options, deps) {
|
|
|
33809
35646
|
packageVersion
|
|
33810
35647
|
}, runnerCallOptions);
|
|
33811
35648
|
if (!result.ok) {
|
|
33812
|
-
return
|
|
33813
|
-
...failureFields(result),
|
|
33814
|
-
exitCode: result.exitCode ?? exitCodes.network
|
|
33815
|
-
};
|
|
35649
|
+
return runnerRequestFailure(result, resolved);
|
|
33816
35650
|
}
|
|
33817
35651
|
if (result.value.outcome === "failure") {
|
|
33818
35652
|
const failure = result.value;
|
|
@@ -33879,7 +35713,7 @@ async function handleRunnerInspect(ctx, options, deps) {
|
|
|
33879
35713
|
}
|
|
33880
35714
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.inspect, { id: resolved.runnerId, request: built.request }, runnerCallOptions);
|
|
33881
35715
|
if (!result.ok) {
|
|
33882
|
-
return
|
|
35716
|
+
return runnerRequestFailure(result, resolved);
|
|
33883
35717
|
}
|
|
33884
35718
|
if (result.value.outcome === "failure") {
|
|
33885
35719
|
const failure = result.value;
|
|
@@ -34014,7 +35848,7 @@ async function handleRunnerInspectMobile(ctx, options, deps) {
|
|
|
34014
35848
|
}
|
|
34015
35849
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.inspectMobile, { id: resolved.runnerId, request: built.request }, runnerCallOptions);
|
|
34016
35850
|
if (!result.ok) {
|
|
34017
|
-
return
|
|
35851
|
+
return runnerRequestFailure(result, resolved);
|
|
34018
35852
|
}
|
|
34019
35853
|
if (result.value.outcome === "success") {
|
|
34020
35854
|
const value = result.value;
|
|
@@ -34306,14 +36140,11 @@ async function handleRunnerAct(ctx, options, deps) {
|
|
|
34306
36140
|
...options.screenshot === undefined ? {} : { withScreenshot: true }
|
|
34307
36141
|
}, runnerCallOptions);
|
|
34308
36142
|
if (!result.ok) {
|
|
34309
|
-
const fields =
|
|
34310
|
-
return {
|
|
36143
|
+
const fields = runnerRequestFailure(result, resolved);
|
|
36144
|
+
return result.mayHaveArrived ? {
|
|
34311
36145
|
...fields,
|
|
34312
|
-
|
|
34313
|
-
|
|
34314
|
-
} : {},
|
|
34315
|
-
exitCode: exitCodes.network
|
|
34316
|
-
};
|
|
36146
|
+
error: appendSentence(fields.error, interactiveRunnerMessages.actionMayHaveHappened)
|
|
36147
|
+
} : fields;
|
|
34317
36148
|
}
|
|
34318
36149
|
const answer = result.value;
|
|
34319
36150
|
if (answer.outcome === "success") {
|
|
@@ -34358,9 +36189,8 @@ async function handleRunnerScreenshot(ctx, options, deps) {
|
|
|
34358
36189
|
};
|
|
34359
36190
|
}
|
|
34360
36191
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.takeScreenshot, { id: resolved.runnerId }, runnerCallOptions);
|
|
34361
|
-
if (!result.ok)
|
|
34362
|
-
return
|
|
34363
|
-
}
|
|
36192
|
+
if (!result.ok)
|
|
36193
|
+
return runnerRequestFailure(result, resolved);
|
|
34364
36194
|
if (result.value.outcome === "success") {
|
|
34365
36195
|
const written = await deps.writeScreenshot({
|
|
34366
36196
|
imageJpegBase64: result.value.imageJpegBase64,
|
|
@@ -34465,20 +36295,16 @@ var unreachableFailure = {
|
|
|
34465
36295
|
error: interactiveRunnerMessages.runnerUnreachable,
|
|
34466
36296
|
exitCode: exitCodes.network
|
|
34467
36297
|
};
|
|
34468
|
-
async function readJournal(ctx,
|
|
36298
|
+
async function readJournal(ctx, runner, request) {
|
|
34469
36299
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.readJournal, {
|
|
34470
|
-
id: runnerId,
|
|
36300
|
+
id: runner.runnerId,
|
|
34471
36301
|
stream: request.stream,
|
|
34472
36302
|
...request.runId === undefined ? {} : { runId: request.runId },
|
|
34473
36303
|
...request.sinceSequence === undefined ? {} : { sinceSequence: request.sinceSequence },
|
|
34474
36304
|
...request.tail === undefined ? {} : { tail: request.tail }
|
|
34475
36305
|
}, runnerCallOptions);
|
|
34476
36306
|
if (!result.ok) {
|
|
34477
|
-
return {
|
|
34478
|
-
...failureFields(result),
|
|
34479
|
-
exitCode: exitCodes.network,
|
|
34480
|
-
type: "failed"
|
|
34481
|
-
};
|
|
36307
|
+
return { ...runnerRequestFailure(result, runner), type: "failed" };
|
|
34482
36308
|
}
|
|
34483
36309
|
if (result.value.outcome === "failure") {
|
|
34484
36310
|
result.value.failureReason;
|
|
@@ -34493,7 +36319,7 @@ async function handleRunnerKeepalive(ctx, options, deps) {
|
|
|
34493
36319
|
if (resolved.type === "failed") {
|
|
34494
36320
|
return { ...failureFields(resolved), exitCode: resolved.exitCode };
|
|
34495
36321
|
}
|
|
34496
|
-
const window = await readJournal(ctx, resolved
|
|
36322
|
+
const window = await readJournal(ctx, resolved, {
|
|
34497
36323
|
stream: "run-status",
|
|
34498
36324
|
tail: 1
|
|
34499
36325
|
});
|
|
@@ -34523,7 +36349,8 @@ async function handleRunnerLaunch(ctx, options, deps) {
|
|
|
34523
36349
|
if (envRunnerId && envRunnerId !== launched.value.id) {
|
|
34524
36350
|
ctx.ui.warn(interactiveRunnerMessages.envRunnerIdShadowsLaunch(launched.value.id, envRunnerId));
|
|
34525
36351
|
}
|
|
34526
|
-
|
|
36352
|
+
const runner = launched.value;
|
|
36353
|
+
ctx.ui.output(runner, runner.alreadyRunning ? interactiveRunnerMessages.alreadyRunning(runner.id, runner.url) : interactiveRunnerMessages.launched(runner.id, runner.url));
|
|
34527
36354
|
return;
|
|
34528
36355
|
}
|
|
34529
36356
|
|
|
@@ -34561,7 +36388,8 @@ async function listRunners(ctx, deps) {
|
|
|
34561
36388
|
id: runner.id,
|
|
34562
36389
|
isDefault: runner.id === defaultRunnerId,
|
|
34563
36390
|
launchedHere: heldIds.has(runner.id),
|
|
34564
|
-
runnerName: runner.runnerName
|
|
36391
|
+
runnerName: runner.runnerName,
|
|
36392
|
+
url: runner.url
|
|
34565
36393
|
}));
|
|
34566
36394
|
return {
|
|
34567
36395
|
items: items.sort((left, right) => rank(left) - rank(right) || left.id.localeCompare(right.id)),
|
|
@@ -34600,7 +36428,7 @@ async function handleRunnerStopRun(ctx, options, deps) {
|
|
|
34600
36428
|
}
|
|
34601
36429
|
const result = await ctx.platformClient.callPublicApi(publicContractsV1.runner.stopRun, { id: resolved.runnerId }, runnerCallOptions);
|
|
34602
36430
|
if (!result.ok) {
|
|
34603
|
-
return
|
|
36431
|
+
return runnerRequestFailure(result, resolved);
|
|
34604
36432
|
}
|
|
34605
36433
|
if (result.value.outcome === "failure") {
|
|
34606
36434
|
result.value.failureReason;
|
|
@@ -34623,7 +36451,7 @@ async function handleRunnerTerminate(ctx, options, deps) {
|
|
|
34623
36451
|
id: resolved.runnerId
|
|
34624
36452
|
}, runnerCallOptions);
|
|
34625
36453
|
if (!result.ok) {
|
|
34626
|
-
return
|
|
36454
|
+
return runnerRequestFailure(result, resolved);
|
|
34627
36455
|
}
|
|
34628
36456
|
await deps.store.forgetRunner(resolved.runnerId).catch(() => {
|
|
34629
36457
|
ctx.ui.warn(interactiveRunnerMessages.defaultNotForgotten(resolved.runnerId));
|
|
@@ -34671,7 +36499,7 @@ async function handleRunnerPromoteSnapshot(ctx, options, deps) {
|
|
|
34671
36499
|
screenshotPath: options.screenshotPath
|
|
34672
36500
|
}, runnerCallOptions);
|
|
34673
36501
|
if (!result.ok) {
|
|
34674
|
-
return
|
|
36502
|
+
return runnerRequestFailure(result, resolved);
|
|
34675
36503
|
}
|
|
34676
36504
|
if (result.value.outcome === "success") {
|
|
34677
36505
|
ctx.ui.output(result.value, interactiveRunnerMessages.snapshotPromoted(options.screenshotPath, options.baselinePath));
|
|
@@ -34718,16 +36546,6 @@ function registerRunnerPromoteSnapshotCommand(runner, signals) {
|
|
|
34718
36546
|
|
|
34719
36547
|
// src/core/interactiveRunner/followTimeout.ts
|
|
34720
36548
|
var defaultFollowTimeoutSeconds = 3600;
|
|
34721
|
-
var followTimeoutSchema = exports_coerce.number().int().positive();
|
|
34722
|
-
function parseFollowTimeout(seconds) {
|
|
34723
|
-
if (seconds === undefined) {
|
|
34724
|
-
return { ok: true, seconds: defaultFollowTimeoutSeconds };
|
|
34725
|
-
}
|
|
34726
|
-
const parsed = followTimeoutSchema.safeParse(seconds);
|
|
34727
|
-
if (!parsed.success)
|
|
34728
|
-
return { error: prettifyError(parsed.error), ok: false };
|
|
34729
|
-
return { ok: true, seconds: parsed.data };
|
|
34730
|
-
}
|
|
34731
36549
|
|
|
34732
36550
|
// src/core/interactiveRunner/journal.ts
|
|
34733
36551
|
function formatJournalLine(entry, options) {
|
|
@@ -34805,12 +36623,12 @@ function parseEventsOptions(options) {
|
|
|
34805
36623
|
}
|
|
34806
36624
|
|
|
34807
36625
|
// src/domains/interactiveRunner/journalCursor.ts
|
|
34808
|
-
function createJournalCursor(ctx,
|
|
36626
|
+
function createJournalCursor(ctx, runner, request) {
|
|
34809
36627
|
let sinceSequence = request.sinceSequence;
|
|
34810
36628
|
let tail = request.tail;
|
|
34811
36629
|
let warnedUnsearchedHistory = false;
|
|
34812
36630
|
return async function read() {
|
|
34813
|
-
const window = await readJournal(ctx,
|
|
36631
|
+
const window = await readJournal(ctx, runner, {
|
|
34814
36632
|
...request,
|
|
34815
36633
|
sinceSequence,
|
|
34816
36634
|
tail
|
|
@@ -34832,8 +36650,8 @@ function createJournalCursor(ctx, runnerId, request) {
|
|
|
34832
36650
|
return { entries: window.value.entries, type: "entries" };
|
|
34833
36651
|
};
|
|
34834
36652
|
}
|
|
34835
|
-
function createPrintingCursor(ctx,
|
|
34836
|
-
const read = createJournalCursor(ctx,
|
|
36653
|
+
function createPrintingCursor(ctx, runner, request, format) {
|
|
36654
|
+
const read = createJournalCursor(ctx, runner, request);
|
|
34837
36655
|
return async () => {
|
|
34838
36656
|
const window = await read();
|
|
34839
36657
|
if (window.type !== "entries")
|
|
@@ -34857,12 +36675,12 @@ function createUnreachableBudget(pollIntervalMs) {
|
|
|
34857
36675
|
}
|
|
34858
36676
|
|
|
34859
36677
|
// src/domains/interactiveRunner/events.ts
|
|
34860
|
-
var
|
|
36678
|
+
var pollIntervalMs3 = 1000;
|
|
34861
36679
|
async function handleRunnerEvents(ctx, options, deps) {
|
|
34862
36680
|
const parsed = parseEventsOptions(options);
|
|
34863
36681
|
if (!parsed.ok)
|
|
34864
36682
|
return { error: parsed.error, exitCode: exitCodes.invalidArgs };
|
|
34865
|
-
const timeout = parseFollowTimeout(options.timeout);
|
|
36683
|
+
const timeout = parseFollowTimeout(options.timeout, defaultFollowTimeoutSeconds);
|
|
34866
36684
|
if (!timeout.ok) {
|
|
34867
36685
|
return { error: timeout.error, exitCode: exitCodes.invalidArgs };
|
|
34868
36686
|
}
|
|
@@ -34874,9 +36692,9 @@ async function handleRunnerEvents(ctx, options, deps) {
|
|
|
34874
36692
|
if (!known.includes(parsed.value.stream)) {
|
|
34875
36693
|
ctx.ui.warn(interactiveRunnerMessages.unknownStream(parsed.value.stream, known));
|
|
34876
36694
|
}
|
|
34877
|
-
const read = createJournalCursor(ctx, resolved
|
|
34878
|
-
const unreachable = createUnreachableBudget(
|
|
34879
|
-
const maxPolls = Math.max(1, Math.ceil(timeout.seconds * 1000 /
|
|
36695
|
+
const read = createJournalCursor(ctx, resolved, parsed.value);
|
|
36696
|
+
const unreachable = createUnreachableBudget(pollIntervalMs3);
|
|
36697
|
+
const maxPolls = Math.max(1, Math.ceil(timeout.seconds * 1000 / pollIntervalMs3));
|
|
34880
36698
|
for (let poll = 1;; poll++) {
|
|
34881
36699
|
const window = await read();
|
|
34882
36700
|
if (window.type === "failed")
|
|
@@ -34902,7 +36720,7 @@ async function handleRunnerEvents(ctx, options, deps) {
|
|
|
34902
36720
|
exitCode: exitCodes.timeout
|
|
34903
36721
|
};
|
|
34904
36722
|
}
|
|
34905
|
-
await deps.sleep(
|
|
36723
|
+
await deps.sleep(pollIntervalMs3);
|
|
34906
36724
|
}
|
|
34907
36725
|
}
|
|
34908
36726
|
|
|
@@ -34930,12 +36748,12 @@ var anchorPollIntervalMs = 1000;
|
|
|
34930
36748
|
async function resolveRecorderAnchor(ctx, resolved, deps) {
|
|
34931
36749
|
if (resolved.type === "launched")
|
|
34932
36750
|
return { ok: true, sinceSequence: 0 };
|
|
34933
|
-
return anchorRecorderCursor(ctx, resolved
|
|
36751
|
+
return anchorRecorderCursor(ctx, resolved, deps);
|
|
34934
36752
|
}
|
|
34935
|
-
async function anchorRecorderCursor(ctx,
|
|
36753
|
+
async function anchorRecorderCursor(ctx, runner, deps) {
|
|
34936
36754
|
const unreachable = createUnreachableBudget(anchorPollIntervalMs);
|
|
34937
36755
|
for (;; ) {
|
|
34938
|
-
const anchor = await readJournal(ctx,
|
|
36756
|
+
const anchor = await readJournal(ctx, runner, {
|
|
34939
36757
|
stream: "recorder",
|
|
34940
36758
|
tail: 1
|
|
34941
36759
|
});
|
|
@@ -34955,20 +36773,20 @@ function createFollowPrinters(ctx, options) {
|
|
|
34955
36773
|
const jsonLine = (payload) => JSON.stringify(payload);
|
|
34956
36774
|
const printers = [];
|
|
34957
36775
|
if (options.logs) {
|
|
34958
|
-
printers.push(createPrintingCursor(ctx, options.
|
|
36776
|
+
printers.push(createPrintingCursor(ctx, options.runner, { runId: options.runId, stream: "run-logs" }, formatRunLogLine));
|
|
34959
36777
|
}
|
|
34960
36778
|
if (options.runEvents) {
|
|
34961
|
-
printers.push(createPrintingCursor(ctx, options.
|
|
36779
|
+
printers.push(createPrintingCursor(ctx, options.runner, { runId: options.runId, stream: "run-events" }, jsonLine));
|
|
34962
36780
|
}
|
|
34963
36781
|
if (options.recorderSinceSequence !== undefined) {
|
|
34964
|
-
printers.push(createPrintingCursor(ctx, options.
|
|
36782
|
+
printers.push(createPrintingCursor(ctx, options.runner, { sinceSequence: options.recorderSinceSequence, stream: "recorder" }, jsonLine));
|
|
34965
36783
|
}
|
|
34966
36784
|
return printers;
|
|
34967
36785
|
}
|
|
34968
36786
|
|
|
34969
36787
|
// src/domains/interactiveRunner/followRun.ts
|
|
34970
|
-
var
|
|
34971
|
-
function
|
|
36788
|
+
var pollIntervalMs4 = 1000;
|
|
36789
|
+
function reportSettlement2(ctx, settlement) {
|
|
34972
36790
|
if (settlement.type === "passed") {
|
|
34973
36791
|
ctx.ui.success(interactiveRunnerMessages.runPassed);
|
|
34974
36792
|
return;
|
|
@@ -34980,11 +36798,11 @@ function reportSettlement(ctx, settlement) {
|
|
|
34980
36798
|
}
|
|
34981
36799
|
async function followRun(ctx, options, deps) {
|
|
34982
36800
|
const printers = createFollowPrinters(ctx, options);
|
|
34983
|
-
const readStatus = createJournalCursor(ctx, options.
|
|
36801
|
+
const readStatus = createJournalCursor(ctx, options.runner, {
|
|
34984
36802
|
runId: options.runId,
|
|
34985
36803
|
stream: "run-status"
|
|
34986
36804
|
});
|
|
34987
|
-
const unreachable = createUnreachableBudget(
|
|
36805
|
+
const unreachable = createUnreachableBudget(pollIntervalMs4);
|
|
34988
36806
|
const printAll = async () => {
|
|
34989
36807
|
for (const print of printers) {
|
|
34990
36808
|
const window = await print();
|
|
@@ -35003,7 +36821,7 @@ async function followRun(ctx, options, deps) {
|
|
|
35003
36821
|
progressReported = true;
|
|
35004
36822
|
ctx.ui.stream(entry, interactiveRunnerMessages.runInProgress);
|
|
35005
36823
|
};
|
|
35006
|
-
const maxPolls = Math.max(1, Math.ceil(options.timeoutSeconds * 1000 /
|
|
36824
|
+
const maxPolls = Math.max(1, Math.ceil(options.timeoutSeconds * 1000 / pollIntervalMs4));
|
|
35007
36825
|
for (let poll = 1;; poll++) {
|
|
35008
36826
|
const interrupted = await printAll();
|
|
35009
36827
|
if (interrupted?.type === "failed")
|
|
@@ -35022,16 +36840,16 @@ async function followRun(ctx, options, deps) {
|
|
|
35022
36840
|
if (await printAll() !== undefined) {
|
|
35023
36841
|
ctx.ui.warn(interactiveRunnerMessages.followEndCutShort);
|
|
35024
36842
|
}
|
|
35025
|
-
return
|
|
36843
|
+
return reportSettlement2(ctx, settlement);
|
|
35026
36844
|
}
|
|
35027
36845
|
}
|
|
35028
36846
|
if (poll >= maxPolls) {
|
|
35029
36847
|
return {
|
|
35030
|
-
error: interactiveRunnerMessages.followTimedOut(options.runId, options.runnerId, options.timeoutSeconds),
|
|
36848
|
+
error: interactiveRunnerMessages.followTimedOut(options.runId, options.runner.runnerId, options.timeoutSeconds),
|
|
35031
36849
|
exitCode: exitCodes.timeout
|
|
35032
36850
|
};
|
|
35033
36851
|
}
|
|
35034
|
-
await deps.sleep(
|
|
36852
|
+
await deps.sleep(pollIntervalMs4);
|
|
35035
36853
|
}
|
|
35036
36854
|
}
|
|
35037
36855
|
|
|
@@ -35235,10 +37053,7 @@ async function sendRunFlowRequest(ctx, options, delta) {
|
|
|
35235
37053
|
}, runnerCallOptions);
|
|
35236
37054
|
if (!result.ok) {
|
|
35237
37055
|
return {
|
|
35238
|
-
failure:
|
|
35239
|
-
...failureFields(result),
|
|
35240
|
-
exitCode: result.exitCode ?? exitCodes.network
|
|
35241
|
-
},
|
|
37056
|
+
failure: runnerRequestFailure(result, options.resolved),
|
|
35242
37057
|
type: "failed"
|
|
35243
37058
|
};
|
|
35244
37059
|
}
|
|
@@ -35311,7 +37126,7 @@ async function finish(sent, fileSync, options, deps) {
|
|
|
35311
37126
|
|
|
35312
37127
|
// src/domains/interactiveRunner/runFlow.ts
|
|
35313
37128
|
async function handleRunnerRun(ctx, options, deps) {
|
|
35314
|
-
const timeout = parseFollowTimeout(options.timeout);
|
|
37129
|
+
const timeout = parseFollowTimeout(options.timeout, defaultFollowTimeoutSeconds);
|
|
35315
37130
|
if (!timeout.ok) {
|
|
35316
37131
|
return { error: timeout.error, exitCode: exitCodes.invalidArgs };
|
|
35317
37132
|
}
|
|
@@ -35371,7 +37186,7 @@ async function handleRunnerRun(ctx, options, deps) {
|
|
|
35371
37186
|
recorderSinceSequence,
|
|
35372
37187
|
runEvents: options.runEvents,
|
|
35373
37188
|
runId,
|
|
35374
|
-
|
|
37189
|
+
runner: resolved,
|
|
35375
37190
|
timeoutSeconds: timeout.seconds
|
|
35376
37191
|
}, deps);
|
|
35377
37192
|
}
|
|
@@ -35422,6 +37237,7 @@ function createProgram({
|
|
|
35422
37237
|
const program = new Command2().name("qawolf").description("Run QA Wolf flows locally").version(package_default.version).option("--verbose", "Enable debug logging to stderr").option("--json", "Output as JSON").option("--agent", "Output for agent consumption").exitOverride((err) => {
|
|
35423
37238
|
exit(err.exitCode === 0 ? exitCodes.success : exitCodes.invalidArgs);
|
|
35424
37239
|
});
|
|
37240
|
+
registerAgentCommand(program, signals);
|
|
35425
37241
|
registerAuthCommand(program, signals);
|
|
35426
37242
|
registerDoctorCommand(program, signals);
|
|
35427
37243
|
registerFlowsCommand(program, signals);
|
|
@@ -35442,4 +37258,4 @@ createProgram({ signals }).parseAsync().catch(() => {
|
|
|
35442
37258
|
process.exitCode = 1;
|
|
35443
37259
|
}).finally(() => exitWhenIdle(typeof process.exitCode === "number" ? process.exitCode : 0));
|
|
35444
37260
|
|
|
35445
|
-
//# debugId=
|
|
37261
|
+
//# debugId=59D2DE48FE68917864756E2164756E21
|